From 71cff4032ccf99092b78b72ec599e43a96a3c3db Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 18 Nov 2016 16:26:12 +0100 Subject: [PATCH 001/410] NEW : option to copy into attachement files of events, files send by mail (with auto event creation) --- htdocs/core/actions_sendmails.inc.php | 1 + .../interface_50_modAgenda_ActionsAuto.class.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 9ec3bfcb3b7..e9d65222d28 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -345,6 +345,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $object->trackid = $trackid; $object->fk_element = $object->id; $object->elementtype = $object->element; + $object->attachedfiles = $attachedfiles; // Call of triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index bce6cd02eee..437dcea9e1c 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -856,6 +856,21 @@ class InterfaceActionsAuto extends DolibarrTriggers $ret=$actioncomm->create($user); // User creating action + if ($ret > 0 && $conf->global->MAIN_COPY_FILE_IN_EVENT_AUTO) + { + if (is_array($object->attachedfiles) && array_key_exists('paths',$object->attachedfiles) && count($object->attachedfiles['paths'])>0) { + foreach($object->attachedfiles['paths'] as $key=>$filespath) { + $srcfile = $filespath; + $destdir = $conf->agenda->dir_output . '/' . $ret; + $destfile = $destdir . '/' . $object->attachedfiles['names'][$key]; + if (dol_mkdir($destdir) >= 0) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + dol_copy($srcfile, $destfile); + } + } + } + } + unset($object->actionmsg); unset($object->actionmsg2); unset($object->actiontypecode); // When several action are called on same object, we must be sure to not reuse value of first action. if ($ret > 0) From b813144edb102c4c9b13407836042eae220761dd Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 6 Jan 2017 16:44:09 +0100 Subject: [PATCH 002/410] NEW generation ODT --- htdocs/admin/user.php | 43 +++- .../core/class/commondocgenerator.class.php | 16 ++ htdocs/core/class/commonobject.class.php | 1 + htdocs/core/class/html.formfile.class.php | 29 ++- htdocs/core/lib/functions2.lib.php | 1 - .../modules/product/modules_product.class.php | 37 ++++ .../core/modules/user/modules_user.class.php | 62 ++++++ htdocs/product/admin/product.php | 192 ++++++++++++++++++ htdocs/product/card.php | 70 +++++++ htdocs/product/class/product.class.php | 35 ++++ htdocs/user/card.php | 35 ++++ 11 files changed, 516 insertions(+), 5 deletions(-) create mode 100644 htdocs/core/modules/user/modules_user.class.php diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index f76762c8334..fcb062457a9 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -40,11 +40,48 @@ if (! $user->admin) accessforbidden(); $extrafields = new ExtraFields($db); +$type='user'; /* * Action */ -if (preg_match('/set_(.*)/',$action,$reg)) + +// Activate a model +if ($action == 'set_default') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); + $res = true; +} + +elseif ($action == 'del_default') +{ + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + if ($conf->global->USER_ADDON_PDF_ODT == "$value") dolibarr_del_const($db, 'USER_ADDON_PDF_ODT',$conf->entity); + } + $res = true; +} + +// Set default model +elseif ($action == 'setdoc') +{ + if (dolibarr_set_const($db, "USER_ADDON_PDF_ODT",$value,'chaine',0,'',$conf->entity)) + { + // La constante qui a ete lue en avant du nouveau set + // on passe donc par une variable pour avoir un affichage coherent + $conf->global->PRODUCT_ADDON_PDF_ODT = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } + $res = true; +} +elseif (preg_match('/set_(.*)/',$action,$reg)) { $code=$reg[1]; if (dolibarr_set_const($db, $code, 1, 'chaine', 0, '', $conf->entity) > 0) @@ -58,7 +95,7 @@ if (preg_match('/set_(.*)/',$action,$reg)) } } -if (preg_match('/del_(.*)/',$action,$reg)) +elseif (preg_match('/del_(.*)/',$action,$reg)) { $code=$reg[1]; if (dolibarr_del_const($db, $code, $conf->entity) > 0) @@ -72,7 +109,7 @@ if (preg_match('/del_(.*)/',$action,$reg)) } } //Set hide closed customer into combox or select -if ($action == 'sethideinactiveuser') +elseif ($action == 'sethideinactiveuser') { $status = GETPOST('status','alpha'); diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 9b233ef6b74..51977bcb356 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -317,6 +317,22 @@ abstract class CommonDocGenerator return $array_other; } + + + + function get_substitutionarray_each_var_object(&$object,$outputlangs,$recursive=true) { + foreach($object as $key => $value) { + if(!is_array($value) && !is_object($value)) { + $array_other['object_'.$key] = $value; + } + if(is_array($value) && $recursive){ + foreach($value as $key2 => $val) { + $array_other[$key][$key2] = $this->get_substitutionarray_each_var_object($val,$outputlangs,false); + } + } + } + return $array_other; + } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3279d372a0e..f8ab4f34467 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3589,6 +3589,7 @@ abstract class CommonObject $modele=$tmp[0]; $srctemplatepath=$tmp[1]; } + // Search template files $file=''; $classname=''; $filefound=0; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index a973c2622cc..ded716c1766 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -299,7 +299,7 @@ class FormFile $headershown=0; $showempty=0; $i=0; - + $titletoshow=$langs->trans("Documents"); if (! empty($title)) $titletoshow=$title; @@ -402,6 +402,33 @@ class FormFile $modellist=ModelePDFProjects::liste_modeles($this->db); } } + elseif ($modulepart == 'product') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php'; + $modellist=ModelePDFProduct::liste_modeles($this->db); + } + } + elseif ($modulepart == 'user') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.php'; + $modellist=ModelePDFProduct::liste_modeles($this->db); + } + } + elseif ($modulepart == 'group') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_group.php'; + $modellist=ModelePDFProduct::liste_modeles($this->db); + } + } elseif ($modulepart == 'project_task') { if (is_array($genallowed)) $modellist=$genallowed; diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 82449ac63cb..19279296ce9 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1444,7 +1444,6 @@ function getListOfModels($db,$type,$maxfilenamelength=0) $const=$obj->description; $dirtoscan.=($dirtoscan?',':'').preg_replace('/[\r\n]+/',',',trim($conf->global->$const)); - $listoffiles=array(); // Now we add models found in directories scanned diff --git a/htdocs/core/modules/product/modules_product.class.php b/htdocs/core/modules/product/modules_product.class.php index e08ea074bbd..d7138af84a8 100644 --- a/htdocs/core/modules/product/modules_product.class.php +++ b/htdocs/core/modules/product/modules_product.class.php @@ -24,6 +24,43 @@ * \class ModeleProductCode * \brief Parent class for product code generators */ + +/** + * \file htdocs/core/modules/contract/modules_contract.php + * \ingroup contract + * \brief File with parent class for generating contracts to PDF and File of class to manage contract numbering + */ + + require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; + +/** + * Parent class to manage intervention document templates + */ +abstract class ModelePDFProduct extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='product'; + $liste=array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + return $liste; + } +} + abstract class ModeleProductCode { var $error=''; diff --git a/htdocs/core/modules/user/modules_user.class.php b/htdocs/core/modules/user/modules_user.class.php new file mode 100644 index 00000000000..3e94ece9372 --- /dev/null +++ b/htdocs/core/modules/user/modules_user.class.php @@ -0,0 +1,62 @@ + + * Copyright (C) 2004-2010 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + + +/** + * \class ModeleProductCode + * \brief Parent class for product code generators + */ + +/** + * \file htdocs/core/modules/contract/modules_contract.php + * \ingroup contract + * \brief File with parent class for generating contracts to PDF and File of class to manage contract numbering + */ + + require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; + +/** + * Parent class to manage intervention document templates + */ +abstract class ModelePDFUser extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='user'; + $liste=array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + return $liste; + } +} \ No newline at end of file diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 8a561c0e53e..10da8463058 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -43,6 +43,7 @@ if (! $user->admin || (empty($conf->product->enabled) && empty($conf->service->e $action = GETPOST('action','alpha'); $value = GETPOST('value','alpha'); +$type='product'; // Pricing Rules $select_pricing_rules=array( @@ -110,6 +111,42 @@ if ($action == 'setModuleOptions') } } +// Activate a model +if ($action == 'set_default') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); + $res = true; +} + +if ($action == 'del_default') +{ + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + if ($conf->global->PRODUCT_ADDON_PDF_ODT == "$value") dolibarr_del_const($db, 'PRODUCT_ADDON_PDF_ODT',$conf->entity); + } + $res = true; +} + +// Set default model +if ($action == 'setdoc') +{ + if (dolibarr_set_const($db, "PRODUCT_ADDON_PDF_ODT",$value,'chaine',0,'',$conf->entity)) + { + // La constante qui a ete lue en avant du nouveau set + // on passe donc par une variable pour avoir un affichage coherent + $conf->global->PRODUCT_ADDON_PDF_ODT = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } + $res = true; +} + if ($action == 'other' && GETPOST('value_PRODUIT_LIMIT_SIZE') >= 0) { $res = dolibarr_set_const($db, "PRODUIT_LIMIT_SIZE", GETPOST('value_PRODUIT_LIMIT_SIZE'),'chaine',0,'',$conf->entity); @@ -228,6 +265,8 @@ else if (empty($conf->service->enabled)) llxHeader('',$title); +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + $linkback=''.$langs->trans("BackToModuleList").''; print load_fiche_titre($title,$linkback,'title_setup'); @@ -317,6 +356,159 @@ foreach ($dirproduct as $dirroot) } print ''; + +// Defini tableau def des modeles +$def = array(); +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + +print ''; +print ''; +print ''; +print ''; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +$var=true; +foreach ($dirmodels as $reldir) +{ + foreach (array('','/doc') as $valdir) + { + $dir = dol_buildpath($reldir."core/modules/product".$valdir); + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var = !$var; + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } + else + { + print '"; + } + + // Defaut + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + $htmltooltip.='
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } +} + +print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print "'; + if ($conf->global->PRODUCT_ADDON_PDF == $name) + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'contract').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
'; +print "
"; + /* * Other conf */ diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 59ccdb79a1f..7a0ebca0ace 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -38,6 +38,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/canvas.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; @@ -517,6 +518,40 @@ if (empty($reshook)) $action=''; } } + if ($action == 'builddoc' && $user->rights->produit->creer) { + /*if (GETPOST('model')) { + $object->setDocModel($user, GETPOST('model')); + }*/ + + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } + } + + // Remove file in doc form + if ($action == 'remove_file' && $user->rights->contrat->creer) { + if ($object->id > 0) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->contrat->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); + else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); + } + } // Add product into object @@ -770,6 +805,7 @@ else $title = $langs->trans('ProductServiceCard'); llxHeader('', $title, $helpurl); $form = new Form($db); +$formfile = new FormFile($db); $formproduct = new FormProduct($db); @@ -1829,5 +1865,39 @@ if ($object->id && ($action == '' || $action == 'view') && $object->status) } +print '
'; + +/* + * Documents generes +*/ +$filename = dol_sanitizeFileName($object->ref); +$filedir = $conf->produit->dir_output . "/" . dol_sanitizeFileName($object->ref); +$urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; +$genallowed = $user->rights->produit->creer; +$delallowed = $user->rights->produit->supprimer; + +$var = true; + +$somethingshown = $formfile->show_documents('product', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + +// Linked object block +$somethingshown = $form->showLinkedObjectBlock($object); + +// Show links to link elements +$linktoelem = $form->showLinkToObjectBlock($object); +if ($linktoelem) print '
'.$linktoelem; + + +print '
'; + +// List of actions on element +include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; +$formactions = new FormActions($db); +$somethingshown = $formactions->showactions($object, 'product', $socid); + + +print '
'; + + llxFooter(); $db->close(); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 1d8d17d6c8f..2c4eb128413 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3191,6 +3191,41 @@ class Product extends CommonObject return $result; } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force model to use ('' to not force) + * @param Translate $outputlangs Object langs to use for output + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) + { + global $conf,$user,$langs; + + $langs->load("products"); + + // Positionne le modele sur le nom du modele a utiliser + if (! dol_strlen($modele)) + { + if (! empty($conf->global->PRODUCT_ADDON_PDF)) + { + $modele = $conf->global->PRODUCT_ADDON_PDF; + } + else + { + $modele = 'strato'; + } + } + + $modelpath = "core/modules/product/doc/"; + + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + /** * Return label of status of object * diff --git a/htdocs/user/card.php b/htdocs/user/card.php index b0425b182e0..ce6ef3f992f 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -35,6 +35,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; @@ -589,6 +590,7 @@ if (empty($reshook)) { $form = new Form($db); $formother=new FormOther($db); $formcompany = new FormCompany($db); +$formfile = new FormFile($db); llxHeader('',$langs->trans("UserCard")); @@ -2275,8 +2277,41 @@ else print ''; } + print '
'; + /* + * Documents generes + */ + $filename = dol_sanitizeFileName($object->ref); + $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->user->creer; + $delallowed = $user->rights->user->supprimer; + + $var = true; + + $somethingshown = $formfile->show_documents('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + + // Linked object block + $somethingshown = $form->showLinkedObjectBlock($object); + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object); + if ($linktoelem) print '
'.$linktoelem; + + + print '
'; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'user', $socid); + + + print '
'; + if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) $ldap->close; } + } if (! empty($conf->api->enabled) && ! empty($conf->use_javascript_ajax)) From ddbd6c371d08c09018149eca014242f1f98bb70d Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 20 Jan 2017 11:58:30 +0100 Subject: [PATCH 003/410] MERGE DEGUEU --- build/pad/DoliWamp.pml | 2 +- build/pad/Dolibarr.pml | 16 ++++++++-------- build/pad/pad_dolibarr.xml | 16 ++++++++-------- build/pad/pad_doliwamp.xml | 2 +- .../phpexcel/Classes/PHPExcel/locale/cs/config | 2 +- .../Classes/PHPExcel/locale/cs/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/da/config | 4 ++-- .../Classes/PHPExcel/locale/da/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/de/config | 4 ++-- .../Classes/PHPExcel/locale/de/functions | 2 +- .../Classes/PHPExcel/locale/en/uk/config | 2 +- .../phpexcel/Classes/PHPExcel/locale/es/config | 4 ++-- .../Classes/PHPExcel/locale/es/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/fi/config | 4 ++-- .../Classes/PHPExcel/locale/fi/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/fr/config | 4 ++-- .../Classes/PHPExcel/locale/fr/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/hu/config | 2 +- .../Classes/PHPExcel/locale/hu/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/it/config | 4 ++-- .../Classes/PHPExcel/locale/it/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/nl/config | 4 ++-- .../Classes/PHPExcel/locale/nl/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/no/config | 4 ++-- .../Classes/PHPExcel/locale/no/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/pl/config | 4 ++-- .../Classes/PHPExcel/locale/pl/functions | 2 +- .../Classes/PHPExcel/locale/pt/br/config | 4 ++-- .../phpexcel/Classes/PHPExcel/locale/pt/config | 4 ++-- .../phpexcel/Classes/PHPExcel/locale/ru/config | 4 ++-- .../Classes/PHPExcel/locale/ru/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/sv/config | 4 ++-- .../phpexcel/Classes/PHPExcel/locale/tr/config | 4 ++-- .../Classes/PHPExcel/locale/tr/functions | 2 +- 34 files changed, 62 insertions(+), 62 deletions(-) diff --git a/build/pad/DoliWamp.pml b/build/pad/DoliWamp.pml index e0f2b99bfec..fa2da1902aa 100644 --- a/build/pad/DoliWamp.pml +++ b/build/pad/DoliWamp.pml @@ -42,7 +42,7 @@ DoliWamp, the easy to use Dolibarr for Windows to manage your company,foundation DoliWamp is the Dolibarr ERP/CRM for Windows, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs. DoliWamp is the Dolibarr ERP/CRM autoinstaller for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. Dolibarr ERP/CRM is a software package built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. - DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. + DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. DoliWamp is the auto-installer for Windows users with no technical knowledge to install Dolibarr ERP/CRM and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. diff --git a/build/pad/Dolibarr.pml b/build/pad/Dolibarr.pml index 250aed0d791..3ef5e16137c 100644 --- a/build/pad/Dolibarr.pml +++ b/build/pad/Dolibarr.pml @@ -42,10 +42,10 @@ Dolibarr ERP & CRM, the easy to use open source software to manage your activity Dolibarr ERP & CRM, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs to follow. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or medium companies, freelancers or foundations. We can say Dolibarr is an ERP or CRM. Dolibarr is also available with an auto-installer for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. See DoliWamp software for this. - Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: -Simple to install -Simple to use -Simple to develop + Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: +Simple to install +Simple to use +Simple to develop Note that Dolibarr is also available with an auto-installer for Windows or Ubuntu users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. This version is called DoliWamp (for Windows) or DoliBuntu (for Ubuntu/Debian). @@ -62,10 +62,10 @@ Note that Dolibarr is also available with an auto-installer for Windows or Ubunt Dolibarr ERP & CRM, le gestionnaire simple pour gérer votre activité Dolibarr ERP & CRM, le logiciel simple et OpenSource pour gérer votre activité (factures, devis, facturation, commandes, compta, trésorerie, stocks, produits, agenda, comptes bancaires, associations) Dolibarr ERP/CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). - Dolibarr ERP/CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): -Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) -Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) -Simple pour le développement (pas de frameworks lourds). + Dolibarr ERP/CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): +Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) +Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) +Simple pour le développement (pas de frameworks lourds). Dolibarr intègre en effet sa propre architecture (design patterns) permettant à tout développeur d'être tout de suite opérationnel sans connaissances particulières autre que le PHP. diff --git a/build/pad/pad_dolibarr.xml b/build/pad/pad_dolibarr.xml index c8ad2c62cfb..0920a19311d 100644 --- a/build/pad/pad_dolibarr.xml +++ b/build/pad/pad_dolibarr.xml @@ -72,10 +72,10 @@ Dolibarr ERP & CRM, the easy to use open source software to manage your activity Dolibarr ERP & CRM, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs to manage. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or medium companies, freelancers or foundations. We can say Dolibarr is an ERP or CRM. Dolibarr is also available with an auto-installer for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. See DoliWamp software for this. - Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: -Simple to install -Simple to use -Simple to develop + Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: +Simple to install +Simple to use +Simple to develop Note that Dolibarr is also available with an auto-installer for Windows or Ubuntu users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. This version is called DoliWamp (for Windows) or DoliBuntu (for Ubuntu/Debian). @@ -84,10 +84,10 @@ Note that Dolibarr is also available with an auto-installer for Windows or Ubunt Dolibarr ERP & CRM, le gestionnaire simple pour gérer votre activité Dolibarr ERP & CRM, le logiciel simple et OpenSource pour gérer votre activité (factures, devis, facturation, commandes, compta, trésorerie, stocks, produits, agenda, comptes bancaires, associations) Dolibarr ERP & CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). - Dolibarr ERP & CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): -Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) -Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) -Simple pour le développement (pas de frameworks lourds). + Dolibarr ERP & CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): +Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) +Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) +Simple pour le développement (pas de frameworks lourds). Dolibarr intègre en effet sa propre architecture (design patterns) permettant à tout développeur d'être tout de suite opérationnel sans connaissances particulières autre que le PHP. diff --git a/build/pad/pad_doliwamp.xml b/build/pad/pad_doliwamp.xml index 3ee629c644b..8abf126d5f7 100644 --- a/build/pad/pad_doliwamp.xml +++ b/build/pad/pad_doliwamp.xml @@ -72,7 +72,7 @@ DoliWamp, the easy to use Dolibarr for Windows to manage your company,foundation DoliWamp is the Dolibarr ERP/CRM for Windows, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs. DoliWamp is the Dolibarr ERP/CRM autoinstaller for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. Dolibarr ERP/CRM is a software package built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. - DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. + DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. DoliWamp is the auto-installer for Windows users with no technical knowledge to install Dolibarr ERP/CRM and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config index 500460e8ab5..8992916acaf 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions index b648e20c2b0..f9d69784ae2 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config index b959379b133..cef47e9502d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -37,7 +37,7 @@ currencySymbol = kr ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NUL! DIV0 = #DIVISION/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions index 1599ccd1815..1db4d30bb1c 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config index 7e2ba9d2891..ff7e29899cc 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULL! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions index 8214f384878..ce85641a3c9 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config index 00acff8bc34..f008e61cc90 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config index 8f7d9e084ec..fa16f5639df 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = $ ## I'm surprised that the Excel Documentation suggests $ rath ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #¡NULO! DIV0 = #¡DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions index aa065969f3d..51ce48b3153 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config index 36bc3fc70b8..a481864a6fa 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = $ # Symbol not known, should it be a € (Euro)? ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #TYHJÄ! DIV0 = #JAKO/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions index c10b3b9f381..7bed722a641 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config index 80f7d5411a6..2240d6b9f8b 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NUL! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions index cce977b15bc..8d25f6ac193 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config index c6c315814c4..dec7cbde15d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions index 941c1b740d0..4abce13b91b 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config index 97af8b9a570..f862a02d72d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULLO! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions index 862cf8302c8..b9219a6a4ce 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config index a14b476c945..7377a181df0 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #LEEG! DIV0 = #DEEL/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions index 79b7acd1ef9..b6b8296ef04 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config index e3e3cc4f786..15fcc128640 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = kr ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULL! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions index 3cccce42a1d..57a80a7a406 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config index ea111797270..fb1e7b13d9d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = zł ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #ZERO! DIV0 = #DZIEL/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions index 5607f8f672c..2e5697973c1 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config index d39c5c63438..e99aad6bea4 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = R$ ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULO! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config index 5e486bb29ff..36df63cc012 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULO! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config index 098c8075d29..205c342ada4 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = р ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #ПУСТО! DIV0 = #ДЕЛ/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions index 86bcd4f63a7..324c3df2a81 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config index c2094c06249..454e52ef52f 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = kr ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #Skärning! DIV0 = #Division/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config index cca084b2ba5..8a103d3c196 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = YTL ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #BOŞ! DIV0 = #SAYI/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions index 3e7c225f402..79645214714 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or From dccddf5c7ec0745a2c777fa1587e1651692cfa4e Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 3 Feb 2017 09:25:26 +0100 Subject: [PATCH 004/410] NEW : change render extrafields checkbox list for multiselectarray --- htdocs/core/class/extrafields.class.php | 74 ++++++++++--------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 1211c334617..b14f7c65ed9 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -993,23 +993,12 @@ class ExtraFields } elseif ($type == 'checkbox') { - $out=''; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + $form = new Form($db); + $value_arr=explode(',',$value); + $out=$form->multiselectarray($keysuffix.'options_'.$key.$keyprefix, $param['options'], $value_arr, '', 0, '', 0, '100%'); - foreach ($param['options'] as $keyopt=>$val ) - { - - $out.=''; - } } elseif ($type == 'radio') { @@ -1100,6 +1089,9 @@ class ExtraFields if ($resql) { $num = $this->db->num_rows($resql); $i = 0; + + $data=array(); + while ( $i < $num ) { $labeltoshow = ''; $obj = $this->db->fetch_object($resql); @@ -1125,12 +1117,9 @@ class ExtraFields $labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' '; } } - $out .= 'rowid . '"'; - - $out .= 'checked'; - - $out .= '/>' . $labeltoshow . '
'; + + $data[$obj->rowid]=$labeltoshow; + } else { if (! $notrans) { $translabel = $langs->trans($obj->{$InfoFieldList[1]}); @@ -1144,32 +1133,25 @@ class ExtraFields $labeltoshow = '(not defined)'; if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { - $out .= 'rowid . '"'; - - $out .= 'checked'; - $out .= ''; - - $out .= '/>' . $labeltoshow . '
'; + $data[$obj->rowid]=$labeltoshow; } if (! empty($InfoFieldList[3])) { $parent = $parentName . ':' . $obj->{$parentField}; } - $out .= 'rowid . '"'; - - $out .= ((is_array($value_arr) && in_array($obj->rowid, $value_arr)) ? ' checked ' : ''); - ; - $out .= ''; - - $out .= '/>' . $labeltoshow . '
'; + $data[$obj->rowid]=$labeltoshow; } - + $i ++; } $this->db->free($resql); + + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + $form = new Form($db); + + $out=$form->multiselectarray($keysuffix.'options_'.$key.$keyprefix, $data, $value_arr, '', 0, '', 0, '100%'); + } else { print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.
'; } @@ -1380,9 +1362,10 @@ class ExtraFields if (is_array($value_arr)) { foreach ($value_arr as $keyval=>$valueval) { - $value.=$params['options'][$valueval].'
'; + $toprint[]='
  • '.$params['options'][$valueval].'
  • '; } } + $value='
      '.implode(' ', $toprint).'
    '; } elseif ($type == 'chkbxlst') { @@ -1417,7 +1400,7 @@ class ExtraFields $resql = $this->db->query($sql); if ($resql) { $value = ''; // value was used, so now we reste it to use it to build final output - + $toprint=array(); while ( $obj = $this->db->fetch_object($resql) ) { // Several field into label (eq table:code|libelle:rowid) @@ -1430,9 +1413,9 @@ class ExtraFields $translabel = $langs->trans($obj->$field_toshow); } if ($translabel != $field_toshow) { - $value .= dol_trunc($translabel, 18) . '
    '; + $toprint[]='
  • '.dol_trunc($translabel, 18).'
  • '; } else { - $value .= $obj->$field_toshow . '
    '; + $toprint[]='
  • '.$obj->$field_toshow.'
  • '; } } } else { @@ -1441,15 +1424,18 @@ class ExtraFields $translabel = $langs->trans($obj->{$InfoFieldList[1]}); } if ($translabel != $obj->{$InfoFieldList[1]}) { - $value .= dol_trunc($translabel, 18) . '
    '; + $toprint[]='
  • '.dol_trunc($translabel, 18).'
  • '; } else { - $value .= $obj->{$InfoFieldList[1]} . '
    '; + $toprint[]='
  • '.$obj->{$InfoFieldList[1]}.'
  • '; } } } } - } else + $value='
      '.implode(' ', $toprint).'
    '; + + } else { dol_syslog(get_class($this) . '::showOutputField error ' . $this->db->lasterror(), LOG_WARNING); + } } elseif ($type == 'link') { From c06aedc54da2dadd3d01e8dd3c5200ea847ed8c3 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 15 Feb 2017 20:55:52 +0100 Subject: [PATCH 005/410] [FP17] : Add data in llx_accountancy_journal --- htdocs/install/mysql/data/llx_accounting.sql | 8 +++++++- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 6 ++++++ htdocs/install/mysql/tables/llx_accounting_journal.sql | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/htdocs/install/mysql/data/llx_accounting.sql b/htdocs/install/mysql/data/llx_accounting.sql index 149d7fea394..dc7aeb27bef 100644 --- a/htdocs/install/mysql/data/llx_accounting.sql +++ b/htdocs/install/mysql/data/llx_accounting.sql @@ -5,7 +5,7 @@ -- Copyright (C) 2004 Guillaume Delecourt -- Copyright (C) 2005-2009 Regis Houssin -- Copyright (C) 2007 Patrick Raguin --- Copyright (C) 2011-2016 Alexandre Spangaro +-- Copyright (C) 2011-2017 Alexandre Spangaro -- -- 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 @@ -29,7 +29,13 @@ delete from llx_accounting_account; delete from llx_accounting_system; +delete from llx_accounting_journal; +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Journal des ventes', 1, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Journal des achats', 2, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (3,'BQ', 'Journal de banque', 3, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 4, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (5,'AN', 'Journal des à-nouveaux', 9, 1); -- -- Descriptif des plans comptables FR PCG99-ABREGE -- diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index aa755daa09a..0d47261503c 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -98,3 +98,9 @@ CREATE TABLE llx_product_attribute_combination entity INT DEFAULT 1 NOT NULL ); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Journal des ventes', 1, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Journal des achats', 2, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (3,'BQ', 'Journal de banque', 3, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 4, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (5,'AN', 'Journal des à-nouveaux', 9, 1); + diff --git a/htdocs/install/mysql/tables/llx_accounting_journal.sql b/htdocs/install/mysql/tables/llx_accounting_journal.sql index bc514f0ed9b..f3ee2a2e010 100644 --- a/htdocs/install/mysql/tables/llx_accounting_journal.sql +++ b/htdocs/install/mysql/tables/llx_accounting_journal.sql @@ -1,5 +1,5 @@ -- ============================================================================ --- Copyright (C) 2016 Alexandre Spangaro +-- Copyright (C) 2016-2017 Alexandre Spangaro -- -- 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 @@ -22,6 +22,6 @@ create table llx_accounting_journal rowid integer AUTO_INCREMENT PRIMARY KEY, code varchar(32) NOT NULL, label varchar(128) NOT NULL, - nature smallint DEFAULT 0 NOT NULL, -- type of journals (Sale / purchase / bank / various operations) + nature smallint DEFAULT 0 NOT NULL, -- type of journals (1:Sale / 2:purchase / 3:bank / 4:various operations / 9: has-new) active smallint DEFAULT 0 )ENGINE=innodb; From 1401e9267b5ec5a9554e2cb08f1d22b15847c9d3 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 21 Feb 2017 07:09:58 +0100 Subject: [PATCH 006/410] [FP17] Modify menu for multijournal --- htdocs/core/menus/standard/eldy.lib.php | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index e16e6601940..5f2a5f5def6 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -993,6 +993,37 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu { if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('',$langs->trans("Journalization"),1,$user->rights->accounting->comptarapport->lire); + // Multi journal + $sql = "SELECT rowid, code, label, nature"; + $sql.= " FROM ".MAIN_DB_PREFIX."accounting_journal"; + // $sql.= " WHERE entity = ".$conf->entity; + $sql.= " ORDER BY code"; + + $resql = $db->query($sql); + if ($resql) + { + $numr = $db->num_rows($resql); + $i = 0; + + if ($numr > 0) + while ($i < $numr) + { + $objp = $db->fetch_object($resql); + + if ($objp->nature == 1) $nature="sells"; + if ($objp->nature == 2) $nature="purchases"; + if ($objp->nature == 3) $nature="bank"; + if ($objp->nature == 4) $nature="various"; + if ($objp->nature == 9) $nature="hasnew"; + + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&code_journal='.$objp->code,dol_trunc($objp->label,25),2,$user->rights->accounting->comptarapport->lire); + $i++; + } + } + else dol_print_error($db); + $db->free($resql); + + /* $sql = "SELECT rowid, label, accountancy_journal"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE entity = ".$conf->entity; @@ -1020,6 +1051,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/sellsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("SellsJournal"),2,$user->rights->accounting->comptarapport->lire); if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/purchasesjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("PurchasesJournal"),2,$user->rights->accounting->comptarapport->lire); if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/expensereportsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("ExpenseReportsJournal"),2,$user->rights->accounting->comptarapport->lire); + */ } // General Ledger From abeba95de9740d1cecaed4f872ff799326e15c13 Mon Sep 17 00:00:00 2001 From: arnaud Date: Thu, 2 Mar 2017 15:13:42 +0100 Subject: [PATCH 007/410] New USER odt --- htdocs/admin/user.php | 194 +++++++++++++++++++++- htdocs/core/class/html.formfile.class.php | 4 +- htdocs/core/lib/admin.lib.php | 2 +- htdocs/user/card.php | 9 +- htdocs/user/class/user.class.php | 34 ++++ 5 files changed, 235 insertions(+), 8 deletions(-) diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index fcb062457a9..d237ca3e727 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -35,11 +35,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $langs->load("admin"); $langs->load("members"); $langs->load("users"); - if (! $user->admin) accessforbidden(); $extrafields = new ExtraFields($db); +$action = GETPOST('action','alpha'); +$value = GETPOST('value','alpha'); $type='user'; /* @@ -47,7 +48,36 @@ $type='user'; */ // Activate a model -if ($action == 'set_default') + +// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) +if ($action == 'setModuleOptions') +{ + $post_size=count($_POST); + + $db->begin(); + + for($i=0;$i < $post_size;$i++) + { + if (array_key_exists('param'.$i,$_POST)) + { + $param=GETPOST("param".$i,'alpha'); + $value=GETPOST("value".$i,'alpha'); + if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + } + } + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} +elseif ($action == 'set_default') { $ret = addDocumentModel($value, $type, $label, $scandir); $res = true; @@ -70,7 +100,7 @@ elseif ($action == 'setdoc') { // La constante qui a ete lue en avant du nouveau set // on passe donc par une variable pour avoir un affichage coherent - $conf->global->PRODUCT_ADDON_PDF_ODT = $value; + $conf->global->USER_ADDON_PDF_ODT = $value; } // On active le modele @@ -175,6 +205,164 @@ print ''; print ''; + + +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + +$form=new Form($db); + +// Defini tableau def des modeles +$def = array(); +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + +print ''; +print ''; +print ''; +print ''; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +$var=true; +foreach ($dirmodels as $reldir) +{ + foreach (array('','/doc') as $valdir) + { + $dir = dol_buildpath($reldir."core/modules/user".$valdir); + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var = !$var; + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } + else + { + print '"; + } + + // Defaut + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
    '.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip.='
    '.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip.='

    '.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
    '.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
    '.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
    '.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
    '.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + $htmltooltip.='
    '.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } +} + +print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
    '; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print "'; + if ($conf->global->USER_ADDON_PDF == $name) + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'contract').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
    '; +print "
    "; + dol_fiche_end(); llxFooter(); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index ded716c1766..f60faa84426 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -416,8 +416,8 @@ class FormFile if (is_array($genallowed)) $modellist=$genallowed; else { - include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.php'; - $modellist=ModelePDFProduct::liste_modeles($this->db); + include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.class.php'; + $modellist=ModelePDFUser::liste_modeles($this->db); } } elseif ($modulepart == 'group') diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index ffb09b2b3ab..56c48a33173 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1270,7 +1270,7 @@ function addDocumentModel($name, $type, $label='', $description='') $sql.= ($label?"'".$db->escape($label)."'":'null').", "; $sql.= (! empty($description)?"'".$db->escape($description)."'":"null"); $sql.= ")"; - + dol_syslog("admin.lib::addDocumentModel", LOG_DEBUG); $resql=$db->query($sql); if ($resql) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index ce6ef3f992f..53634de159c 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -580,6 +580,11 @@ if (empty($reshook)) { setEventMessages($ldap->error, $ldap->errors, 'errors'); } } + + // Actions to build doc + $upload_dir = $conf->user->dir_output; + $permissioncreate=$user->rights->user->user->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -2284,8 +2289,8 @@ else $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->user->creer; - $delallowed = $user->rights->user->supprimer; + $genallowed = $user->rights->user->user->creer; + $delallowed = $user->rights->user->user->supprimer; $var = true; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 1ee07e0a7af..f77a7fbc9df 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2622,5 +2622,39 @@ class User extends CommonObject } } + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force model to use ('' to not force) + * @param Translate $outputlangs Object langs to use for output + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) + { + global $conf,$user,$langs; + + $langs->load("user"); + + // Positionne le modele sur le nom du modele a utiliser + if (! dol_strlen($modele)) + { + if (! empty($conf->global->USER_ADDON_PDF)) + { + $modele = $conf->global->USER_ADDON_PDF; + } + else + { + $modele = 'bluesky'; + } + } + + $modelpath = "core/modules/user/doc/"; + + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } From 19ce0b0d89d21533e8c2c78f85c5c8be5bc718f8 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 3 Mar 2017 06:22:12 +0100 Subject: [PATCH 008/410] Fix : Language & revert a description of the function --- htdocs/accountancy/admin/index.php | 4 ++-- htdocs/langs/en_US/accountancy.lang | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 8f023432727..85c290eef7f 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent @@ -301,7 +301,7 @@ print '
    transnoentitiesnoconv("Home").'-'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy")); +print $langs->trans("AccountancySetupDoneFromAccountancyMenu", $langs->transnoentitiesnoconv("Home").'-'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy")); print '
    '; print ''; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 1b1032804f6..85b7b60c01b 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -107,7 +107,7 @@ ACCOUNTING_LENGTH_DESCRIPTION=Truncate product & services description in listing ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT=Truncate product & services account description form in listings after x chars (Best = 50) ACCOUNTING_LENGTH_GACCOUNT=Length of the general accounting accounts ACCOUNTING_LENGTH_AACCOUNT=Length of the third party accounting accounts -ACCOUNTING_MANAGE_ZERO=Manage the zero at the end of an accounting account. Needed by some countries. Disabled by default. If set to on, you must also set the 2 following parameters (or it is ignored) +ACCOUNTING_MANAGE_ZERO=Manage the zero at the end of an accounting account. Needed by some countries. Disabled by default. If set to on, you must not set the 2 following parameters. This function adds real zero while the 2 following functions add virtual zero. BANK_DISABLE_DIRECT_INPUT=Disable direct recording of transaction in bank account ACCOUNTING_SELL_JOURNAL=Sell journal From cff9fa0e6b4f4c13909f703f2cd646336cd48437 Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 3 Mar 2017 12:01:58 +0100 Subject: [PATCH 009/410] FIX user odt --- .../core/class/commondocgenerator.class.php | 29 ++++++++++++++----- .../core/modules/user/modules_user.class.php | 28 ++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 51977bcb356..1d4cb508fb9 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -320,16 +320,29 @@ abstract class CommonDocGenerator + /** + * Define array with couple subtitution key => subtitution value + * + * @param Object $object Dolibarr Object + * @param Translate $outputlangs Language object for output + * @param boolean $recursive Want to fetch child array or child object + * @return array Array of substitution key->code + */ function get_substitutionarray_each_var_object(&$object,$outputlangs,$recursive=true) { - foreach($object as $key => $value) { - if(!is_array($value) && !is_object($value)) { - $array_other['object_'.$key] = $value; - } - if(is_array($value) && $recursive){ - foreach($value as $key2 => $val) { - $array_other[$key][$key2] = $this->get_substitutionarray_each_var_object($val,$outputlangs,false); + $array_other = array(); + if(!empty($object)) { + foreach($object as $key => $value) { + if(!is_array($value) && !is_object($value)) { + $array_other['object_'.$key] = $value; } - } + if(is_array($value) && $recursive){ + if(!empty($value)) { + foreach($value as $key2 => $val) { + $array_other[$key][$key2] = $this->get_substitutionarray_each_var_object($val,$outputlangs,false); + } + } + } + } } return $array_other; } diff --git a/htdocs/core/modules/user/modules_user.class.php b/htdocs/core/modules/user/modules_user.class.php index 3e94ece9372..43660da1adb 100644 --- a/htdocs/core/modules/user/modules_user.class.php +++ b/htdocs/core/modules/user/modules_user.class.php @@ -55,6 +55,34 @@ abstract class ModelePDFUser extends CommonDocGenerator $type='user'; $liste=array(); + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + return $liste; + } +} + +/** + * Parent class to manage intervention document templates + */ +abstract class ModelePDFUserGroup extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='usergroup'; + $liste=array(); + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $liste=getListOfModels($db,$type,$maxfilenamelength); return $liste; From e1f459d67a5b096b95b7f385b7e02911630cc2d0 Mon Sep 17 00:00:00 2001 From: fmarcet Date: Fri, 3 Mar 2017 12:57:52 +0100 Subject: [PATCH 010/410] Fix: Error when references are numeric --- htdocs/product/class/product.class.php | 4 ++-- htdocs/projet/class/project.class.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 1d8d17d6c8f..72f7533135a 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -12,7 +12,7 @@ * Copyright (C) 2014 Henry Florian * Copyright (C) 2014-2016 Philippe Grand * Copyright (C) 2014 Ion agorria - * Copyright (C) 2016 Ferran Marcet + * Copyright (C) 2016-2017 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -803,7 +803,7 @@ class Product extends CommonObject // End call triggers } - if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref)) + if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) { // We remove directory if ($conf->product->dir_output) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 91a75f80ce1..6e866057584 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2017 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -279,7 +280,7 @@ class Project extends CommonObject } } - if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref)) + if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) { // We remove directory if ($conf->projet->dir_output) From 840408c1d21f6895c821b78c62a7bd7090c461aa Mon Sep 17 00:00:00 2001 From: tarrsalah Date: Sun, 5 Mar 2017 12:34:22 +0100 Subject: [PATCH 011/410] Fix the remainder to pay amount (#6486) The commit fix the remainder to pay amount (`$restapayer` value) in a supplier invoice card. --- htdocs/fourn/facture/card.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index ffdaa8924aa..afd36862fde 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -2411,6 +2411,8 @@ else print $langs->trans('AlreadyPaid'); print ' : 0)?' class="amountalreadypaid"':'').'>' . price($totalpaye) . ' '; + $totalpaye = $object->getSommePaiement(); + $resteapayer = $object->total_ttc - $totalpaye; $resteapayeraffiche = $resteapayer; $cssforamountpaymentcomplete = 'amountpaymentcomplete'; From bc7f4f30314ea9e6a803c878b06dc04d88dbbfe2 Mon Sep 17 00:00:00 2001 From: tarrsalah Date: Mon, 6 Mar 2017 09:02:01 +0100 Subject: [PATCH 012/410] No need to recalculate $totalpaye. --- htdocs/fourn/facture/card.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index afd36862fde..4d9e2521dd7 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -2411,7 +2411,6 @@ else print $langs->trans('AlreadyPaid'); print ' : 0)?' class="amountalreadypaid"':'').'>' . price($totalpaye) . ' '; - $totalpaye = $object->getSommePaiement(); $resteapayer = $object->total_ttc - $totalpaye; $resteapayeraffiche = $resteapayer; $cssforamountpaymentcomplete = 'amountpaymentcomplete'; From f291e1c47051908e9ea7ffbcc8a356567359a005 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 6 Mar 2017 12:30:59 +0100 Subject: [PATCH 013/410] Fix test on qty for stock move --- htdocs/product/stock/class/mouvementstock.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index dee344b6a5b..40ebb215250 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -277,7 +277,7 @@ class MouvementStock extends CommonObject // Check if stock is enough when qty is < 0 // Note that qty should be > 0 with type 0 or 3, < 0 with type 1 or 2. - if ($qty < 0 && empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) + if ($movestock && $qty < 0 && empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) { if (! empty($conf->productbatch->enabled) && $product->hasbatch() && ! $skip_batch) { From c260325863f1e9e902cdfbcc96a3999e9e6bde7a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 6 Mar 2017 12:32:07 +0100 Subject: [PATCH 014/410] Lang not loaded --- htdocs/product/stock/class/mouvementstock.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 40ebb215250..631f6697c33 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -292,6 +292,7 @@ class MouvementStock extends CommonObject } if (! $foundforbatch || $qtyisnotenough) { + $langs->load("stocks"); $this->error = $langs->trans('qtyToTranferLotIsNotEnough'); $this->errors[] = $langs->trans('qtyToTranferLotIsNotEnough'); $this->db->rollback(); @@ -302,6 +303,7 @@ class MouvementStock extends CommonObject { if (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty)) { + $langs->load("stocks"); $this->error = $langs->trans('qtyToTranferIsNotEnough'); $this->errors[] = $langs->trans('qtyToTranferIsNotEnough'); $this->db->rollback(); From d38818ff11af27821502c58e2b0cc7fad9b1d8b5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 6 Mar 2017 12:58:38 +0100 Subject: [PATCH 015/410] Fix option PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS not correctly supported. --- htdocs/fourn/commande/card.php | 2 +- htdocs/fourn/facture/card.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index d54a477aeee..736cb8340d3 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1774,7 +1774,7 @@ elseif (! empty($object->id)) $morehtmlref.='
    '; $morehtmlref.=''; $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$object->socid:-1), $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); $morehtmlref.=''; $morehtmlref.='
    '; } else { diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index ffdaa8924aa..4bb3346b375 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -2010,7 +2010,7 @@ else $morehtmlref.='
    '; $morehtmlref.=''; $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$object->socid:-1), $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); $morehtmlref.=''; $morehtmlref.='
    '; } else { From b37827944089c9963f6eee1c0bcecb0ccc7e5b4d Mon Sep 17 00:00:00 2001 From: Quentin Vial-Gouteyron Date: Mon, 6 Mar 2017 15:50:17 +0100 Subject: [PATCH 016/410] New_filter_to_add_draft_order_to_validated_one --- htdocs/product/stock/replenish.php | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index c050acc7663..2f8a9ba39b4 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -53,6 +53,8 @@ $type = GETPOST('type','int'); $tobuy = GETPOST('tobuy', 'int'); $salert = GETPOST('salert', 'alpha'); $mode = GETPOST('mode','alpha'); +$draftorder = GETPOST('draftorder','alpha'); + $fourn_id = GETPOST('fourn_id','int'); $fk_supplier = GETPOST('fk_supplier','int'); @@ -96,7 +98,9 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP $snom = ''; $sal = ''; $salert = ''; + $draftorder=''; } +if($draftorder == 'on') $draftchecked = "checked"; // Create orders if ($action == 'order' && isset($_POST['valid'])) @@ -438,6 +442,7 @@ print ''; print ''; print ''; print ''; +print ''; print ''; print '
    '; print $langs->trans('Warehouse').' '.$formproduct->selectWarehouses($fk_entrepot, 'fk_entrepot', '', 1); @@ -450,10 +455,11 @@ print ''; $param = (isset($type)? '&type=' . $type : ''); -$param .= '&fourn_id=' . $fourn_id . '&snom='. $snom . '&salert=' . $salert; +$param .= '&fourn_id=' . $fourn_id . '&snom='. $snom . '&salert=' . $salert . '&draftorder='.$draftorder; $param .= '&sref=' . $sref; $param .= '&mode=' . $mode; $param .= '&fk_supplier=' . $fk_supplier; @@ -534,7 +541,7 @@ if (!empty($conf->service->enabled) && $type == 1) print ' '; print ' '; print '' . $langs->trans('AlertOnly') . ' '; -print ' '; +print '' . $langs->trans('Draft') . ' '; print ' '; print ''; $searchpitco=$form->showFilterAndCheckAddButtons(0); @@ -584,7 +591,12 @@ while ($i < ($limit ? min($num, $limit) : $num)) } // Force call prod->load_stats_xxx to choose status to count (otherwise it is loaded by load_stock function) - $result=$prod->load_stats_commande_fournisseur(0,'1,2,3,4'); + if(isset($draftchecked)){ + $result=$prod->load_stats_commande_fournisseur(0,'0,1,2,3,4'); + }else { + $result=$prod->load_stats_commande_fournisseur(0,'1,2,3,4'); + } + $result=$prod->load_stats_reception(0,'4'); //print $prod->stats_commande_fournisseur['qty'].'
    '."\n"; @@ -671,11 +683,12 @@ print ''; if ($num > $conf->liste_limit) { - if ($sref || $snom || $sall || $salert || GETPOST('search', 'alpha')) + if ($sref || $snom || $sall || $salert || $draftorder || GETPOST('search', 'alpha')) { $filters = '&sref=' . $sref . '&snom=' . $snom; $filters .= '&sall=' . $sall; $filters .= '&salert=' . $salert; + $filters .= '&draftorder=' . $draftorder; $filters .= '&mode=' . $mode; $filters .= '&fk_supplier=' . $fk_supplier; $filters .= '&fk_entrepot=' . $fk_entrepot; @@ -687,6 +700,7 @@ if ($num > $conf->liste_limit) $filters .= '&fourn_id=' . $fourn_id; $filters .= (isset($type)? '&type=' . $type : ''); $filters .= '&salert=' . $salert; + $filters .= '&draftorder=' . $draftorder; $filters .= '&mode=' . $mode; $filters .= '&fk_supplier=' . $fk_supplier; $filters .= '&fk_entrepot=' . $fk_entrepot; From 6e0589ce2c756c0ea283520662909709fc4cc72e Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 7 Mar 2017 10:55:17 +0100 Subject: [PATCH 017/410] FIX : load multicurrency informations on supplier order and bill lines fetch --- .../class/fournisseur.commande.class.php | 57 ++++++++++--------- .../fourn/class/fournisseur.facture.class.php | 5 ++ 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index b2f2d3dc3c3..98ed0957b4e 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2752,7 +2752,8 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_ttc,'; $sql.= ' cd.total_localtax1, cd.total_localtax2,'; $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,'; - $sql.= ' cd.date_start, cd.date_end, cd.fk_unit'; + $sql.= ' cd.date_start, cd.date_end, cd.fk_unit,'; + $sql.= ' cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; $sql.= ' WHERE cd.rowid = '.$rowid; @@ -2760,33 +2761,37 @@ class CommandeFournisseurLigne extends CommonOrderLine if ($result) { $objp = $this->db->fetch_object($result); - $this->rowid = $objp->rowid; - $this->fk_commande = $objp->fk_commande; - $this->desc = $objp->description; - $this->qty = $objp->qty; - $this->subprice = $objp->subprice; - $this->tva_tx = $objp->tva_tx; - $this->localtax1_tx = $objp->localtax1_tx; - $this->localtax2_tx = $objp->localtax2_tx; - $this->remise = $objp->remise; - $this->remise_percent = $objp->remise_percent; - $this->fk_product = $objp->fk_product; - $this->info_bits = $objp->info_bits; - $this->total_ht = $objp->total_ht; - $this->total_tva = $objp->total_tva; - $this->total_localtax1 = $objp->total_localtax1; - $this->total_localtax2 = $objp->total_localtax2; - $this->total_ttc = $objp->total_ttc; - $this->product_type = $objp->product_type; + $this->rowid = $objp->rowid; + $this->fk_commande = $objp->fk_commande; + $this->desc = $objp->description; + $this->qty = $objp->qty; + $this->subprice = $objp->subprice; + $this->tva_tx = $objp->tva_tx; + $this->localtax1_tx = $objp->localtax1_tx; + $this->localtax2_tx = $objp->localtax2_tx; + $this->remise = $objp->remise; + $this->remise_percent = $objp->remise_percent; + $this->fk_product = $objp->fk_product; + $this->info_bits = $objp->info_bits; + $this->total_ht = $objp->total_ht; + $this->total_tva = $objp->total_tva; + $this->total_localtax1 = $objp->total_localtax1; + $this->total_localtax2 = $objp->total_localtax2; + $this->total_ttc = $objp->total_ttc; + $this->product_type = $objp->product_type; - $this->ref = $objp->product_ref; - $this->product_libelle = $objp->product_libelle; - $this->product_desc = $objp->product_desc; - - $this->date_start = $this->db->jdate($objp->date_start); - $this->date_end = $this->db->jdate($objp->date_end); - $this->fk_unit = $objp->fk_unit; + $this->ref = $objp->product_ref; + $this->product_libelle = $objp->product_libelle; + $this->product_desc = $objp->product_desc; + $this->date_start = $this->db->jdate($objp->date_start); + $this->date_end = $this->db->jdate($objp->date_end); + $this->fk_unit = $objp->fk_unit; + + $this->multicurrency_total_ht = $objp->multicurrency_total_ht; + $this->multicurrency_total_tva = $objp->multicurrency_total_tva; + $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; + $this->db->free($result); return 1; } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 27b7627f450..b76fb6a0e45 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2078,6 +2078,7 @@ class SupplierInvoiceLine extends CommonObjectLine $sql.= ', f.localtax1_type, f.localtax2_type, f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2 '; $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit'; $sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as label, p.description as product_desc'; + $sql.= ', f.multicurrency_total_ht, f.multicurrency_total_tva, multicurrency_total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det as f'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON f.fk_product = p.rowid'; $sql.= ' WHERE f.rowid = '.$rowid; @@ -2130,6 +2131,10 @@ class SupplierInvoiceLine extends CommonObjectLine $this->rang = $obj->rang; $this->fk_unit = $obj->fk_unit; + $this->multicurrency_total_ht = $obj->multicurrency_total_ht; + $this->multicurrency_total_tva = $obj->multicurrency_total_tva; + $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc; + return 1; } From b192b6cd507e32c959a7aa4ce410473a6d5329aa Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 7 Mar 2017 11:33:18 +0100 Subject: [PATCH 018/410] FIX : multicurrency_subprice --- htdocs/fourn/class/fournisseur.commande.class.php | 3 ++- htdocs/fourn/class/fournisseur.facture.class.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 98ed0957b4e..cc833fc72ce 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2753,7 +2753,7 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql.= ' cd.total_localtax1, cd.total_localtax2,'; $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,'; $sql.= ' cd.date_start, cd.date_end, cd.fk_unit,'; - $sql.= ' cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc'; + $sql.= ' cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; $sql.= ' WHERE cd.rowid = '.$rowid; @@ -2788,6 +2788,7 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->date_end = $this->db->jdate($objp->date_end); $this->fk_unit = $objp->fk_unit; + $this->multicurrency_subprice = $objp->multicurrency_subprice; $this->multicurrency_total_ht = $objp->multicurrency_total_ht; $this->multicurrency_total_tva = $objp->multicurrency_total_tva; $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b76fb6a0e45..20f68f52d65 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2078,7 +2078,7 @@ class SupplierInvoiceLine extends CommonObjectLine $sql.= ', f.localtax1_type, f.localtax2_type, f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2 '; $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit'; $sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as label, p.description as product_desc'; - $sql.= ', f.multicurrency_total_ht, f.multicurrency_total_tva, multicurrency_total_ttc'; + $sql.= ', f.multicurrency_subprice, f.multicurrency_total_ht, f.multicurrency_total_tva, multicurrency_total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det as f'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON f.fk_product = p.rowid'; $sql.= ' WHERE f.rowid = '.$rowid; @@ -2131,6 +2131,7 @@ class SupplierInvoiceLine extends CommonObjectLine $this->rang = $obj->rang; $this->fk_unit = $obj->fk_unit; + $this->multicurrency_subprice = $obj->multicurrency_subprice; $this->multicurrency_total_ht = $obj->multicurrency_total_ht; $this->multicurrency_total_tva = $obj->multicurrency_total_tva; $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc; From 9eb39758034a25c9e3b17fc7526006ff6212d845 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 7 Mar 2017 15:18:20 +0100 Subject: [PATCH 019/410] FIX : forgotten fk_facture_fourn attribute on supplierinvoice line object --- htdocs/fourn/class/fournisseur.facture.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 27b7627f450..af009e7ca11 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2076,7 +2076,7 @@ class SupplierInvoiceLine extends CommonObjectLine { $sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.tva_tx'; $sql.= ', f.localtax1_type, f.localtax2_type, f.localtax1_tx, f.localtax2_tx, f.total_localtax1, f.total_localtax2 '; - $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit'; + $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_facture_fourn, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit'; $sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as label, p.description as product_desc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det as f'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON f.fk_product = p.rowid'; @@ -2098,6 +2098,7 @@ class SupplierInvoiceLine extends CommonObjectLine $this->id = $obj->rowid; $this->rowid = $obj->rowid; + $this->fk_facture_fourn = $obj->fk_facture_fourn; $this->description = $obj->description; $this->product_ref = $obj->product_ref; $this->ref = $obj->product_ref; From 72606a6fa65dc18e42c621cbccc76aec02d222e4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Mar 2017 15:46:47 +0100 Subject: [PATCH 020/410] Fix english --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 85cf85ece96..64faedeb8b6 100644 --- a/README.md +++ b/README.md @@ -81,14 +81,15 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Standing orders management (European SEPA) - Bank accounts management - Shared calendar/agenda (with ical and vcal export for third party tools integration) -- Opportunities and/or project management (following project benefit including invoices, expense reports, time spent, ...) +- Opportunities and/or project management - Projects management - Contracts management - Stock management - Shipping management - Interventions management - Employee's leave requests management -- Expense report management +- Expense reports +- Timesheets - Electronic Document Management (EDM) - Foundations members management - Mass emailing From 8ac1aab45af59eb996ef7b84645aec65d7343a04 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Mar 2017 18:34:57 +0100 Subject: [PATCH 021/410] Uniformize look and feels --- htdocs/core/ajax/ajaxdirpreview.php | 3 ++- htdocs/core/class/html.formfile.class.php | 19 +++++++++++---- htdocs/ecm/docfile.php | 29 +++++++++++++++++------ 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index 28f78e22ef4..52411613e0b 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -192,6 +192,7 @@ if ($type == 'directory') // Auto area for expense report else if ($module == 'expensereport') $upload_dir = $conf->expensereport->dir_output; + // Automatic list if (in_array($module, $automodules)) { $param.='&module='.$module; @@ -200,7 +201,7 @@ if ($type == 'directory') $filearray=dol_dir_list($upload_dir,"files",1,'', $excludefiles, $sortfield, $sorting,1); $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); } - //Manual area + // Manual list else { $relativepath=$ecmdir->getRelativePath(); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index e80ff8008df..44b6a8adcd7 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1115,6 +1115,7 @@ class FormFile print "\n"; print ''.dol_print_size($file['size'],1,1).''; print ''.dol_print_date($file['date'],"dayhour","tzuser").''; + // Preview if (empty($useinecm)) { @@ -1420,6 +1421,13 @@ class FormFile print ''; if ($found > 0 && is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) print $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]->getNomUrl(1,'document'); else print $langs->trans("ObjectDeleted",($id?$id:$ref)); + + $filename=dol_sanitizeFileName($ref); + //$filedir=$conf->$modulepart->dir_output . '/' . dol_sanitizeFileName($obj->ref); + $filedir=$file['path']; + //$urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid; + //print $formfile->getDocumentsLink($modulepart, $filename, $filedir); + print ''; print ''; //print "XX".$file['name']; //$file['name'] must be utf8 @@ -1429,14 +1437,17 @@ class FormFile print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')').' '; print dol_trunc($file['name'],$maxlength,'middle'); print ''; + + print $this->getDocumentsLink($modulepart, $filename, $filedir); + print "\n"; print ''.dol_print_size($file['size'],1,1).''; print ''.dol_print_date($file['date'],"dayhour").''; print ''; - if (! empty($useinecm)) print ''; - print img_view().'   '; + //if (! empty($useinecm)) print ''; + //print img_view().'   '; //if ($permtodelete) print ''.img_delete().''; //else print ' '; print "\n"; diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index 9a0ca16f662..3b6455fe4a9 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2008-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 @@ -61,6 +61,8 @@ $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="label"; +$cancel=GETPOST('cancel'); +$action=GETPOST('action'); $section=GETPOST("section"); if (! $section) { @@ -107,8 +109,23 @@ if (! empty($_GET["fileid"])) * Put here all code to do according to value of "action" parameter ********************************************************************/ +if ($action == 'cancel') +{ + $action =''; + if ($backtourl) + { + header("Location: ".$backtourl); + exit; + } + else + { + header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager§ion='.$section); + exit; + } +} + // Rename file -if (GETPOST('action') == 'update' && ! GETPOST('cancel')) +if ($action == 'update') { $error=0; @@ -131,7 +148,7 @@ if (GETPOST('action') == 'update' && ! GETPOST('cancel')) if (! $result) { $langs->load('errors'); - $mesg='
    '.$langs->trans('ErrorFailToRenameFile',$oldfile,$newfile).'
    '; + setEventMessages($langs->trans('ErrorFailToRenameFile',$oldfile,$newfile), null, 'errors'); $error++; } } @@ -279,16 +296,14 @@ if ($_GET['action'] == 'delete_file') if ($_GET["action"] != 'edit') { - - if ($mesg) { print $mesg."
    "; } - - // Actions buttons print '
    '; if ($user->rights->ecm->setup) { print ''.$langs->trans('Edit').''; + + print ''.$langs->trans('Cancel').''; } /* if ($user->rights->ecm->setup) From fd0a46c5cfa1b011fe0a1c99e271aafcf5f9c5de Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 7 Mar 2017 22:31:34 +0100 Subject: [PATCH 022/410] New : add donations statistics in home statistics --- htdocs/core/modules/modDon.class.php | 2 +- htdocs/don/class/don.class.php | 35 +++++++++++++++++++++++++++- htdocs/index.php | 24 ++++++++++++------- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/htdocs/core/modules/modDon.class.php b/htdocs/core/modules/modDon.class.php index f69cb1b5331..26dd397c913 100644 --- a/htdocs/core/modules/modDon.class.php +++ b/htdocs/core/modules/modDon.class.php @@ -32,7 +32,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** * Class to describe and enable module Donation */ -class modDon extends DolibarrModules +class modDon extends DolibarrModules { /** diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index d7e4d84baab..74349a16271 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2009 Regis Houssin * Copyright (C) 2014 Florian Henry - * Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 2015-2017 Alexandre Spangaro * Copyright (C) 2016 Juanjo Menent * * This program is free software; you can redistribute it and/or modify @@ -804,6 +804,39 @@ class Don extends CommonObject return $result; } + /** + * Charge indicateurs this->nb pour le tableau de bord + * + * @return int <0 if KO, >0 if OK + */ + function load_state_board() + { + global $conf; + + $this->nb=array(); + + $sql = "SELECT count(d.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."don as d"; + $sql.= " WHERE d.fk_statut > 0"; + $sql.= " AND d.entity IN (".getEntity('don', 1).")"; + + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["donations"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } /** * Return clicable name (with picto eventually) diff --git a/htdocs/index.php b/htdocs/index.php index eab8844b960..21210904abb 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -159,7 +159,8 @@ if (empty($user->societe_id)) ! empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS), ! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS), ! empty($conf->projet->enabled) && $user->rights->projet->lire, - ! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire + ! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire, + ! empty($conf->don->enabled) && $user->rights->don->lire ); // Class file containing the method load_state_board for each line $includes=array( @@ -180,7 +181,8 @@ if (empty($user->societe_id)) DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.facture.class.php", DOL_DOCUMENT_ROOT."/supplier_proposal/class/supplier_proposal.class.php", DOL_DOCUMENT_ROOT."/projet/class/project.class.php", - DOL_DOCUMENT_ROOT."/expensereport/class/expensereport.class.php" + DOL_DOCUMENT_ROOT."/expensereport/class/expensereport.class.php", + DOL_DOCUMENT_ROOT."/don/class/don.class.php" ); // Name class containing the method load_state_board for each line $classes=array('User', @@ -200,7 +202,8 @@ if (empty($user->societe_id)) 'FactureFournisseur', 'SupplierProposal', 'Project', - 'ExpenseReport' + 'ExpenseReport', + 'Don' ); // Cle array returned by the method load_state_board for each line $keys=array('users', @@ -220,7 +223,8 @@ if (empty($user->societe_id)) 'supplier_invoices', 'askprice', 'projects', - 'expensereports' + 'expensereports', + 'donations' ); // Dashboard Icon lines $icons=array('user', @@ -240,7 +244,8 @@ if (empty($user->societe_id)) 'bill', 'propal', 'project', - 'trip' + 'trip', + 'generic' ); // Translation keyword $titres=array("Users", @@ -260,7 +265,8 @@ if (empty($user->societe_id)) "SuppliersInvoices", "SupplierProposalShort", "Projects", - "ExpenseReports" + "ExpenseReports", + "Donations" ); // Dashboard Link lines $links=array( @@ -281,7 +287,8 @@ if (empty($user->societe_id)) DOL_URL_ROOT.'/fourn/facture/list.php', DOL_URL_ROOT.'/supplier_proposal/list.php', DOL_URL_ROOT.'/projet/list.php?mainmenu=project', - DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm' + DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm', + DOL_URL_ROOT.'/don/list.php?leftmenu=donations' ); // Translation lang files $langfile=array("users", @@ -301,7 +308,8 @@ if (empty($user->societe_id)) "bills", "supplier_proposal", "projects", - "trips" + "trips", + "donations" ); From 184d52525a0b89f96e16b7933457e321a2435e8d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Mar 2017 22:45:22 +0100 Subject: [PATCH 023/410] PHP code to manage pair/impair is replaced by native CSS. --- htdocs/adherents/index.php | 143 +++++++++++----------- htdocs/adherents/type.php | 10 +- htdocs/comm/index.php | 24 ++-- htdocs/commande/index.php | 10 +- htdocs/compta/index.php | 78 ++++++------ htdocs/compta/paiement/cheque/index.php | 14 +-- htdocs/compta/prelevement/index.php | 12 +- htdocs/contrat/index.php | 18 +-- htdocs/core/boxes/box_actions.php | 5 +- htdocs/core/boxes/modules_boxes.php | 5 +- htdocs/core/lib/agenda.lib.php | 8 +- htdocs/don/index.php | 4 +- htdocs/expedition/index.php | 8 +- htdocs/expensereport/index.php | 12 +- htdocs/fichinter/index.php | 8 +- htdocs/fourn/commande/index.php | 14 +-- htdocs/hrm/index.php | 28 ++--- htdocs/index.php | 33 ++--- htdocs/product/index.php | 4 +- htdocs/product/stock/index.php | 16 +-- htdocs/projet/graph_opportunities.inc.php | 2 +- htdocs/supplier_proposal/index.php | 8 +- htdocs/theme/eldy/style.css.php | 115 ++++++++--------- htdocs/theme/md/style.css.php | 84 +++++++------ 24 files changed, 329 insertions(+), 334 deletions(-) diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index ef20c2e96c0..9c1b0bb01e1 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -163,7 +163,7 @@ if (! empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is usele if ($conf->use_javascript_ajax) { print ''; - print ''; + print ''; print '
    '.$langs->trans("Statistics").'
    '.$langs->trans("Statistics").'
    '; $SommeA=0; @@ -201,8 +201,70 @@ if ($conf->use_javascript_ajax) print '
    '; } +print '
    '; + +// List of subscription by year +$Total=array(); +$Number=array(); +$tot=0; +$numb=0; + +$sql = "SELECT c.subscription, c.dateadh as dateh"; +$sql.= " FROM ".MAIN_DB_PREFIX."adherent as d, ".MAIN_DB_PREFIX."subscription as c"; +$sql.= " WHERE d.entity IN (".getEntity().")"; +$sql.= " AND d.rowid = c.fk_adherent"; +if(isset($date_select) && $date_select != '') +{ + $sql .= " AND c.dateadh LIKE '".$date_select."%'"; +} +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $db->fetch_object($result); + $year=dol_print_date($db->jdate($objp->dateh),"%Y"); + $Total[$year]=(isset($Total[$year])?$Total[$year]:0)+$objp->subscription; + $Number[$year]=(isset($Number[$year])?$Number[$year]:0)+1; + $tot+=$objp->subscription; + $numb+=1; + $i++; + } +} + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +$var=true; +krsort($Total); +foreach ($Total as $key=>$value) +{ + $var=!$var; + print ""; + print ""; + print ""; + print ""; + print ""; + print "\n"; +} + +// Total +print ''; +print ''; +print ""; +print '"; +print ""; +print "\n"; +print "
    '.$langs->trans("Subscriptions").''.$langs->trans("Number").''.$langs->trans("AmountTotal").''.$langs->trans("AmountAverage").'
    $key".$Number[$key]."".price($value)."".price(price2num($value/$Number[$key],'MT'))."
    '.$langs->trans("Total").'".$numb."'.price($tot)."".price(price2num($numb>0?($tot/$numb):0,'MT'))."

    \n"; + -//print ''; print '
    '; @@ -227,7 +289,7 @@ if ($resql) { print ''; print ''; - print ''; + print ''; $num = $db->num_rows($resql); if ($num) @@ -290,7 +352,7 @@ if ($resql) { print '
    '.$langs->trans("LastMembersModified",$max).'
    '.$langs->trans("LastMembersModified",$max).'
    '; print ''; - print ''; + print ''; $num = $db->num_rows($resql); if ($num) @@ -336,11 +398,11 @@ else // Summary of members by type print '
    '.$langs->trans("LastSubscriptionsModified",$max).'
    '.$langs->trans("LastSubscriptionsModified",$max).'
    '; print ''; -print ''; -print ''; -print ''; -print ''; -print ''; +print ''; +print ''; +print ''; +print ''; +print ''; print "\n"; foreach ($AdherentType as $key => $adhtype) @@ -363,71 +425,8 @@ print ''; print "
    '.$langs->trans("MembersTypes").''.$langs->trans("MembersStatusToValid").''.$langs->trans("MenuMembersNotUpToDate").''.$langs->trans("MenuMembersUpToDate").''.$langs->trans("MembersStatusResiliated").''.$langs->trans("MembersTypes").''.$langs->trans("MembersStatusToValid").''.$langs->trans("MenuMembersNotUpToDate").''.$langs->trans("MenuMembersUpToDate").''.$langs->trans("MembersStatusResiliated").'
    '.$SommeD.' '.$staticmember->LibSta print '
    \n"; -print "
    \n"; -// List of subscription by year -$Total=array(); -$Number=array(); -$tot=0; -$numb=0; - -$sql = "SELECT c.subscription, c.dateadh as dateh"; -$sql.= " FROM ".MAIN_DB_PREFIX."adherent as d, ".MAIN_DB_PREFIX."subscription as c"; -$sql.= " WHERE d.entity IN (".getEntity().")"; -$sql.= " AND d.rowid = c.fk_adherent"; -if(isset($date_select) && $date_select != '') -{ - $sql .= " AND c.dateadh LIKE '".$date_select."%'"; -} -$result = $db->query($sql); -if ($result) -{ - $num = $db->num_rows($result); - $i = 0; - while ($i < $num) - { - $objp = $db->fetch_object($result); - $year=dol_print_date($db->jdate($objp->dateh),"%Y"); - $Total[$year]=(isset($Total[$year])?$Total[$year]:0)+$objp->subscription; - $Number[$year]=(isset($Number[$year])?$Number[$year]:0)+1; - $tot+=$objp->subscription; - $numb+=1; - $i++; - } -} - -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print "\n"; - -$var=true; -krsort($Total); -foreach ($Total as $key=>$value) -{ - $var=!$var; - print ""; - print ""; - print ""; - print ""; - print ""; - print "\n"; -} - -// Total -print ''; -print ''; -print ""; -print '"; -print ""; -print "\n"; -print "
    '.$langs->trans("Subscriptions").''.$langs->trans("Number").''.$langs->trans("AmountTotal").''.$langs->trans("AmountAverage").'
    $key".$Number[$key]."".price($value)."".price(price2num($value/$Number[$key],'MT'))."
    '.$langs->trans("Total").'".$numb."'.price($tot)."".price(price2num($numb>0?($tot/$numb):0,'MT'))."

    \n"; - -//print ''; print '
    '; diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 3ad6120be02..846b0dab7a9 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -199,11 +199,11 @@ if (! $rowid && $action != 'create' && $action != 'edit') print ''."\n"; print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print "\n"; $var=True; diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index c967f303648..f8f987f1222 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -158,7 +158,7 @@ if (! empty($conf->propal->enabled) && $user->rights->propal->lire) print '
    '.$langs->trans("Ref").''.$langs->trans("Label").''.$langs->trans("SubscriptionRequired").''.$langs->trans("VoteAllowed").' '.$langs->trans("Ref").''.$langs->trans("Label").''.$langs->trans("SubscriptionRequired").''.$langs->trans("VoteAllowed").' 
    '; print ''; - print ''; + print ''; if ($num > 0) { @@ -239,7 +239,7 @@ if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_propos print '
    '.$langs->trans("ProposalsDraft").($num?' '.$num.'':'').'
    '.$langs->trans("ProposalsDraft").($num?' '.$num.'':'').'
    '; print ''; - print ''; + print ''; if ($num > 0) { @@ -318,7 +318,7 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire) print '
    '.$langs->trans("SupplierProposalsDraft").($num?' '.$num.'':'').'
    '.$langs->trans("SupplierProposalsDraft").($num?' '.$num.'':'').'
    '; print ''; - print ''; + print ''; if ($num) { @@ -399,7 +399,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande print '
    '.$langs->trans("DraftOrders").($num?' '.$num.'':'').'
    '.$langs->trans("DraftOrders").($num?' '.$num.'':'').'
    '; print ''; - print ''; + print ''; if ($num) { @@ -485,12 +485,12 @@ if (! empty($conf->societe->enabled) && $user->rights->societe->lire) print '
    '.$langs->trans("DraftSuppliersOrders").($num?' '.$num.'':'').'
    '.$langs->trans("DraftSuppliersOrders").($num?' '.$num.'':'').'
    '; print ''; - print ''; + print ''; + print ''; print ''; if ($num) { @@ -549,8 +549,8 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->societe->lire) $i = 0; print '
    '; + print ''; if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastCustomersOrProspects",$max); else if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastModifiedProspects",$max); else print $langs->trans("BoxTitleLastModifiedCustomers",$max); - print ''; - print ''.$langs->trans("DateModificationShort").''.$langs->trans("DateModificationShort").'
    '; - print ''; - print ''; + print ''; + print ''; print ''; if ($num) { @@ -628,7 +628,7 @@ if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) // TO if ($num > 0) { print '
    '.$langs->trans("BoxTitleLastModifiedSuppliers",min($max,$num)).''.$langs->trans("DateModificationShort").'
    '.$langs->trans("BoxTitleLastModifiedSuppliers",min($max,$num)).''.$langs->trans("DateModificationShort").'
    '; - print ''; + print ''; $i = 0; $staticcontrat=new Contrat($db); @@ -689,7 +689,7 @@ if (! empty($conf->propal->enabled) && $user->rights->propal->lire) $var=true; print '
    '.$langs->trans("LastContracts",5).'
    '.$langs->trans("LastContracts",5).'
    '; - print ''; + print ''; $nbofloop=min($num, (empty($conf->global->MAIN_MAXLIST_OVERLOAD)?500:$conf->global->MAIN_MAXLIST_OVERLOAD)); while ($i < $nbofloop) @@ -788,7 +788,7 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire) $var=true; print '
    '.$langs->trans("ProposalsOpened").' '.$num.'
    '.$langs->trans("ProposalsOpened").' '.$num.'
    '; - print ''; + print ''; $nbofloop=min($num, (empty($conf->global->MAIN_MAXLIST_OVERLOAD)?500:$conf->global->MAIN_MAXLIST_OVERLOAD)); while ($i < $nbofloop) diff --git a/htdocs/commande/index.php b/htdocs/commande/index.php index 24e07b5ab07..f24202f7fff 100644 --- a/htdocs/commande/index.php +++ b/htdocs/commande/index.php @@ -119,7 +119,7 @@ if ($resql) } $db->free($resql); print '
    '.$langs->trans("OrdersOpened").' '.$num.'
    '.$langs->trans("OrdersOpened").' '.$num.'
    '; - print ''."\n"; + print ''."\n"; $listofstatus=array(0,1,2,3,3,-1); $bool=false; foreach ($listofstatus as $status) @@ -187,7 +187,7 @@ if (! empty($conf->commande->enabled)) { print '
    '.$langs->trans("Statistics").' - '.$langs->trans("CustomersOrders").'
    '.$langs->trans("Statistics").' - '.$langs->trans("CustomersOrders").'
    '; print ''; - print ''; + print ''; $langs->load("orders"); $num = $db->num_rows($resql); if ($num) @@ -259,7 +259,7 @@ if ($resql) { print '
    '.$langs->trans("DraftOrders").'
    '.$langs->trans("DraftOrders").'
    '; print ''; - print ''; + print ''; $num = $db->num_rows($resql); if ($num) @@ -341,7 +341,7 @@ if (! empty($conf->commande->enabled)) print '
    '.$langs->trans("LastModifiedOrders",$max).'
    '.$langs->trans("LastModifiedOrders",$max).'
    '; print ''; - print ''; + print ''; if ($num) { @@ -423,7 +423,7 @@ if (! empty($conf->commande->enabled)) print '
    '.$langs->trans("OrdersToProcess").' '.$num.'
    '.$langs->trans("OrdersToProcess").' '.$num.'
    '; print ''; - print ''; + print ''; if ($num) { diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index 44d9aa4d3c1..ea8d47b264e 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -162,7 +162,7 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) print '
    '.$langs->trans("OnProcessOrders").' '.$num.'
    '.$langs->trans("OnProcessOrders").' '.$num.'
    '; print ''; - print ''; + print ''; if ($num) { $companystatic=new Societe($db); @@ -238,7 +238,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- print '
    '.$langs->trans("CustomersDraftInvoices").($num?' '.$num.'':'').'
    '.$langs->trans("CustomersDraftInvoices").($num?' '.$num.'':'').'
    '; print ''; - print ''; + print ''; if ($num) { $companystatic=new Societe($db); @@ -324,11 +324,11 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) $i = 0; print '
    '.$langs->trans("SuppliersDraftInvoices").($num?' '.$num.'':'').'
    '.$langs->trans("SuppliersDraftInvoices").($num?' '.$num.'':'').'
    '; - print ''; - if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; - print ''; - print ''; - print ''; + print ''; + if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; + print ''; + print ''; + print ''; print ''; if ($num) { @@ -432,11 +432,11 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- $num = $db->num_rows($resql); print '
    '.$langs->trans("BoxTitleLastCustomerBills",$max).''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' 
    '.$langs->trans("BoxTitleLastCustomerBills",$max).''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' 
    '; - print ''; - if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; - print ''; - print ''; - print ''; + print ''; + if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; + print ''; + print ''; + print ''; print "\n"; if ($num) { @@ -513,10 +513,10 @@ if (! empty($conf->don->enabled) && $user->rights->societe->lire) print '
    '.$langs->trans("BoxTitleLastSupplierBills",$max).''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' 
    '.$langs->trans("BoxTitleLastSupplierBills",$max).''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' 
    '; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print ''; if ($num) { @@ -581,11 +581,11 @@ if (! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) print '
    '.$langs->trans("BoxTitleLastModifiedDonations",$max).''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' '.$langs->trans("BoxTitleLastModifiedDonations",$max).''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' 
    '; print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print ''; if ($num) { @@ -667,11 +667,11 @@ if (! empty($conf->facture->enabled) && ! empty($conf->commande->enabled) && $us $i = 0; print '
    '.$langs->trans("ContributionsToPay").($num?' '.$num.'':'').''.$langs->trans("DateDue").''.$langs->trans("AmountTTC").''.$langs->trans("Paid").' '.$langs->trans("ContributionsToPay").($num?' '.$num.'':'').''.$langs->trans("DateDue").''.$langs->trans("AmountTTC").''.$langs->trans("Paid").' 
    '; print ""; - print ''; - if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; - print ''; - print ''; - print ''; + print ''; + if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; + print ''; + print ''; + print ''; print ''; $tot_ht=$tot_ttc=$tot_tobill=0; $societestatic = new Societe($db); @@ -769,12 +769,12 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) $i = 0; print '
    '.$langs->trans("OrdersDeliveredToBill").' '.$num.''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("ToBill").' '.$langs->trans("OrdersDeliveredToBill").' '.$num.''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("ToBill").' 
    '; - print ''; - print ''; - if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; + print ''; + print ''; + print ''; print ''; if ($num) { @@ -891,12 +891,12 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- $num = $db->num_rows($resql); print '
    '.$langs->trans("BillsCustomersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("Received").' 
    '.$langs->trans("BillsCustomersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("Received").' 
    '; - print ''; - print ''; - if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print ''; + print ''; + print ''; + print ''; print "\n"; $societestatic = new Societe($db); if ($num) @@ -963,7 +963,7 @@ $resql = 0; if ($resql) { print '
    '.$langs->trans("BillsSuppliersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("Paid").' 
    '.$langs->trans("BillsSuppliersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("Paid").' 
    '; - print ''; + print ''.$langs->trans("TasksToDo").''; print "\n"; $var = true; $i = 0; diff --git a/htdocs/compta/paiement/cheque/index.php b/htdocs/compta/paiement/cheque/index.php index 887868fb594..bba49827104 100644 --- a/htdocs/compta/paiement/cheque/index.php +++ b/htdocs/compta/paiement/cheque/index.php @@ -67,7 +67,7 @@ $resql = $db->query($sql); print '
    '.$langs->trans("TasksToDo").'
    '; print ''; -print '\n"; +print '\n"; print "\n"; if ($resql) @@ -111,12 +111,12 @@ if ($resql) { print '
    '.$langs->trans("BankChecks")."'.$langs->trans("BankChecks")."
    '; print ''; - print ''; - print '"; - print ''; - print ''; - print ''; - print ''; + print ''; + print '"; + print ''; + print ''; + print ''; + print ''; print "\n"; $var=true; diff --git a/htdocs/compta/prelevement/index.php b/htdocs/compta/prelevement/index.php index 9e766e937e2..440af1cdbaf 100644 --- a/htdocs/compta/prelevement/index.php +++ b/htdocs/compta/prelevement/index.php @@ -74,7 +74,7 @@ $bprev = new BonPrelevement($db); $var=true; print '
    '.$langs->trans("LastCheckReceiptShort",$max).''.$langs->trans("Date")."'.$langs->trans("Account").''.$langs->trans("NbOfCheques").''.$langs->trans("Amount").''.$langs->trans("Status").''.$langs->trans("LastCheckReceiptShort",$max).''.$langs->trans("Date")."'.$langs->trans("Account").''.$langs->trans("NbOfCheques").''.$langs->trans("Amount").''.$langs->trans("Status").'
    '; -print ''; +print ''; $var=!$var; print ''; print '\n"; // Activate/Disable and Setup (2 columns) - if (! empty($conf->global->$const_name)) // If module is activated + if (! empty($conf->global->$const_name)) // If module is already activated { $disableSetup = 0; @@ -699,12 +711,12 @@ if ($mode == 'common') } } - else // Module not activated + else // Module not yet activated { print ''; } + // Numero statement if (! empty($arrayfields['b.num_releve']['checked'])) { - // Numero statement print ''; } + // Conciliated + if (! empty($arrayfields['b.conciliated']['checked'])) + { + print ''; + } print ''; print ''; + if (! $i) $totalarray['nbfield']++; + } + // Action edit/delete print ''; - $var = ! $var; - print ""; - print ''; - if (! empty($conf->global->BANK_DISABLE_DIRECT_INPUT)) { - print ''; - } else { - print ''; - } - print ''; - $var = ! $var; print ""; print ''; diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index ad3817f28cd..3fabed83d93 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -4,8 +4,9 @@ * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2012 Vinícius Nogueira * Copyright (C) 2014 Florian Henry - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016 Juanjo Menent + * Copyright (C) 2017 Alexandre Spangaro * * 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 @@ -405,28 +406,19 @@ if ($id > 0 || ! empty($ref)) dol_fiche_end(); - - /* * Buttons actions */ - if ($action != 'addline' && $action != 'reconcile') + if ($action != 'reconcile') { print '
    '; - - if ($action != 'addline') - { - if (empty($conf->global->BANK_DISABLE_DIRECT_INPUT)) - { - if ($user->rights->banque->modifier) { - print ''.$langs->trans("AddBankRecord").''; - } else { - print ''.$langs->trans("AddBankRecord").''; - } - } else { - print ''.$langs->trans("AddBankRecord").''; - } - } + + if ($user->rights->banque->modifier) { + print ''.$langs->trans("AddBankRecord").''; + } else { + print ''.$langs->trans("AddBankRecord").''; + } + if ($object->canBeConciliated() > 0) { // If not cash account and can be reconciliate if ($user->rights->banque->consolidate) { @@ -636,49 +628,6 @@ if ($resql) // print '
    '.$langs->trans("Statistics").'
    '.$langs->trans("Statistics").'
    '.$langs->trans("NbOfInvoiceToWithdraw").''; @@ -114,7 +114,7 @@ if ($resql) print ''; print ''; - print ''; + print ''; if ($num) { $var = True; @@ -188,10 +188,10 @@ if ($result) print"\n\n"; print '
    '.$langs->trans("InvoiceWaitingWithdraw").' ('.$num.')
    '.$langs->trans("InvoiceWaitingWithdraw").' ('.$num.')
    '; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print ''; while ($i < min($num,$limit)) diff --git a/htdocs/contrat/index.php b/htdocs/contrat/index.php index b1d99c60d20..9ec924254a9 100644 --- a/htdocs/contrat/index.php +++ b/htdocs/contrat/index.php @@ -180,7 +180,7 @@ else print '
    '.$langs->trans("LastWithdrawalReceipt",$limit).''.$langs->trans("Date").''.$langs->trans("Amount").''.$langs->trans("Status").'
    '.$langs->trans("LastWithdrawalReceipt",$limit).''.$langs->trans("Date").''.$langs->trans("Amount").''.$langs->trans("Status").'
    '; -print ''."\n"; +print ''."\n"; $var=true; $listofstatus=array(0,4,4,5); $bool=false; foreach($listofstatus as $status) @@ -248,7 +248,7 @@ if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire) print '
    '.$langs->trans("Statistics").' - '.$langs->trans("Services").'
    '.$langs->trans("Statistics").' - '.$langs->trans("Services").'
    '; print ''; - print ''; + print ''; if ($num) { $companystatic=new Societe($db); @@ -324,10 +324,10 @@ if ($result) print '
    '.$langs->trans("DraftContracts").($num?' '.$num.'':'').'
    '.$langs->trans("DraftContracts").($num?' '.$num.'':'').'
    '; - print ''; - print ''; - //print ''; - print ''; + print ''; + print ''; + //print ''; + print ''; print "\n"; $var=True; @@ -394,7 +394,7 @@ if ($resql) print '
    '.$langs->trans("LastContracts",5).''.$langs->trans("DateModification").''.$langs->trans("Status").''.$langs->trans("Services").'
    '.$langs->trans("LastContracts",5).''.$langs->trans("DateModification").''.$langs->trans("Status").''.$langs->trans("Services").'
    '; - print ''; + print ''; print "\n"; $var=True; @@ -475,7 +475,7 @@ if ($resql) print '
    '.$langs->trans("LastModifiedServices",$max).'
    '.$langs->trans("LastModifiedServices",$max).'
    '; - print ''; + print ''; print "\n"; $var=True; @@ -556,7 +556,7 @@ if ($resql) print '
    '.$langs->trans("NotActivatedServices").' '.$num.'
    '.$langs->trans("NotActivatedServices").' '.$num.'
    '; - print ''; + print ''; print "\n"; $var=True; diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php index 973738fec11..c406ada6fa5 100644 --- a/htdocs/core/boxes/box_actions.php +++ b/htdocs/core/boxes/box_actions.php @@ -180,9 +180,6 @@ class box_actions extends ModeleBoxes $actioncejour=false; $contents=$this->info_box_contents; $nblines=count($contents); - $bcx=array(); - $bcx[0] = 'class="box_pair"'; - $bcx[1] = 'class="box_impair"'; if ($contents[0][0]['text'] != $langs->trans("NoActionsToDo")) { $out.= '
    trans("ActionsToDo").'">'; @@ -204,7 +201,7 @@ class box_actions extends ModeleBoxes $urlsoc=$contents[$line][3]['url']; $dateligne=$contents[$line][4]['text']; $percentage=$contents[$line][5]['text']; - $out.= '
    '; + $out.= ''; $out.= ''; diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 0f754682925..9a093cff927 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -206,9 +206,6 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" require_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php'; $MAXLENGTHBOX=60; // Mettre 0 pour pas de limite - $bcx = array(); - $bcx[0] = 'class="box_pair"'; - $bcx[1] = 'class="box_impair"'; $var = false; $cachetime = 900; // 900 : 15mn @@ -284,7 +281,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" // TR if (isset($contents[$i][0]['tr'])) $out.= ''; - else $out.= ''; + else $out.= ''; // Loop on each TD $nbcolthisline=count($contents[$i]); diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 09f89ba0c3f..91c5d24f36c 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -238,8 +238,8 @@ function show_array_actions_to_do($max=5) $num = $db->num_rows($resql); print '
    '.$langs->trans("ListOfExpiredServices").' '.$num.'
    '.$langs->trans("ListOfExpiredServices").' '.$num.'
    '; $out.= img_object("",$logo); $out.= '
    '; - print ''; - print ''; + print ''; print ''; $var = true; @@ -335,8 +335,8 @@ function show_array_last_actions_done($max=5) $num = $db->num_rows($resql); print '
    '.$langs->trans("LastActionsToDo",$max).''.$langs->trans("FullList").''; + print '
    '.$langs->trans("LastActionsToDo",$max).''.$langs->trans("FullList").'
    '; - print ''; - print ''; + print ''; print ''; $var = true; $i = 0; diff --git a/htdocs/don/index.php b/htdocs/don/index.php index daf82d85bbc..de4d84529fe 100644 --- a/htdocs/don/index.php +++ b/htdocs/don/index.php @@ -112,7 +112,7 @@ if (! empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is usele print '
    '.$langs->trans("LastDoneTasks",$max).''.$langs->trans("FullList").''; + print '
    '.$langs->trans("LastDoneTasks",$max).''.$langs->trans("FullList").'
    '; print ''; -print ''; +print ''; print "\n"; $listofstatus=array(0,1,-1,2); @@ -182,7 +182,7 @@ if ($resql) { print '
    '.$langs->trans("Statistics").''.$langs->trans("Statistics").'
    '; print ''; - print ''; + print ''; $num = $db->num_rows($resql); if ($num) diff --git a/htdocs/expedition/index.php b/htdocs/expedition/index.php index e9bfa8a484c..17f349348ff 100644 --- a/htdocs/expedition/index.php +++ b/htdocs/expedition/index.php @@ -88,7 +88,7 @@ if ($resql) { print '
    '.$langs->trans("LastModifiedDonations",$max).'
    '.$langs->trans("LastModifiedDonations",$max).'
    '; print ''; - print ''; + print ''; $i = 0; $var = True; while ($i < $num) @@ -141,7 +141,7 @@ if ($resql) $i = 0; print '
    '.$langs->trans("SendingsToValidate").'
    '.$langs->trans("SendingsToValidate").'
    '; print ''; - print ''; + print ''; $var = True; while ($i < $num) { @@ -203,7 +203,7 @@ if ( $resql ) $i = 0; print '
    '.$langs->trans("OrdersToProcess").'
    '.$langs->trans("OrdersToProcess").'
    '; print ''; - print ''; + print ''; $var = True; while ($i < $num) { @@ -264,7 +264,7 @@ if ($resql) $i = 0; print '
    '.$langs->trans("OrdersInProcess").'
    '.$langs->trans("OrdersInProcess").'
    '; print ''; - print ''; + print ''; $var = True; while ($i < $num) { diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index 2b317a0b751..3f37be8fb8d 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -112,7 +112,7 @@ print '
    '; print '
    '.$langs->trans("LastSendings",$num).'
    '.$langs->trans("LastSendings",$num).'
    '; print ''; -print ''; +print ''; print "\n"; $listoftype=$tripandexpense_static->listOfTypes(); @@ -174,11 +174,11 @@ if ($result) print '
    '.$langs->trans("Statistics").''.$langs->trans("Statistics").'
    '; print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print ''; if ($num) { diff --git a/htdocs/fichinter/index.php b/htdocs/fichinter/index.php index f1592b1e13b..59f94df5f7b 100644 --- a/htdocs/fichinter/index.php +++ b/htdocs/fichinter/index.php @@ -116,7 +116,7 @@ if ($resql) } $db->free($resql); print '
    '.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' '.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).''.$langs->trans("AmountHT").''.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").' 
    '; - print ''."\n"; + print ''."\n"; $listofstatus=array(0,1,2); $bool=false; foreach ($listofstatus as $status) @@ -181,7 +181,7 @@ if (! empty($conf->ficheinter->enabled)) { print '
    '.$langs->trans("Statistics").' - '.$langs->trans("Interventions").'
    '.$langs->trans("Statistics").' - '.$langs->trans("Interventions").'
    '; print ''; - print ''; + print ''; $langs->load("fichinter"); $num = $db->num_rows($resql); if ($num) @@ -231,7 +231,7 @@ if ($resql) { print '
    '.$langs->trans("DraftFichinter").'
    '.$langs->trans("DraftFichinter").'
    '; print ''; - print ''; + print ''; $num = $db->num_rows($resql); if ($num) @@ -303,7 +303,7 @@ if (! empty($conf->ficheinter->enabled)) print '
    '.$langs->trans("LastModifiedInterventions",$max).'
    '.$langs->trans("LastModifiedInterventions",$max).'
    '; print ''; - print ''; + print ''; if ($num) { diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php index 8ad4b9f4857..be27733294f 100644 --- a/htdocs/fourn/commande/index.php +++ b/htdocs/fourn/commande/index.php @@ -112,7 +112,7 @@ if ($resql) $db->free($resql); print '
    '.$langs->trans("FichinterToProcess").' '.$num.'
    '.$langs->trans("FichinterToProcess").' '.$num.'
    '; - print ''; + print ''; print "\n"; foreach (array(0,1,2,3,4,5,6) as $statut) { @@ -169,8 +169,8 @@ if ($resql) print '
    '.$langs->trans("Statistics").' - '.$langs->trans("SuppliersOrders").'
    '.$langs->trans("Statistics").' - '.$langs->trans("SuppliersOrders").'
    '; - print ''; - print ''; + print ''; + print ''; print "\n"; $var=True; @@ -216,7 +216,7 @@ if (! empty($conf->fournisseur->enabled)) { print '
    '.$langs->trans("Status").''.$langs->trans("Nb").'
    '.$langs->trans("Status").''.$langs->trans("Nb").'
    '; print ''; - print ''; + print ''; $langs->load("orders"); $num = $db->num_rows($resql); if ($num) @@ -261,7 +261,7 @@ if ($resql) $i = 0; print '
    '.$langs->trans("DraftOrders").'
    '.$langs->trans("DraftOrders").'
    '; - print ''; + print ''; print "\n"; $var=True; @@ -315,7 +315,7 @@ if ($resql) { print '
    '.$langs->trans("UserWithApproveOrderGrant").'
    '.$langs->trans("UserWithApproveOrderGrant").'
    '; print ''; - print ''; + print ''; $num = $db->num_rows($resql); if ($num) @@ -385,7 +385,7 @@ $num = $db->num_rows($resql); print '
    '.$langs->trans("LastModifiedOrders",$max).'
    '.$langs->trans("LastModifiedOrders",$max).'
    '; print ''; -print ''; +print ''; if ($num) { diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index e8038497e2c..b0e2bf58d79 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -121,7 +121,7 @@ if (! empty($conf->holiday->enabled)) $user_id = $user->id; print '
    '.$langs->trans("OrdersToProcess").' ('.$num.')
    '.$langs->trans("OrdersToProcess").' ('.$num.')
    '; - print ''; + print ''; print ""; print '
    '.$langs->trans("Holidays").'
    '.$langs->trans("Holidays").'
    '; @@ -179,11 +179,11 @@ if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) print ''; print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print ''; if ($num) { @@ -250,10 +250,10 @@ if (! empty($conf->deplacement->enabled) && $user->rights->deplacement->lire) print '
    '.$langs->trans("BoxTitleLastLeaveRequests",min($max,$num)).''.$langs->trans("from").''.$langs->trans("to").''.$langs->trans("DateModificationShort").' '.$langs->trans("BoxTitleLastLeaveRequests",min($max,$num)).''.$langs->trans("from").''.$langs->trans("to").''.$langs->trans("DateModificationShort").' 
    '; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print ''; if ($num) { @@ -317,10 +317,10 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire print '
    '.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).''.$langs->trans("FeesKilometersOrAmout").''.$langs->trans("DateModificationShort").' '.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).''.$langs->trans("FeesKilometersOrAmout").''.$langs->trans("DateModificationShort").' 
    '; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print ''; if ($num) { diff --git a/htdocs/index.php b/htdocs/index.php index eab8844b960..4ac80fbf57c 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -535,7 +535,7 @@ $boxwork.=''."\n"; if ($showweather) { $var=!$var; - $boxwork.=''; + $boxwork.=''; $boxwork.=''; - $boxwork.= ''; - $boxwork.= ''; + $boxwork .= ''; + $boxwork .= ''; - $boxwork.=''; + $boxwork .= ''; + $boxwork .= ''; + $boxwork .= $board->nbtodolate; + $boxwork .= ''; + $boxwork .= ''; + $boxwork .=''; + $boxwork .=''; /*print '';*/ @@ -589,8 +592,8 @@ foreach($valid_dashboardlines as $board) $boxwork.=''; $showweather=0; }*/ - $boxwork.=''; - $boxwork.="\n"; + $boxwork .=''; + $boxwork .="\n"; } $boxwork.='
    '.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).''.$langs->trans("TotalTTC").''.$langs->trans("DateModificationShort").' '.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).''.$langs->trans("TotalTTC").''.$langs->trans("DateModificationShort").' 
    '; //$boxwork.=$langs->trans("Meteo"); //$boxwork.=''; @@ -556,23 +556,26 @@ if ($showweather) // Show dashboard +$nbworkboardempty=0; foreach($valid_dashboardlines as $board) { + if (empty($boad->nbtodo)) $nbworkboardempty++; + $var=!$var; - $boxwork.= '
    '.$board->img.'   '.$board->label.''.$board->nbtodo.''; + $boxwork .= '
    '.$board->img.'   '.$board->label.''.$board->nbtodo.''; $textlate = $langs->trans("NActionsLate",$board->nbtodolate); $textlate.= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')'; - $boxwork.= ''; - $boxwork.= ''; - $boxwork.= $board->nbtodolate; - $boxwork.= ''; - $boxwork.= ''; - $boxwork.=''; - if ($board->nbtodolate > 0) $boxwork.=img_picto($textlate, "warning", 'class="valignmiddle"').' '; - $boxwork.=''; + if ($board->nbtodolate > 0) $boxwork .=img_picto($textlate, "warning", 'class="valignmiddle"').' '; + $boxwork .=''; print ' (>'.ceil($board->warning_delay).' '.$langs->trans("days").')'; print '
    '; // End table array of working board diff --git a/htdocs/product/index.php b/htdocs/product/index.php index 84991a76db2..355e0d2757f 100644 --- a/htdocs/product/index.php +++ b/htdocs/product/index.php @@ -127,7 +127,7 @@ while ($objp = $db->fetch_object($result)) } print ''; -print ''; +print ''; if (! empty($conf->product->enabled)) { $statProducts = ""; @@ -268,7 +268,7 @@ if ($result) $colnb=5; if (empty($conf->global->PRODUIT_MULTIPRICES)) $colnb++; - print ''; + print ''; $var=True; diff --git a/htdocs/product/stock/index.php b/htdocs/product/stock/index.php index 7349b48d1c9..b2ecaf3afd1 100644 --- a/htdocs/product/stock/index.php +++ b/htdocs/product/stock/index.php @@ -77,7 +77,7 @@ if ($result) $i = 0; print '
    '.$langs->trans("Statistics").'
    '.$langs->trans("Statistics").'
    '.$transRecordedType.'
    '.$transRecordedType.'
    '; - print ''; + print ''; if ($num) { @@ -132,16 +132,16 @@ if ($resql) print '
    '.$langs->trans("Warehouses").'
    '.$langs->trans("Warehouses").'
    '; print ""; - print ''; - print ''; + print ''; + print ''; if (! empty($conf->productbatch->enabled)) { - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; } - print ''; - print ''; + print ''; + print ''; print "\n"; $var=True; diff --git a/htdocs/projet/graph_opportunities.inc.php b/htdocs/projet/graph_opportunities.inc.php index 0480196ccf9..668e96d2958 100644 --- a/htdocs/projet/graph_opportunities.inc.php +++ b/htdocs/projet/graph_opportunities.inc.php @@ -50,7 +50,7 @@ if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) $ponderated_opp_amount = $ponderated_opp_amount / 100; print '
    '.$langs->trans("LastMovements",min($num,$max)).''.$langs->trans("Product").''.$langs->trans("LastMovements",min($num,$max)).''.$langs->trans("Product").''.$langs->trans("Batch").''.$langs->trans("EatByDate").''.$langs->trans("SellByDate").''.$langs->trans("Batch").''.$langs->trans("EatByDate").''.$langs->trans("SellByDate").''.$langs->trans("Warehouse").''.$langs->trans("FullList").''.$langs->trans("Warehouse").''.$langs->trans("FullList").'
    '; - print ''."\n"; + print ''."\n"; $var=true; $listofstatus=array_keys($listofoppstatus); foreach ($listofstatus as $status) diff --git a/htdocs/supplier_proposal/index.php b/htdocs/supplier_proposal/index.php index eec34a02987..f6ca9aaee45 100644 --- a/htdocs/supplier_proposal/index.php +++ b/htdocs/supplier_proposal/index.php @@ -117,7 +117,7 @@ if ($resql) $db->free($resql); print '
    '.$langs->trans("Statistics").' - '.$langs->trans("OpportunitiesStatusForOpenedProjects").'
    '.$langs->trans("Statistics").' - '.$langs->trans("OpportunitiesStatusForOpenedProjects").'
    '; - print ''."\n"; + print ''."\n"; $var=true; $listofstatus=array(0,1,2,3,4); foreach ($listofstatus as $status) @@ -169,7 +169,7 @@ if (! empty($conf->supplier_proposal->enabled)) { print '
    '.$langs->trans("Statistics").' - '.$langs->trans("CommRequests").'
    '.$langs->trans("Statistics").' - '.$langs->trans("CommRequests").'
    '; print ''; - print ''; + print ''; $langs->load("supplier_proposal"); $num = $db->num_rows($resql); if ($num) @@ -227,7 +227,7 @@ if ($resql) { print '
    '.$langs->trans("DraftRequests").'
    '.$langs->trans("DraftRequests").'
    '; print ''; - print ''; + print ''; $num = $db->num_rows($resql); if ($num) @@ -311,7 +311,7 @@ if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_propos $var=true; print '
    '.$langs->trans("LastModifiedRequests",$max).'
    '.$langs->trans("LastModifiedRequests",$max).'
    '; - print ''; + print ''; $nbofloop=min($num, (empty($conf->global->MAIN_MAXLIST_OVERLOAD)?500:$conf->global->MAIN_MAXLIST_OVERLOAD)); while ($i < $nbofloop) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a5ae098c545..8a4e636cee0 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2368,23 +2368,23 @@ div.liste_titre_bydiv .divsearchfield { } tr.box_titre .nobordernopadding td { - padding: 0px ! important; + padding: 0 ! important; } table.nobordernopadding { border-collapse: collapse !important; - border: 0px; + border: 0; } table.nobordernopadding tr { - border: 0px !important; - padding: 0px 0px !important; + border: 0 !important; + padding: 0 0 !important; } table.nobordernopadding tr td { - border: 0px; + border: 0 !important; padding: 0 3px 0 0; } table.border tr td table.nobordernopadding tr td { - padding-top: 0px; - padding-bottom: 0px; + padding-top: 0; + padding-bottom: 0; } td.borderright { border: none; /* to erase value for table.nobordernopadding td */ @@ -2559,72 +2559,51 @@ div.pagination li.paginationafterarrows { margin-top: 9px; } -/* Prepare to remove class pair - impair -.noborder > tbody > tr:nth-child(even) td { - background: linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); - font-family: ; - border: 0px; - margin-bottom: 1px; - color: #202020; - min-height: 18px; -} -.noborder > tbody > tr:nth-child(odd) td { - background: linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); - font-family: ; - border: 0px; - margin-bottom: 1px; - color: #202020; -} -*/ /* Set the color for hover lines */ -.odd:hover, .impair:hover, .even:hover, .pair:hover, .even:hover, .pair:hover, table.dataTable tr.even:hover, table.dataTable tr.odd:hover, .box_pair:hover, .box_impair:hover +.oddeven:hover, .odd:hover, .impair:hover, .even:hover, .pair:hover, .even:hover, .pair:hover, table.dataTable tr.even:hover, table.dataTable tr.odd:hover { background: rgb() !important; } -.odd, .impair, .nohover .odd:hover, .nohover .impair:hover, tr.odd td.nohover, tr.impair td.nohover, tr.box_pair td.nohover, tr.box_impair td.nohover +.oddeven, .odd, .impair, .nohover .odd:hover, .nohover .impair:hover, tr.odd td.nohover, tr.impair td.nohover { font-family: ; margin-bottom: 1px; color: #202020; - min-height: 18px; /* seems to not be used */ - +} +.odd, .impair, .nohover .odd:hover, .nohover .impair:hover, tr.odd td.nohover, tr.impair td.nohover +{ background: #; } #GanttChartDIV { background: #; } -.even, .pair, .nohover .even:hover, .nohover .pair:hover, tr.even td.nohover, tr.pair td.nohover { +.oddeven, .even, .pair, .nohover .even:hover, .nohover .pair:hover, tr.even td.nohover, tr.pair td.nohover { font-family: ; margin-bottom: 1px; color: #202020; - +} +.even, .pair, .nohover .even:hover, .nohover .pair:hover, tr.even td.nohover, tr.pair td.nohover { background-color: #; } -table.dataTable tr.odd { +table.dataTable tr.odd, table.dataTable tr.oddeven { background-color: # !important; } /* For no hover style */ -table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td { +td.oddeven, table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td { background-color: # !important; + background: # !important; } tr.nohoverpair td { background-color: # !important; + background: # !important; } table.dataTable td { @@ -2699,6 +2678,10 @@ tr.liste_titre th, tr.liste_titre td, th.liste_titre { border-bottom: 1px solid #; } +/* TODO Once title line is moved under title search, make border bottom of all th black and force to whit when it's first tr */ +tr:first-child th.liste_titre { + border-bottom: 1px solid #FFF ! important; +} tr.liste_titre th, th.liste_titre, tr.liste_titre td, td.liste_titre, form.liste_titre div { font-family: ; @@ -2723,10 +2706,11 @@ tr.liste_titre_topborder td { .liste_titre td a.notasortlink:hover { background: transparent; } -tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ +tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ border-bottom: 1px solid rgb(); } + tr.liste_titre_sel th, th.liste_titre_sel, tr.liste_titre_sel td, td.liste_titre_sel, form.liste_titre_sel div { font-family: ; @@ -2796,6 +2780,32 @@ div.tabBar .noborder { } +/* Prepare to remove class pair - impair */ + +.noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) { + background: linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); +} +.noborder > tbody > tr:nth-child(even):not(:last-child) td:not(.liste_titre), .liste > tbody > tr:nth-child(even):not(:last-child) td:not(.liste_titre) { + border-bottom: 1px solid #ddd; +} + +.noborder > tbody > tr:nth-child(odd):not(.liste_titre), .liste > tbody > tr:nth-child(odd):not(.liste_titre) { + background: linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); +} +.noborder > tbody > tr:nth-child(odd):not(:last-child) td:not(.liste_titre), .liste > tbody > tr:nth-child(odd):not(:last-child) td:not(.liste_titre) { + border-bottom: 1px solid #ddd; +} + + + /* * Boxes */ @@ -2884,29 +2894,6 @@ tr.box_titre td.boxclose { width: 30px; } -tr.box_impair { - background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: linear-gradient(bottom, rgb() 85%, rgb() 100%); - - font-family: ; -} - - -tr.box_pair { - font-family: ; - - background-color: #f9f9f9; -} - -tr.box_pair td, tr.box_impair td { - /* padding: 4px; */ -} -tr.box_pair:not(:last-child) td, tr.box_impair:not(:last-child) td { - border-bottom: 1px solid #ddd; -} .noborderbottom { border-bottom: none !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 625251a6bb0..6fad30ed46b 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2290,19 +2290,19 @@ div.liste_titre_bydiv .divsearchfield { table.nobordernopadding { border-collapse: collapse !important; - border: 0px; + border: 0; } table.nobordernopadding tr { - border: 0px !important; - padding: 0px 0px !important; + border: 0 !important; + padding: 0 0 !important; } table.nobordernopadding tr td { - border: 0px; + border: 0 !important; padding: 0 3px 0 0; } table.border tr td table.nobordernopadding tr td { - padding-top: 0px; - padding-bottom: 0px; + padding-top: 0; + padding-bottom: 0; } td.borderright { border: none; /* to erase value for table.nobordernopadding td */ @@ -2475,44 +2475,48 @@ div.pagination li.paginationafterarrows { */ /* Set the color for hover lines */ -.odd:hover, .impair:hover, .even:hover, .pair:hover, .even:hover, .pair:hover, table.dataTable tr.even:hover, table.dataTable tr.odd:hover, .box_pair:hover, .box_impair:hover +.oddeven:hover, .odd:hover, .impair:hover, .even:hover, .pair:hover, .even:hover, .pair:hover, table.dataTable tr.even:hover, table.dataTable tr.odd:hover { background: rgb() !important; } -.odd, .impair, .nohover .odd:hover, .nohover .impair:hover, tr.odd td.nohover, tr.impair td.nohover, tr.box_pair td.nohover, tr.box_impair td.nohover +.oddeven, .odd, .impair, .nohover .odd:hover, .nohover .impair:hover, tr.odd td.nohover, tr.impair td.nohover { font-family: ; border: 0px; margin-bottom: 1px; color: #202020; - min-height: 18px; /* seems to not be used */ - +} +.odd, .impair, .nohover .odd:hover, .nohover .impair:hover, tr.odd td.nohover, tr.impair td.nohover +{ background: #; } #GanttChartDIV { background: #; } -.even, .pair, .nohover .even:hover, .nohover .pair:hover, tr.even td.nohover, tr.pair td.nohover { +.oddeven, .even, .pair, .nohover .even:hover, .nohover .pair:hover, tr.even td.nohover, tr.pair td.nohover { font-family: ; margin-bottom: 1px; color: #202020; - +} +.even, .pair, .nohover .even:hover, .nohover .pair:hover, tr.even td.nohover, tr.pair td.nohover { background-color: #; } -table.dataTable tr.odd { +table.dataTable tr.odd, table.dataTable tr.oddeven { background-color: # !important; } /* For no hover style */ -table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td { +td.oddeven, table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td { background-color: # !important; + background: # !important; } tr.nohoverpair td { background-color: # !important; + background: # !important; } table.dataTable td { @@ -2592,6 +2596,10 @@ tr.liste_titre th, tr.liste_titre td, th.liste_titre, form.liste_titre div, div. { border-bottom: 1px solid #; } +/* TODO Once title line is moved under title search, make border bottom of all th black and force to whit when it's first tr */ +tr:first-child th.liste_titre { + border-bottom: 1px solid #FFF ! important; +} tr.liste_titre th, th.liste_titre, tr.liste_titre td, td.liste_titre, form.liste_titre div, div.liste_titre { font-family: ; @@ -2616,7 +2624,7 @@ tr.liste_titre_topborder td { .liste_titre td a.notasortlink:hover { background: transparent; } -tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel { /* For last line of table headers only */ +tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ border-bottom: 1px solid rgb(); } @@ -2694,6 +2702,31 @@ div .tdtop { } +/* Prepare to remove class pair - impair */ + +.noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) { + background: linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); +} +.noborder > tbody > tr:nth-child(even):not(:last-child) td:not(.liste_titre), .liste > tbody > tr:nth-child(even):not(:last-child) td:not(.liste_titre) { + border-bottom: 1px solid #ddd; +} + +.noborder > tbody > tr:nth-child(odd):not(.liste_titre), .liste > tbody > tr:nth-child(odd):not(.liste_titre) { + background: linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); +} +.noborder > tbody > tr:nth-child(odd):not(:last-child) td:not(.liste_titre), .liste > tbody > tr:nth-child(odd):not(:last-child) td:not(.liste_titre) { + border-bottom: 1px solid #ddd; +} + + /* * Boxes */ @@ -2784,27 +2817,6 @@ tr.box_titre td.boxclose { width: 30px; } -tr.box_impair { - background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: linear-gradient(bottom, rgb() 85%, rgb() 100%); - font-family: ; -} - -tr.box_pair { - font-family: ; - - background-color: #f9f9f9; -} - -tr.box_pair td, tr.box_impair td { - padding: 4px; -} -tr.box_pair:not(:last-child) td, tr.box_impair:not(:last-child) td { - border-bottom: 1px solid #eee; -} .noborderbottom { border-bottom: none !important; } From 76e55fcdb1ec51c7d12623960aa91aa953b15802 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Wed, 8 Mar 2017 09:06:38 +0100 Subject: [PATCH 024/410] NEW :hidden Easter egg to display commitstrip strip on login page --- htdocs/core/tpl/login.tpl.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 3772b44c9fc..ba501e802dd 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -239,6 +239,18 @@ if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file global->MAIN_EASTER_EGG_COMMITSTRIP)) { + if (substr($langs->defaultlang,0,2)=='fr') { + $xml = simplexml_load_file("http://www.commitstrip.com/fr/feed/"); + } else { + $xml = simplexml_load_file("http://www.commitstrip.com/en/feed/"); + } + + $little = $xml->channel->item[0]->children('content',true); + + print $little->encoded; +} + ?> Date: Wed, 8 Mar 2017 11:34:21 +0100 Subject: [PATCH 025/410] NEW odt usergroup --- htdocs/admin/usergroup.php | 316 ++++++++++++++++++ .../core/class/commondocgenerator.class.php | 16 +- htdocs/core/class/conf.class.php | 5 + htdocs/core/class/html.formfile.class.php | 6 +- htdocs/core/lib/usergroups.lib.php | 5 + .../core/modules/user/modules_user.class.php | 28 -- .../usergroup/modules_usergroup.class.php | 62 ++++ htdocs/install/mysql/tables/llx_user.sql | 1 + htdocs/install/mysql/tables/llx_usergroup.sql | 5 +- htdocs/user/class/usergroup.class.php | 34 ++ htdocs/user/group/card.php | 40 ++- 11 files changed, 475 insertions(+), 43 deletions(-) create mode 100644 htdocs/admin/usergroup.php create mode 100644 htdocs/core/modules/usergroup/modules_usergroup.class.php diff --git a/htdocs/admin/usergroup.php b/htdocs/admin/usergroup.php new file mode 100644 index 00000000000..72365726d25 --- /dev/null +++ b/htdocs/admin/usergroup.php @@ -0,0 +1,316 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2009 Laurent Destailleur + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2015 Juanjo Menent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/usergroup.php + * \ingroup core + * \brief Page to setup usergroup module + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + +$langs->load("admin"); +$langs->load("members"); +$langs->load("users"); +if (! $user->admin) accessforbidden(); + +$extrafields = new ExtraFields($db); + +$action = GETPOST('action','alpha'); +$value = GETPOST('value','alpha'); +$type='group'; + +/* + * Action + */ + +// Activate a model + +// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) +if ($action == 'setModuleOptions') +{ + $post_size=count($_POST); + + $db->begin(); + + for($i=0;$i < $post_size;$i++) + { + if (array_key_exists('param'.$i,$_POST)) + { + $param=GETPOST("param".$i,'alpha'); + $value=GETPOST("value".$i,'alpha'); + if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + } + } + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} +elseif ($action == 'set_default') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); + $res = true; +} + +elseif ($action == 'del_default') +{ + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + if ($conf->global->USERGROUP_ADDON_PDF_ODT == "$value") dolibarr_del_const($db, 'USERGROUP_ADDON_PDF_ODT',$conf->entity); + } + $res = true; +} + +// Set default model +elseif ($action == 'setdoc') +{ + if (dolibarr_set_const($db, "USERGROUP_ADDON_PDF_ODT",$value,'chaine',0,'',$conf->entity)) + { + // La constante qui a ete lue en avant du nouveau set + // on passe donc par une variable pour avoir un affichage coherent + $conf->global->USERGROUP_ADDON_PDF_ODT = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } + $res = true; +} +elseif (preg_match('/set_(.*)/',$action,$reg)) +{ + $code=$reg[1]; + if (dolibarr_set_const($db, $code, 1, 'chaine', 0, '', $conf->entity) > 0) + { + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + dol_print_error($db); + } +} + +elseif (preg_match('/del_(.*)/',$action,$reg)) +{ + $code=$reg[1]; + if (dolibarr_del_const($db, $code, $conf->entity) > 0) + { + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + dol_print_error($db); + } +} +/* + * View + */ + +$help_url='EN:Module_Users|FR:Module_Utilisateurs|ES:Módulo_Usuarios'; +llxHeader('',$langs->trans("UsersSetup"),$help_url); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("UsersSetup"),$linkback,'title_setup'); + + +$head=user_admin_prepare_head(); + +dol_fiche_head($head,'usergroupcard', $langs->trans("MenuUsersAndGroups"), 0, 'user'); + + +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + +$form=new Form($db); + +// Defini tableau def des modeles +$def = array(); +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + +print '
    '.$langs->trans("RequestsOpened").' '.$num.'
    '.$langs->trans("RequestsOpened").' '.$num.'
    '; +print ''; +print ''; +print ''; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +$var=true; +foreach ($dirmodels as $reldir) +{ + foreach (array('','/doc') as $valdir) + { + $dir = dol_buildpath($reldir."core/modules/usergroup".$valdir); + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var = !$var; + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } + else + { + print '"; + } + + // Defaut + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
    '.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip.='
    '.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip.='

    '.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
    '.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
    '.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
    '.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
    '.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + $htmltooltip.='
    '.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } +} + +print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
    '; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print "'; + if ($conf->global->USERGROUP_ADDON_PDF == $name) + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'contract').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
    '; +print "
    "; + +dol_fiche_end(); + +llxFooter(); +$db->close(); diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 1d4cb508fb9..9c3bc5b131e 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -332,19 +332,17 @@ abstract class CommonDocGenerator $array_other = array(); if(!empty($object)) { foreach($object as $key => $value) { - if(!is_array($value) && !is_object($value)) { - $array_other['object_'.$key] = $value; - } - if(is_array($value) && $recursive){ - if(!empty($value)) { - foreach($value as $key2 => $val) { - $array_other[$key][$key2] = $this->get_substitutionarray_each_var_object($val,$outputlangs,false); - } + if(!empty($value)) { + if(!is_array($value) && !is_object($value)) { + $array_other['object_'.$key] = $value; + } + if(is_array($value) && $recursive){ + $array_other['object_'.$key] = $this->get_substitutionarray_each_var_object($value,$outputlangs,false); } } } } - return $array_other; + return $array_other; } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 0bd28092bff..8a5172c182b 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -106,6 +106,7 @@ class Conf $this->propal = new stdClass(); $this->facture = new stdClass(); $this->contrat = new stdClass(); + $this->usergroup = new stdClass(); $this->adherent = new stdClass(); $this->bank = new stdClass(); $this->notification = new stdClass(); @@ -309,6 +310,10 @@ class Conf // For backward compatibility $this->user->dir_output=$rootforuser."/users"; $this->user->dir_temp=$rootforuser."/users/temp"; + + // UserGroup + $this->usergroup->dir_output=$rootforuser."/usergroups"; + $this->usergroup->dir_temp=$rootforuser."/usergroups/temp"; // For propal storage $this->propal->dir_output=$rootfordata."/propale"; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index f60faa84426..2dbbd9545db 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -420,13 +420,13 @@ class FormFile $modellist=ModelePDFUser::liste_modeles($this->db); } } - elseif ($modulepart == 'group') + elseif ($modulepart == 'usergroup') { if (is_array($genallowed)) $modellist=$genallowed; else { - include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_group.php'; - $modellist=ModelePDFProduct::liste_modeles($this->db); + include_once DOL_DOCUMENT_ROOT.'/core/modules/usergroup/modules_usergroup.class.php'; + $modellist=ModelePDFUserGroup::liste_modeles($this->db); } } elseif ($modulepart == 'project_task') diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index ed95bdc4023..117f7a1e86e 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -207,6 +207,11 @@ function user_admin_prepare_head() $head[$h][2] = 'card'; $h++; + $head[$h][0] = DOL_URL_ROOT.'/admin/usergroup.php'; + $head[$h][1] = $langs->trans("Group"); + $head[$h][2] = 'usergroupcard'; + $h++; + $head[$h][0] = DOL_URL_ROOT.'/user/admin/user_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFields"); $head[$h][2] = 'attributes'; diff --git a/htdocs/core/modules/user/modules_user.class.php b/htdocs/core/modules/user/modules_user.class.php index 43660da1adb..3e94ece9372 100644 --- a/htdocs/core/modules/user/modules_user.class.php +++ b/htdocs/core/modules/user/modules_user.class.php @@ -55,34 +55,6 @@ abstract class ModelePDFUser extends CommonDocGenerator $type='user'; $liste=array(); - include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $liste=getListOfModels($db,$type,$maxfilenamelength); - return $liste; - } -} - -/** - * Parent class to manage intervention document templates - */ -abstract class ModelePDFUserGroup extends CommonDocGenerator -{ - var $error=''; - - - /** - * Return list of active generation modules - * - * @param DoliDB $db Database handler - * @param integer $maxfilenamelength Max length of value to show - * @return array List of templates - */ - static function liste_modeles($db,$maxfilenamelength=0) - { - global $conf; - - $type='usergroup'; - $liste=array(); - include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $liste=getListOfModels($db,$type,$maxfilenamelength); return $liste; diff --git a/htdocs/core/modules/usergroup/modules_usergroup.class.php b/htdocs/core/modules/usergroup/modules_usergroup.class.php new file mode 100644 index 00000000000..f7d4778efe1 --- /dev/null +++ b/htdocs/core/modules/usergroup/modules_usergroup.class.php @@ -0,0 +1,62 @@ + + * Copyright (C) 2004-2010 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + + +/** + * \class ModeleProductCode + * \brief Parent class for product code generators + */ + +/** + * \file htdocs/core/modules/contract/modules_contract.php + * \ingroup contract + * \brief File with parent class for generating contracts to PDF and File of class to manage contract numbering + */ + + require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; + +/** + * Parent class to manage intervention document templates + */ +abstract class ModelePDFUserGroup extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='usergroup'; + $liste=array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + return $liste; + } +} \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index e334ae1f802..5530622ac1d 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -62,6 +62,7 @@ create table llx_user fk_member integer, fk_user integer, -- Hierarchic parent note text DEFAULT NULL, + model_pdf varchar(255) DEFAULT NULL, datelastlogin datetime, datepreviouslogin datetime, egroupware_id integer, diff --git a/htdocs/install/mysql/tables/llx_usergroup.sql b/htdocs/install/mysql/tables/llx_usergroup.sql index 156c6eda364..9afe72f3b24 100644 --- a/htdocs/install/mysql/tables/llx_usergroup.sql +++ b/htdocs/install/mysql/tables/llx_usergroup.sql @@ -25,7 +25,8 @@ create table llx_usergroup entity integer DEFAULT 1 NOT NULL, -- multi company id datec datetime, tms timestamp, - note text + note text, + model_pdf varchar(255) DEFAULT NULL, )ENGINE=innodb; -- @@ -35,4 +36,4 @@ create table llx_usergroup -- 1 : first company group -- 2 : second company group -- 3 : etc... --- \ No newline at end of file +-- diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 50237b0ef61..96f2d3aa7bc 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -818,5 +818,39 @@ class UserGroup extends CommonObject $this->datem=time(); $this->members=array($user->id); // Members of this group is just me } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force model to use ('' to not force) + * @param Translate $outputlangs Object langs to use for output + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) + { + global $conf,$user,$langs; + + $langs->load("user"); + + // Positionne le modele sur le nom du modele a utiliser + if (! dol_strlen($modele)) + { + if (! empty($conf->global->USERGROUP_ADDON_PDF)) + { + $modele = $conf->global->USERGROUP_ADDON_PDF; + } + else + { + $modele = 'grass'; + } + } + + $modelpath = "core/modules/usergroup/doc/"; + + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + } } diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 716db97b911..cc496152f4f 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -28,6 +28,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; if(! empty($conf->multicompany->enabled)) dol_include_once('/multicompany/class/actions_multicompany.class.php'); // Defini si peux lire/modifier utilisateurs et permisssions @@ -220,6 +221,8 @@ llxHeader('',$langs->trans("GroupCard")); $form = new Form($db); $fuserstatic = new User($db); +$form = new Form($db); +$formfile = new FormFile($db); if ($action == 'create') { @@ -495,6 +498,42 @@ else } print "
    "; print "
    "; + + // Actions to build doc + $upload_dir = $conf->usergroup->dir_output; + $permissioncreate=$user->rights->user->user->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + + /* + * Documents generes + */ + $filename = dol_sanitizeFileName($object->ref); + $filedir = $conf->usergroup->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->user->user->creer; + $delallowed = $user->rights->user->user->supprimer; + + $var = true; + + $somethingshown = $formfile->show_documents('usergroup', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + + // Linked object block + $somethingshown = $form->showLinkedObjectBlock($object); + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object); + if ($linktoelem) print '
    '.$linktoelem; + + + print '
    '; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'usergroup', $socid); + + + print '
    '; } /* @@ -551,7 +590,6 @@ else print ''; } - } } From b520c0ab6b910b76796d177cca7a998a3492d577 Mon Sep 17 00:00:00 2001 From: Thomas Raschbacher Date: Thu, 9 Mar 2017 08:12:45 +0100 Subject: [PATCH 026/410] fix typo in Issue tracker URL --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 690b00211f7..02d21453a3a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ Bug reports and feature requests *Note*: Issues are not a support forum. If you need help using the software, please use [the forums](http://www.dolibarr.org/forum). -Issues are managed on [GitHub](https://github.com/Dolibarr/dolibarr/Issues). +Issues are managed on [GitHub](https://github.com/Dolibarr/dolibarr/issues). 1. Please [use the search engine](https://help.github.com/articles/searching-issues) to check if nobody's already reported your problem. 2. [Create an issue](https://help.github.com/articles/creating-an-issue). Choose an appropriate title. Prepend appropriately with Bug or Feature Request. From d241adc201292f87cbb4ebbdff953b068f125f66 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Mar 2017 13:22:43 +0100 Subject: [PATCH 027/410] NEW Use autocompletion on the "Add widget list". --- htdocs/core/ajax/box.php | 7 ++++++- htdocs/core/class/html.formother.class.php | 18 +++--------------- htdocs/core/class/infobox.class.php | 2 +- htdocs/index.php | 5 ++--- htdocs/langs/en_US/boxes.lang | 1 + htdocs/theme/eldy/style.css.php | 17 +++++++++++++++++ htdocs/theme/md/style.css.php | 17 +++++++++++++++++ 7 files changed, 47 insertions(+), 20 deletions(-) diff --git a/htdocs/core/ajax/box.php b/htdocs/core/ajax/box.php index 63f96a0c513..be4d9231c5f 100644 --- a/htdocs/core/ajax/box.php +++ b/htdocs/core/ajax/box.php @@ -26,7 +26,7 @@ if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK','1'); require '../../main.inc.php'; @@ -70,5 +70,10 @@ if ($boxorder && $zone != '' && $userid > 0) dol_syslog("AjaxBox boxorder=".$boxorder." zone=".$zone." userid=".$userid, LOG_DEBUG); $result=InfoBox::saveboxorder($db,$zone,$boxorder,$userid); + if ($result > 0) + { + $langs->load("boxes"); + setEventMessages($langs->trans("BoxAdded"), null); + } } diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 9cb402cfc89..bcad9dbac44 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -978,7 +978,7 @@ class FormOther * * @param User $user Object User * @param String $areacode Code of area for pages (0=value for Home page) - * @return array array('selectboxlist'=>, 'boxactivated'=>, 'boxlist'=>) + * @return array array('selectboxlist'=>, 'boxactivated'=>, 'boxlista'=>, 'boxlistb'=>) */ static function getBoxesArea($user,$areacode) { @@ -1027,10 +1027,10 @@ class FormOther $selectboxlist.=''; $selectboxlist.=''; $selectboxlist.=''; - $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, '', $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, ' disabled hidden selected'); + $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected'); if (empty($conf->use_javascript_ajax)) $selectboxlist.=' '; $selectboxlist.=''; - //$selectboxlist.=ajax_combobox("boxcombo"); + $selectboxlist.=ajax_combobox("boxcombo"); } // Javascript code for dynamic actions @@ -1114,11 +1114,6 @@ class FormOther $emptybox=new ModeleBoxes($db); - //$boxlist.=''; - //$boxlist.='"; - //$boxlist.= "
    '."\n"; - - //$boxlist.='
    '; - $boxlista.="\n\n"; $boxlista.='
    '."\n"; @@ -1152,8 +1147,6 @@ class FormOther $boxlista.= "
    \n"; $boxlista.= "\n"; - //$boxlist.= '
    '; - $boxlistb.= "\n\n"; $boxlistb.= '\n"; $boxlistb.= "\n"; - //$boxlist.= '
    '; - //$boxlist.= "\n"; - - //$boxlist.= "
    "; } return array('selectboxlist'=>count($boxactivated)?$selectboxlist:'', 'boxactivated'=>$boxactivated, 'boxlista'=>$boxlista, 'boxlistb'=>$boxlistb); diff --git a/htdocs/core/class/infobox.class.php b/htdocs/core/class/infobox.class.php index cd06eb587b7..419f31dca4d 100644 --- a/htdocs/core/class/infobox.class.php +++ b/htdocs/core/class/infobox.class.php @@ -183,7 +183,7 @@ class InfoBox * @param string $zone Name of area (0 for Homepage, ...) * @param string $boxorder List of boxes with correct order 'A:123,456,...-B:789,321...' * @param int $userid Id of user - * @return int <0 if KO, >= 0 if OK + * @return int <0 if KO, 0=Nothing done, > 0 if OK */ static function saveboxorder($db, $zone,$boxorder,$userid=0) { diff --git a/htdocs/index.php b/htdocs/index.php index 4ac80fbf57c..0fec7ea11d5 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -61,11 +61,10 @@ if (GETPOST('addbox')) // Add box (when submit is done from a form when ajax dis $boxorder.=GETPOST('boxcombo'); $result=InfoBox::saveboxorder($db,$zone,$boxorder,$userid); + if ($result > 0) setEventMessages($langs->trans("BoxAdded"), null); } - - /* * View */ @@ -79,7 +78,7 @@ if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $title=$langs->trans("HomeAr llxHeader('',$title); -$resultboxes=FormOther::getBoxesArea($user,"0"); +$resultboxes=FormOther::getBoxesArea($user,"0"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb) print load_fiche_titre($langs->trans("HomeArea"),$resultboxes['selectboxlist'],'title_home'); diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index 0e6c5019cac..9eb795ea7d1 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -83,3 +83,4 @@ ForCustomersOrders=Customers orders ForProposals=Proposals LastXMonthRolling=The latest %s month rolling ChooseBoxToAdd=Add widget to your dashboard +BoxAdded=Widget was added in your dashboard \ No newline at end of file diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 8a4e636cee0..090bb3f887c 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -4023,6 +4023,23 @@ a span.select2-chosen .select2-container-multi .select2-choices .select2-search-choice { margin-bottom: 3px; } + +/* Special case for the select2 add widget */ +#addbox .select2-container .select2-choice > .select2-chosen { + text-align: left; + opacity: 0.2; +} +/* Style used before the select2 js is executed on boxcombo */ +#boxcombo.boxcombo { + text-align: left; + opacity: 0.2; + border-bottom: 1px solid #000; + height: 26px; + line-height: 24px; + padding: 0 0 5px 5px; + vertical-align: top; +} + /* To emulate select 2 style */ .select2-container-multi-dolibarr .select2-choices-dolibarr .select2-search-choice-dolibarr { padding: 2px 5px 1px 5px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6fad30ed46b..96cb8002719 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3970,6 +3970,23 @@ a span.select2-chosen .select2-container-multi .select2-choices .select2-search-choice { margin-bottom: 3px; } + +/* Special case for the select2 add widget */ +#addbox .select2-container .select2-choice > .select2-chosen { + text-align: left; + opacity: 0.2; +} +/* Style used before the select2 js is executed on boxcombo */ +#boxcombo.boxcombo { + text-align: left; + opacity: 0.2; + border-bottom: 1px solid #000; + height: 26px; + line-height: 24px; + padding: 0 0 5px 5px; + vertical-align: top; +} + /* To emulate select 2 style */ .select2-container-multi-dolibarr .select2-choices-dolibarr .select2-search-choice-dolibarr { padding: 2px 5px 1px 5px; From c962daabacac1c832045663f6284b7f9e6c476b6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Mar 2017 15:16:16 +0100 Subject: [PATCH 028/410] NEW add property to show warnings when activating modules --- htdocs/admin/modules.php | 55 ++++++++++++++++--- htdocs/core/lib/admin.lib.php | 17 ++++-- htdocs/core/modules/DolibarrModules.class.php | 27 +++++++-- htdocs/core/modules/modCron.class.php | 2 +- htdocs/core/modules/modFacture.class.php | 9 ++- htdocs/core/modules/modSkype.class.php | 2 +- htdocs/core/modules/modWebsites.class.php | 2 +- htdocs/langs/en_US/admin.lang | 1 + 8 files changed, 90 insertions(+), 25 deletions(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 596aefa803e..6d9df62e979 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -235,6 +235,8 @@ $help_url='EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones' llxHeader('',$langs->trans("Setup"),$help_url); $arrayofnatures=array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers")); +$arrayofwarnings=array(); // Array of warning each module want to show when activated +$arrayofwarningsext=array(); // Array of warning each module want to show when we activate an external module // Search modules dirs $modulesdir = dolGetModulesDirs(); @@ -266,7 +268,7 @@ foreach ($modulesdir as $dir) if ($modName) { - if (! empty($modNameLoaded[$modName])) + if (! empty($modNameLoaded[$modName])) // In cache of already loaded modules ? { $mesg="Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.
    "; setEventMessages($mesg, null, 'warnings'); @@ -297,7 +299,7 @@ foreach ($modulesdir as $dir) if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) $modulequalified=0; if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) $modulequalified=0; - // We discard modules according to property disabled + // We discard modules according to property ->hidden if (! empty($objMod->hidden)) $modulequalified=0; if ($modulequalified > 0) @@ -321,8 +323,8 @@ foreach ($modulesdir as $dir) // Define array $categ with categ with at least one qualified module if ($modulequalified > 0) { - $modules[$i] = $objMod; $filename[$i]= $modName; + $modules[$modName] = $objMod; $special = $objMod->special; @@ -342,6 +344,16 @@ foreach ($modulesdir as $dir) if ($special == 1) $familykey='interface'; + // Add list of warnings to show into arrayofwarnings and arrayofwarningsext + if (! empty($objMod->warnings_activation)) + { + $arrayofwarnings[$modName]=$objMod->warnings_activation; + } + if (! empty($objMod->warnings_activation_ext)) + { + $arrayofwarningsext[$modName]=$objMod->warnings_activation_ext; + } + $orders[$i] = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number $dirmod[$i] = $dir; //print $i.'-'.$dirmod[$i].'
    '; @@ -484,7 +496,7 @@ if ($mode == 'common') $familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3]; $modName = $filename[$key]; - $objMod = $modules[$key]; + $objMod = $modules[$modName]; $dirofmodule = $dirmod[$key]; $special = $objMod->special; @@ -633,7 +645,7 @@ if ($mode == 'common') print "
    '; if (! empty($objMod->always_enabled)) { - // Ne devrait pas arriver. + // Should never happened } else if (! empty($objMod->disabled)) { @@ -712,7 +724,34 @@ if ($mode == 'common') } else { - // Module non actif + // Module qualified for activation + $warningmessage=''; + if (! empty($arrayofwarnings[$modName])) + { + print ''."\n"; + foreach ($arrayofwarnings[$modName] as $keycountry => $cursorwarningmessage) + { + $warningmessage .= ($warningmessage?"\n":"").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code); + } + } + if ($objMod->isCoreOrExternalModule() == 'external' && ! empty($arrayofwarningsext)) + { + print ''."\n"; + foreach ($arrayofwarningsext as $keymodule => $arrayofwarningsextbycountry) + { + if (! empty($modules[$keymodule]->const_name)) // If module that request warning is on + { + foreach ($arrayofwarningsextbycountry as $keycountry => $cursorwarningmessage) + { + if ($keycountry == 'always' || $keycountry == $mysoc->country_code) + { + $warningmessage .= ($warningmessage?"\n":"").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code, $modules[$keymodule]->getName()); + } + } + } + } + } + print ''."\n"; print ''; print img_picto($langs->trans("Disabled"),'switch_off'); print "\n"; diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 288082296f3..7de948ddfba 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -779,16 +779,21 @@ function activateModule($value,$withdeps=1) { if (isset($objMod->depends) && is_array($objMod->depends) && ! empty($objMod->depends)) { - // Activation des modules dont le module depend - $num = count($objMod->depends); - for ($i = 0; $i < $num; $i++) + // Activation of modules this module depends on + // this->depends may be array('modModule1', 'mmodModule2') or array('always'=>"modModule1", 'FR'=>'modModule2') + foreach ($objMod->depend as $key => $modulestring) { + if ((! is_numeric($key)) && $key != 'always' && $key != $mysoc->country_code) + { + dol_syslog("We are not concerned by dependency with key=".$key." because our country is ".$mysoc->country_code); + continue; + } $activate = false; foreach ($modulesdir as $dir) { - if (file_exists($dir.$objMod->depends[$i].".class.php")) + if (file_exists($dir.$modulestring.".class.php")) { - $resarray = activateModule($objMod->depends[$i]); + $resarray = activateModule($modulestring); if (empty($resarray['errors'])){ $activate = true; }else{ @@ -807,7 +812,7 @@ function activateModule($value,$withdeps=1) } else { - $ret['errors'][] = $langs->trans('activateModuleDependNotSatisfied', $objMod->name, $objMod->depends[$i]); + $ret['errors'][] = $langs->trans('activateModuleDependNotSatisfied', $objMod->name, $modulestring); } } } diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 8e526baa241..84538801add 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -215,11 +215,6 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $descriptionlong; - /** - * @var string[] Module language files - */ - public $langfiles; - /** * @var string Module export code */ @@ -291,6 +286,7 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $config_page_url; + /** * @var string[] List of module class names that must be enabled if this module is enabled. * @@ -309,6 +305,26 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $conflictwith; + /** + * @var string[] Module language files + */ + public $langfiles; + + /** + * @var string[] Array of warnings to show when we activate the module + * + * array('always'='text') or array('FR'='text') + */ + public $warnings_activation; + + /** + * @var string[] Array of warnings to show when we activate an external module + * + * array('always'='text') or array('FR'='text') + */ + public $warnings_activation_ext; + + /** * @var array() Minimum version of PHP required by module. * e.g.: PHP ≥ 5.3 = array(5, 3) @@ -326,6 +342,7 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $hidden = false; + /** * Constructor. Define names, constants, directories, boxes, permissions * diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index bd5f193c568..88b154f891e 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -67,7 +67,7 @@ class modCron extends DolibarrModules // Dependancies //------------- - $this->hidden = ! empty($conf->global->CRON_MODULE_DISABLED); // A condition to disable module + $this->hidden = ! empty($conf->global->MODULE_CRON_DISABLED); // A condition to disable module $this->depends = array(); // List of modules id that must be enabled if this module is enabled $this->requiredby = array(); // List of modules id to disable if this one is disabled $this->conflictwith = array(); // List of modules id this module is in conflict with diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index 4bc8590d5b4..a88082ba6fc 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -64,11 +64,13 @@ class modFacture extends DolibarrModules $this->dirs = array("/facture/temp"); // Dependencies - $this->depends = array("modSociete"); + $this->depends = array('always'=>"modSociete", 'FR'=>'modBlockChainLog'); $this->requiredby = array("modComptabilite","modAccounting"); $this->conflictwith = array(); $this->langfiles = array("bills","companies","compta","products"); - + $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='text') + $this->warnings_activation_ext = array('CA'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') + // Config pages $this->config_page_url = array("facture.php"); @@ -96,7 +98,8 @@ class modFacture extends DolibarrModules $this->const[$r][3] = ""; $this->const[$r][4] = 0; $r++; - + + // Boxes //$this->boxes = array(0=>array(1=>'box_factures_imp.php'),1=>array(1=>'box_factures.php')); $this->boxes = array( diff --git a/htdocs/core/modules/modSkype.class.php b/htdocs/core/modules/modSkype.class.php index d6017b06c16..ca9179d5fa3 100644 --- a/htdocs/core/modules/modSkype.class.php +++ b/htdocs/core/modules/modSkype.class.php @@ -65,7 +65,7 @@ class modSkype extends DolibarrModules // Dependancies //------------- - $this->hidden = ! empty($conf->global->SKYPE_MODULE_DISABLED); // A condition to disable module + $this->hidden = ! empty($conf->global->MODULE_SKYPE_DISABLED); // A condition to disable module $this->depends = array('modSociete'); // List of modules id that must be enabled if this module is enabled $this->requiredby = array(); // List of modules id to disable if this one is disabled $this->conflictwith = array(); // List of modules id this module is in conflict with diff --git a/htdocs/core/modules/modWebsites.class.php b/htdocs/core/modules/modWebsites.class.php index 97dfbd6dd12..877c78b85eb 100644 --- a/htdocs/core/modules/modWebsites.class.php +++ b/htdocs/core/modules/modWebsites.class.php @@ -67,7 +67,7 @@ class modWebsites extends DolibarrModules // Dependancies //------------- - $this->hidden = ! empty($conf->global->WEBSITE_MODULE_DISABLED); // A condition to disable module + $this->hidden = ! empty($conf->global->MODULE_WEBSITE_DISABLED); // A condition to disable module $this->depends = array('modFckeditor'); // List of modules id that must be enabled if this module is enabled $this->requiredby = array(); // List of modules id to disable if this one is disabled $this->conflictwith = array(); // List of modules id this module is in conflict with diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a5fb93a4665..f5aa35f0c35 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1661,6 +1661,7 @@ ModuleEnabledAdminMustCheckRights=Module has been activated. Permissions for act UserHasNoPermissions=This user has no permission defined TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "Nb of days")
    Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days)
    Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days") BaseCurrency=Reference currency of the company (go into setup of company to change this) +WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activate an external module only if it does not alterate negatively the behavior required by your country laws (%s). If the module bring a non legal feature, you are the only responsible for the use of a non-compliant software. ##### Resource #### ResourceSetup=Configuration du module Resource UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list). From e44234a47f55ab12fdfe2d4eab393d67867e7439 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Mar 2017 15:16:45 +0100 Subject: [PATCH 029/410] NEW add property to show warnings when activating modules --- .../core/modules/modBlockChainLog.class.php | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 htdocs/core/modules/modBlockChainLog.class.php diff --git a/htdocs/core/modules/modBlockChainLog.class.php b/htdocs/core/modules/modBlockChainLog.class.php new file mode 100644 index 00000000000..dbf9cc406e9 --- /dev/null +++ b/htdocs/core/modules/modBlockChainLog.class.php @@ -0,0 +1,90 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \defgroup blockchainlog Module BlockChainLog + * \brief Add a log into a block chain for some actions. + * \file htdocs/core/modules/modBlockChainLog.class.php + * \ingroup blockchainlog + * \brief Description and activation file for module BlockChainLog + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + +/** + * Class to describe a Cron module + */ +class modBlockChainLog extends DolibarrModules +{ + + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $langs,$conf; + + $this->db = $db; + $this->numero = 3200; + + // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' + // It is used to group modules in module setup page + $this->family = "technic"; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + $this->description = "Enable a log of some business events into a non reversible block chain. This module may be mandatory for some countries."; + $this->version = 'development'; // 'development', 'experimental' or 'dolibarr' or version + // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) + $this->special = 1; + // Name of image file used for this module. + $this->picto='skype'; + + // Data directories to create when module is enabled + $this->dirs = array(); + + // Config pages + //------------- + $this->config_page_url = array(); + + // Dependancies + //------------- + $this->hidden = false; // A condition to disable module + $this->depends = array('modFacture'); // List of modules id that must be enabled if this module is enabled + $this->requiredby = array(); // List of modules id to disable if this one is disabled + $this->conflictwith = array(); // List of modules id this module is in conflict with + $this->langfiles = array(); + + // Constants + //----------- + + + // New pages on tabs + // ----------------- + $this->tabs = array(); + + // Boxes + //------ + $this->boxes = array(); + + // Main menu entries + //------------------ + $this->menu = array(); + } +} From 9b10c9f6d15cda7896d8ce0ea4402b1187ad1154 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 10 Mar 2017 09:19:42 +0100 Subject: [PATCH 030/410] FIX : Can use quote into supplier ref on order line add --- 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 b2f2d3dc3c3..322f06d58e1 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1457,7 +1457,7 @@ class CommandeFournisseur extends CommonOrder $sql.= ", '".$localtax1_type."',"; $sql.= " '".$localtax2_type."'"; - $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$ref."',"; + $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$this->db->escape($ref)."',"; $sql.= "'".price2num($total_ht)."',"; $sql.= "'".price2num($total_tva)."',"; $sql.= "'".price2num($total_localtax1)."',"; From 8389db18bf7de7b5b4219b1f9d7bd7712e7ce5b9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 10:07:09 +0100 Subject: [PATCH 031/410] Fix solution for comaptibility --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 6340facf31a..2fc6d22fd62 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1223,7 +1223,7 @@ abstract class CommonObject * @param int $id To force other object id (should not be used) * @param string $format Data format ('text', 'date'). 'text' is used if not defined * @param string $id_field To force rowid field name. 'rowid' is used if not defined - * @param User|string $user Update last update fields also if user object provided + * @param User|string $user Update last update fields also if user object provided. If not provided, current user is used. * @param string $trigkey Trigger key to run (in most cases something like 'XXX_MODIFY') * @return int <0 if KO, >0 if OK */ @@ -1247,7 +1247,7 @@ abstract class CommonObject if ($format == 'text') $sql.= $field." = '".$this->db->escape($value)."'"; else if ($format == 'int') $sql.= $field." = ".$this->db->escape($value); else if ($format == 'date') $sql.= $field." = ".($value ? "'".$this->db->idate($value)."'" : "null"); - if (is_object($user)) $sql.=", fk_user_modif = ".$user->id; + if (empty($user) && is_object($user)) $sql.=", fk_user_modif = ".$user->id; $sql.= " WHERE ".$id_field." = ".$id; dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG); From b3d27521cb238fe20c4261f3b66b4aa2009c3e12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 10:55:35 +0100 Subject: [PATCH 032/410] Fix Must use tdoverflowmax100 instead of tdoverflow --- htdocs/core/boxes/box_services_expired.php | 14 ++++++++------ htdocs/core/boxes/modules_boxes.php | 2 +- htdocs/theme/eldy/style.css.php | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index f2bc86cdac5..90f36ef6d30 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -83,6 +83,8 @@ class box_services_expired extends ModeleBoxes $i = 0; + $thirdpartytmp = new Societe($this->db); + while ($i < $num) { $late=''; @@ -100,13 +102,13 @@ class box_services_expired extends ModeleBoxes 'text' => ($objp->ref?$objp->ref:$objp->rowid), // Some contracts have no ref 'url' => DOL_URL_ROOT."/contrat/card.php?id=".$objp->rowid); - $this->info_box_contents[$i][2] = array('td' => 'align="left" width="16"', - 'logo' => 'company', - 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); + $thirdpartytmp->id = $objp->socid; + $thirdpartytmp->name = $objp->name; - $this->info_box_contents[$i][3] = array('td' => 'class="tdoverflow maxwidth100onsmartphone" align="left"', - 'text' => $objp->name, - 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); + $this->info_box_contents[$i][2] = array('td' => 'class="tdoverflowmax100 maxwidth100onsmartphone" align="left"', + 'text' => $thirdpartytmp->getNomUrl(1, 'customer'), + 'asis' => 1 + ); $this->info_box_contents[$i][4] = array('td' => 'align="center"', 'text' => dol_print_date($dateline,'day'), diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 9a093cff927..3ebac7e7ab0 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -240,7 +240,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" $out.= '>'; if ($conf->use_javascript_ajax) { - $out.= ''; } diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 195ad3dbd89..e47d105e863 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -413,11 +413,11 @@ if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) { print ''; } -print ''; -print ''; -print ''; -if ($usertoprocess->id == $user->id) print ''; -else print ''; +print ''; +print ''; +print ''; +if ($usertoprocess->id == $user->id) print ''; +else print ''; print ''; print ''; print ''; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 7bfa7728d4f..fb2f3f1c752 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -408,17 +408,17 @@ if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) { print ''; } -print ''; -print ''; -print ''; -if ($usertoprocess->id == $user->id) print ''; -else print ''; +print ''; +print ''; +print ''; +if ($usertoprocess->id == $user->id) print ''; +else print ''; $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['first_day'], $startdayarray['first_year']); for($i=0;$i<7;$i++) { - print ''; + print ''; } print ''; print "\n"; @@ -460,13 +460,13 @@ if (count($tasksarray) > 0) print ' - - - - - - - + + + + + + + '; } From dba6d996869a7d2549472d13508a3fd78e5c6beb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Mar 2017 17:02:30 +0100 Subject: [PATCH 115/410] Minor look enhancement --- htdocs/core/class/html.form.class.php | 19 +++++++++++-------- htdocs/core/class/html.formprojet.class.php | 2 +- htdocs/core/lib/project.lib.php | 1 - htdocs/projet/activity/perday.php | 8 +++++--- htdocs/projet/activity/perweek.php | 6 ++++-- htdocs/theme/eldy/style.css.php | 4 ++-- htdocs/theme/md/style.css.php | 4 ++-- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index dc47dec5c41..1366435f144 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4740,7 +4740,7 @@ class Form // Year if ($emptydate || $set_time == -1) { - $retstring.=''; + $retstring.=''; } else { @@ -4885,7 +4885,7 @@ class Form * @param string $prefix Prefix for input fields * @param int $iSecond Default preselected duration (number of seconds or '') * @param int $disabled Disable the combo box - * @param string $typehour If 'select' then input hour and input min is a combo, if 'text' input hour is in text and input min is a combo + * @param string $typehour If 'select' then input hour and input min is a combo, if 'text' input hour is in text and input min is a text * @param integer $minunderhours If 1, show minutes selection under the hours * @param int $nooutput Do not output html string but return it * @return string|null @@ -4923,12 +4923,13 @@ class Form } elseif ($typehour=='text') { - $retstring.=''; + $retstring.=''; } else return 'BadValueForParameterTypeHour'; - $retstring.=' '.$langs->trans('HourShort'); - + if ($typehour!='text') $retstring.=' '.$langs->trans('HourShort'); + else $retstring.=':'; + // Minutes if ($minunderhours) $retstring.='
    '; else $retstring.=" "; @@ -4946,10 +4947,12 @@ class Form } elseif ($typehour=='text') { - $retstring.=''; + $retstring.=''; } - $retstring.=' '.$langs->trans('MinuteShort'); - $retstring.=" "; + + if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); + + //$retstring.=" "; if (! empty($nooutput)) return $retstring; diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 0a6837ecb53..ea77904f5cf 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -352,7 +352,7 @@ class FormProjets } if (empty($option_only)) { - $out.= ''; } if (!empty($show_empty)) { $out.= ''; diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 173aee8ce26..054ab579194 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -919,7 +919,6 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $tableCell.=''; print $tableCell; } - dol_syslog("yyy"); print '
    '; + $out.= ''; print ''; // Other options diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 890de102e6b..84dccbb93e7 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -400,7 +400,7 @@ if ($id > 0 || ! empty($ref)) // Description print ''; print ''; // Other options From 7f8c4d7d0fbbaf7ee1d22190337d2ec06062a4ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Mar 2017 14:33:25 +0100 Subject: [PATCH 101/410] Fix CSS --- htdocs/comm/card.php | 2 +- htdocs/fourn/card.php | 2 +- htdocs/index.php | 84 ++++++++++++++++++--------------- htdocs/langs/en_US/main.lang | 1 + htdocs/theme/eldy/style.css.php | 3 ++ htdocs/theme/md/style.css.php | 3 ++ 6 files changed, 55 insertions(+), 40 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 126c3fe0f62..b7cd28c446a 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -519,7 +519,7 @@ if ($id > 0) // Lien recap $boxstat.='
    '; - $boxstat.='
    '; } if (! empty($head['text'])) { diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 090bb3f887c..ffb3e7b83f8 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -583,13 +583,13 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } -.tdoverflowmax100 { +.tdoverflowmax100 { /* For tdoverflow, the max-midth become a minimum ! */ max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.tdoverflowmax300 { +.tdoverflowmax300 { /* For tdoverflow, the max-midth become a minimum ! */ max-width: 300px; overflow: hidden; text-overflow: ellipsis; From 567639397ecfdede34d8e31f4c63f8aee41e592e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 10:55:35 +0100 Subject: [PATCH 033/410] Fix Must use tdoverflowmax100 instead of tdoverflow --- htdocs/core/boxes/box_services_expired.php | 14 ++++++++------ htdocs/core/boxes/modules_boxes.php | 2 +- htdocs/theme/eldy/style.css.php | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index f2bc86cdac5..90f36ef6d30 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -83,6 +83,8 @@ class box_services_expired extends ModeleBoxes $i = 0; + $thirdpartytmp = new Societe($this->db); + while ($i < $num) { $late=''; @@ -100,13 +102,13 @@ class box_services_expired extends ModeleBoxes 'text' => ($objp->ref?$objp->ref:$objp->rowid), // Some contracts have no ref 'url' => DOL_URL_ROOT."/contrat/card.php?id=".$objp->rowid); - $this->info_box_contents[$i][2] = array('td' => 'align="left" width="16"', - 'logo' => 'company', - 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); + $thirdpartytmp->id = $objp->socid; + $thirdpartytmp->name = $objp->name; - $this->info_box_contents[$i][3] = array('td' => 'class="tdoverflow maxwidth100onsmartphone" align="left"', - 'text' => $objp->name, - 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); + $this->info_box_contents[$i][2] = array('td' => 'class="tdoverflowmax100 maxwidth100onsmartphone" align="left"', + 'text' => $thirdpartytmp->getNomUrl(1, 'customer'), + 'asis' => 1 + ); $this->info_box_contents[$i][4] = array('td' => 'align="center"', 'text' => dol_print_date($dateline,'day'), diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 0f754682925..566da25aad3 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -243,7 +243,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" $out.= '>'; if ($conf->use_javascript_ajax) { - $out.= ''; + print ''; } print '
    '; + $out.= ''; + + if (! empty($conf->global->ACCOUNTING_MANAGE_ZERO) && ($key == 'ACCOUNTING_LENGTH_GACCOUNT' || $key == 'ACCOUNTING_LENGTH_AACCOUNT')) continue; + // Param $label = $langs->trans($key); print ''; // Value print ''; + print ''; } diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php index 6778f618265..e9d38ad3776 100644 --- a/htdocs/admin/index.php +++ b/htdocs/admin/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index bb704ba5c2e..8ec0713b01a 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -116,8 +116,9 @@ function length_accountg($account) if ($account < 0 || empty($account)) return ''; + if (! empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; + $g = $conf->global->ACCOUNTING_LENGTH_GACCOUNT; - if (! empty($g)) { // Clean parameters $i = strlen($account); @@ -150,8 +151,9 @@ function length_accounta($accounta) if ($accounta < 0 || empty($accounta)) return ''; + if (! empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; + $a = $conf->global->ACCOUNTING_LENGTH_AACCOUNT; - if (! empty($a)) { // Clean parameters $i = strlen($accounta); diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 85b7b60c01b..5a9e63ef4d9 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -105,9 +105,9 @@ ACCOUNTING_LIST_SORT_VENTILATION_DONE=Begin the sorting of the page "Binding don ACCOUNTING_LENGTH_DESCRIPTION=Truncate product & services description in listings after x chars (Best = 50) ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT=Truncate product & services account description form in listings after x chars (Best = 50) -ACCOUNTING_LENGTH_GACCOUNT=Length of the general accounting accounts -ACCOUNTING_LENGTH_AACCOUNT=Length of the third party accounting accounts -ACCOUNTING_MANAGE_ZERO=Manage the zero at the end of an accounting account. Needed by some countries. Disabled by default. If set to on, you must not set the 2 following parameters. This function adds real zero while the 2 following functions add virtual zero. +ACCOUNTING_LENGTH_GACCOUNT=Length of the general accounting accounts (If you set value to 6 here, the account '706' will appear like '706000' on screen) +ACCOUNTING_LENGTH_AACCOUNT=Length of the third party accounting accounts (If you set value to 6 here, the account '401' will appear like '401000' on screen) +ACCOUNTING_MANAGE_ZERO=Allow to manage different number of zero at the end of an accounting account. Needed by some countries (like switzerland). If keep to off (default), you can set the 2 following parameters to ask application to add virtual zero. BANK_DISABLE_DIRECT_INPUT=Disable direct recording of transaction in bank account ACCOUNTING_SELL_JOURNAL=Sell journal From e5fc1583c7b89b19a603d7a04a1bc08742f523ba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 12:05:42 +0100 Subject: [PATCH 037/410] Fix No external access without using getUrlContent function. --- htdocs/core/tpl/login.tpl.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index ba501e802dd..e0aa28ce2d6 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -239,16 +239,21 @@ if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file global->MAIN_EASTER_EGG_COMMITSTRIP)) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; if (substr($langs->defaultlang,0,2)=='fr') { - $xml = simplexml_load_file("http://www.commitstrip.com/fr/feed/"); + $resgetcommitstrip = getURLContent("http://www.commitstrip.com/fr/feed/"); } else { - $xml = simplexml_load_file("http://www.commitstrip.com/en/feed/"); + $resgetcommitstrip = getURLContent("http://www.commitstrip.com/en/feed/"); } - - $little = $xml->channel->item[0]->children('content',true); - - print $little->encoded; + if ($resgetcommitstrip && $resgetcommitstrip['http_code'] == '200') + { + $xml = simplexml_load_string($resgetcommitstrip['content']); + $little = $xml->channel->item[0]->children('content',true); + print $little->encoded; + } } ?> From bf345430859756d2f8c778904c8e4279a61485b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 12:19:50 +0100 Subject: [PATCH 038/410] FIX #6443 --- htdocs/core/lib/files.lib.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index f0cab58bb09..2607f4b2c58 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2304,17 +2304,32 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu // Define $accessallowed if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg)) { - if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1; + if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported + { + dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + exit; + } + if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$fuser->id.'/'.$original_file; } else if (preg_match('/^([a-z]+)_temp$/i',$modulepart,$reg)) { - if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1; + if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported + { + dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + exit; + } + if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$original_file; } else if (preg_match('/^([a-z]+)_user$/i',$modulepart,$reg)) { - if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1; + if (empty($conf->{$reg[1]}->dir_output)) // modulepart not supported + { + dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + exit; + } + if ($fuser->rights->{$reg[1]}->lire || $fuser->rights->{$reg[1]}->read || ($fuser->rights->{$reg[1]}->download)) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file; } else From 50044ed21ecf129e3a4b5e60fa3aecd672bd047a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 12:45:56 +0100 Subject: [PATCH 039/410] FIX #6499 --- .../core/class/commondocgenerator.class.php | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 75336e2a291..0e884f87d0d 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -304,11 +304,13 @@ abstract class CommonDocGenerator $now=dol_now('gmt'); // gmt $array_other = array( - 'current_date'=>dol_print_date($now,'day','tzuser'), - 'current_datehour'=>dol_print_date($now,'dayhour','tzuser'), + // Date in default language + 'current_date'=>dol_print_date($now,'day','tzuser'), + 'current_datehour'=>dol_print_date($now,'dayhour','tzuser'), 'current_server_date'=>dol_print_date($now,'day','tzserver'), 'current_server_datehour'=>dol_print_date($now,'dayhour','tzserver'), - 'current_date_locale'=>dol_print_date($now,'day','tzuser',$outputlangs), + // Date in requested output language + 'current_date_locale'=>dol_print_date($now,'day','tzuser',$outputlangs), 'current_datehour_locale'=>dol_print_date($now,'dayhour','tzuser',$outputlangs), 'current_server_date_locale'=>dol_print_date($now,'day','tzserver',$outputlangs), 'current_server_datehour_locale'=>dol_print_date($now,'dayhour','tzserver',$outputlangs), @@ -350,6 +352,7 @@ abstract class CommonDocGenerator $array_key.'_ref_customer'=>$object->ref_client, $array_key.'_ref_supplier'=>(! empty($object->ref_fournisseur)?$object->ref_fournisseur:''), $array_key.'_source_invoice_ref'=>$invoice_source->ref, + // Dates $array_key.'_hour'=>dol_print_date($object->date,'hour'), $array_key.'_date'=>dol_print_date($object->date,'day'), $array_key.'_date_rfc'=>dol_print_date($object->date,'dayrfc'), @@ -360,6 +363,7 @@ abstract class CommonDocGenerator $array_key.'_date_validation'=>(! empty($object->date_validation)?dol_print_date($object->date_validation,'dayhour'):''), $array_key.'_date_delivery_planed'=>(! empty($object->date_livraison)?dol_print_date($object->date_livraison,'day'):''), $array_key.'_date_close'=>(! empty($object->date_cloture)?dol_print_date($object->date_cloture,'dayhour'):''), + $array_key.'_payment_mode_code'=>$object->mode_reglement_code, $array_key.'_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code)!='PaymentType'.$object->mode_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code):$object->mode_reglement), $array_key.'_payment_term_code'=>$object->cond_reglement_code, @@ -444,10 +448,14 @@ abstract class CommonDocGenerator 'line_price_ht_locale'=>price($line->total_ht, 0, $outputlangs), 'line_price_ttc_locale'=>price($line->total_ttc, 0, $outputlangs), 'line_price_vat_locale'=>price($line->total_tva, 0, $outputlangs), - 'line_date_start'=>$line->date_start, - 'line_date_start_rfc'=>dol_print_date($line->date_start,'dayrfc'), - 'line_date_end'=>$line->date_end, - 'line_date_end_rfc'=>dol_print_date($line->date_end,'dayrfc') + 'line_date_start'=>dol_print_date($line->date_start, 'day', 'tzuser'), + 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzuser', $outputlangs), + 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser'), + 'line_date_start_rfc_locale'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser', $outputlangs), + 'line_date_end'=>dol_print_date($line->date_end, 'day', 'tzuser'), + 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzuser', $outputlangs), + 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser'), + 'line_date_end_rfc_locale'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser', $outputlangs) ); // Retrieve extrafields From de2558c9075605aea5bbbef82c55866315f4c323 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 12:47:31 +0100 Subject: [PATCH 040/410] Fix useless lines --- htdocs/core/class/commondocgenerator.class.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 0e884f87d0d..f338aca7be8 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -448,14 +448,13 @@ abstract class CommonDocGenerator 'line_price_ht_locale'=>price($line->total_ht, 0, $outputlangs), 'line_price_ttc_locale'=>price($line->total_ttc, 0, $outputlangs), 'line_price_vat_locale'=>price($line->total_tva, 0, $outputlangs), + // Dates 'line_date_start'=>dol_print_date($line->date_start, 'day', 'tzuser'), 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzuser', $outputlangs), 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser'), - 'line_date_start_rfc_locale'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser', $outputlangs), 'line_date_end'=>dol_print_date($line->date_end, 'day', 'tzuser'), 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzuser', $outputlangs), 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser'), - 'line_date_end_rfc_locale'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser', $outputlangs) ); // Retrieve extrafields From 1610926ccd0c740d8e5eeea067bf66d302644cde Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 13:11:12 +0100 Subject: [PATCH 041/410] Fix remove a line that look useless --- htdocs/core/lib/files.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 13d458f4047..4df92d3da4e 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1935,7 +1935,8 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->$modulepart->dir_output.'/'.$original_file; } } - if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a specimen + + //if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a specimen if ($fuser->admin) $accessallowed=1; // If user is admin // For modules who wants to manage different levels of permissions for documents From 3f69b1fdf5c32c8b64b557196bb127e64d950492 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 13:14:02 +0100 Subject: [PATCH 042/410] Revert "Fix remove a line that look useless" This reverts commit 1610926ccd0c740d8e5eeea067bf66d302644cde. --- htdocs/core/lib/files.lib.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 4df92d3da4e..13d458f4047 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1935,8 +1935,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->$modulepart->dir_output.'/'.$original_file; } } - - //if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a specimen + if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a specimen if ($fuser->admin) $accessallowed=1; // If user is admin // For modules who wants to manage different levels of permissions for documents From 1a57d1864a048bd1ce289b494997f23d54e2c9f0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 13:39:11 +0100 Subject: [PATCH 043/410] FIX #6443 --- htdocs/core/lib/files.lib.php | 146 ++++++++++++++++------------------ 1 file changed, 67 insertions(+), 79 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 2607f4b2c58..337b0fdc460 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1803,120 +1803,122 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu // find the subdirectory name as the reference if (empty($refname)) $refname=basename(dirname($original_file)."/"); + $relative_original_file = $original_file; + // Wrapping for some images - if ($modulepart == 'companylogo') + if ($modulepart == 'companylogo' && !empty($conf->mycompany->dir_output)) { $accessallowed=1; $original_file=$conf->mycompany->dir_output.'/logos/'.$original_file; } // Wrapping for users photos - elseif ($modulepart == 'userphoto') + elseif ($modulepart == 'userphoto' && !empty($conf->user->dir_output)) { $accessallowed=1; $original_file=$conf->user->dir_output.'/'.$original_file; } // Wrapping for members photos - elseif ($modulepart == 'memberphoto') + elseif ($modulepart == 'memberphoto' && !empty($conf->adherent->dir_output)) { $accessallowed=1; $original_file=$conf->adherent->dir_output.'/'.$original_file; } // Wrapping pour les apercu factures - elseif ($modulepart == 'apercufacture') + elseif ($modulepart == 'apercufacture' && !empty($conf->facture->dir_output)) { if ($fuser->rights->facture->lire) $accessallowed=1; $original_file=$conf->facture->dir_output.'/'.$original_file; } // Wrapping pour les apercu propal - elseif ($modulepart == 'apercupropal') + elseif ($modulepart == 'apercupropal' && !empty($conf->propal->dir_output)) { if ($fuser->rights->propale->lire) $accessallowed=1; $original_file=$conf->propal->dir_output.'/'.$original_file; } // Wrapping pour les apercu commande - elseif ($modulepart == 'apercucommande') + elseif ($modulepart == 'apercucommande' && !empty($conf->commande->dir_output)) { if ($fuser->rights->commande->lire) $accessallowed=1; $original_file=$conf->commande->dir_output.'/'.$original_file; } // Wrapping pour les apercu intervention - elseif ($modulepart == 'apercufichinter') + elseif ($modulepart == 'apercufichinter' && !empty($conf->ficheinter->dir_output)) { if ($fuser->rights->ficheinter->lire) $accessallowed=1; $original_file=$conf->ficheinter->dir_output.'/'.$original_file; } // Wrapping pour les images des stats propales - elseif ($modulepart == 'propalstats') + elseif ($modulepart == 'propalstats' && !empty($conf->propal->dir_temp)) { if ($fuser->rights->propale->lire) $accessallowed=1; $original_file=$conf->propal->dir_temp.'/'.$original_file; } // Wrapping pour les images des stats commandes - elseif ($modulepart == 'orderstats') + elseif ($modulepart == 'orderstats' && !empty($conf->commande->dir_temp)) { if ($fuser->rights->commande->lire) $accessallowed=1; $original_file=$conf->commande->dir_temp.'/'.$original_file; } - elseif ($modulepart == 'orderstatssupplier') + elseif ($modulepart == 'orderstatssupplier' && !empty($conf->fournisseur->dir_output)) { if ($fuser->rights->fournisseur->commande->lire) $accessallowed=1; $original_file=$conf->fournisseur->dir_output.'/commande/temp/'.$original_file; } // Wrapping pour les images des stats factures - elseif ($modulepart == 'billstats') + elseif ($modulepart == 'billstats' && !empty($conf->facture->dir_temp)) { if ($fuser->rights->facture->lire) $accessallowed=1; $original_file=$conf->facture->dir_temp.'/'.$original_file; } - elseif ($modulepart == 'billstatssupplier') + elseif ($modulepart == 'billstatssupplier' && !empty($conf->fournisseur->dir_output)) { if ($fuser->rights->fournisseur->facture->lire) $accessallowed=1; $original_file=$conf->fournisseur->dir_output.'/facture/temp/'.$original_file; } // Wrapping pour les images des stats expeditions - elseif ($modulepart == 'expeditionstats') + elseif ($modulepart == 'expeditionstats' && !empty($conf->expedition->dir_temp)) { if ($fuser->rights->expedition->lire) $accessallowed=1; $original_file=$conf->expedition->dir_temp.'/'.$original_file; } // Wrapping pour les images des stats expeditions - elseif ($modulepart == 'tripsexpensesstats') + elseif ($modulepart == 'tripsexpensesstats' && !empty($conf->deplacement->dir_temp)) { if ($fuser->rights->deplacement->lire) $accessallowed=1; $original_file=$conf->deplacement->dir_temp.'/'.$original_file; } // Wrapping pour les images des stats expeditions - elseif ($modulepart == 'memberstats') + elseif ($modulepart == 'memberstats' && !empty($conf->adherent->dir_temp)) { if ($fuser->rights->adherent->lire) $accessallowed=1; $original_file=$conf->adherent->dir_temp.'/'.$original_file; } // Wrapping pour les images des stats produits - elseif (preg_match('/^productstats_/i',$modulepart)) + elseif (preg_match('/^productstats_/i',$modulepart) && !empty($conf->product->dir_temp)) { if ($fuser->rights->produit->lire || $fuser->rights->service->lire) $accessallowed=1; $original_file=(!empty($conf->product->multidir_temp[$entity])?$conf->product->multidir_temp[$entity]:$conf->service->multidir_temp[$entity]).'/'.$original_file; } // Wrapping for products or services - elseif ($modulepart == 'tax') + elseif ($modulepart == 'tax' && !empty($conf->tax->dir_output)) { if ($fuser->rights->tax->charges->lire) $accessallowed=1; $original_file=$conf->tax->dir_output.'/'.$original_file; } // Wrapping for products or services - elseif ($modulepart == 'actions') + elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) { if ($fuser->rights->agenda->myactions->read) $accessallowed=1; $original_file=$conf->agenda->dir_output.'/'.$original_file; } // Wrapping for categories - elseif ($modulepart == 'category') + elseif ($modulepart == 'category' && !empty($conf->categorie->dir_output)) { if ($fuser->rights->categorie->lire) $accessallowed=1; $original_file=$conf->categorie->multidir_output[$entity].'/'.$original_file; } // Wrapping pour les prelevements - elseif ($modulepart == 'prelevement') + elseif ($modulepart == 'prelevement' && !empty($conf->prelevement->dir_output)) { if ($fuser->rights->prelevement->bons->lire || preg_match('/^specimen/i',$original_file)) { @@ -1925,19 +1927,19 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->prelevement->dir_output.'/'.$original_file; } // Wrapping pour les graph energie - elseif ($modulepart == 'graph_stock') + elseif ($modulepart == 'graph_stock' && !empty($conf->stock->dir_temp)) { $accessallowed=1; $original_file=$conf->stock->dir_temp.'/'.$original_file; } // Wrapping pour les graph fournisseurs - elseif ($modulepart == 'graph_fourn') + elseif ($modulepart == 'graph_fourn' && !empty($conf->fournisseur->dir_temp)) { $accessallowed=1; $original_file=$conf->fournisseur->dir_temp.'/'.$original_file; } // Wrapping pour les graph des produits - elseif ($modulepart == 'graph_product') + elseif ($modulepart == 'graph_product' && !empty($conf->product->dir_temp)) { $accessallowed=1; $original_file=$conf->product->multidir_temp[$entity].'/'.$original_file; @@ -1946,32 +1948,31 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu elseif ($modulepart == 'barcode') { $accessallowed=1; - // If viewimage is called for barcode, we try to output an image on the fly, - // with not build of file on disk. + // If viewimage is called for barcode, we try to output an image on the fly, with no build of file on disk. //$original_file=$conf->barcode->dir_temp.'/'.$original_file; $original_file=''; } // Wrapping pour les icones de background des mailings - elseif ($modulepart == 'iconmailing') + elseif ($modulepart == 'iconmailing' && !empty($conf->mailing->dir_temp)) { $accessallowed=1; $original_file=$conf->mailing->dir_temp.'/'.$original_file; } - // Wrapping pour les icones de background des mailings - elseif ($modulepart == 'scanner_user_temp') + // Wrapping pour le scanner + elseif ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp)) { $accessallowed=1; $original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file; } // Wrapping pour les images fckeditor - elseif ($modulepart == 'fckeditor') + elseif ($modulepart == 'fckeditor' && !empty($conf->fckeditor->dir_output)) { $accessallowed=1; $original_file=$conf->fckeditor->dir_output.'/'.$original_file; } // Wrapping for third parties - else if ($modulepart == 'company' || $modulepart == 'societe') + else if (($modulepart == 'company' || $modulepart == 'societe') && !empty($conf->societe->dir_output)) { if ($fuser->rights->societe->lire || preg_match('/^specimen/i',$original_file)) { @@ -1982,7 +1983,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for contact - else if ($modulepart == 'contact') + else if ($modulepart == 'contact' && !empty($conf->societe->dir_output)) { if ($fuser->rights->societe->lire) { @@ -1992,7 +1993,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for invoices - else if ($modulepart == 'facture' || $modulepart == 'invoice') + else if (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->dir_output)) { if ($fuser->rights->facture->lire || preg_match('/^specimen/i',$original_file)) { @@ -2001,7 +2002,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->facture->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } - else if ($modulepart == 'massfilesarea_facture') + else if ($modulepart == 'massfilesarea_facture' && !empty($conf->facture->dir_output)) { if ($fuser->rights->facture->lire || preg_match('/^specimen/i',$original_file)) { @@ -2010,8 +2011,8 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - // Wrapping pour les fiches intervention - else if ($modulepart == 'ficheinter') + // Wrapping for interventions + else if (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output)) { if ($fuser->rights->ficheinter->lire || preg_match('/^specimen/i',$original_file)) { @@ -2022,7 +2023,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les deplacements et notes de frais - else if ($modulepart == 'deplacement') + else if ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output)) { if ($fuser->rights->deplacement->lire || preg_match('/^specimen/i',$original_file)) { @@ -2032,7 +2033,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu //$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } // Wrapping pour les propales - else if ($modulepart == 'propal') + else if ($modulepart == 'propal' && !empty($conf->propal->dir_output)) { if ($fuser->rights->propale->lire || preg_match('/^specimen/i',$original_file)) { @@ -2044,7 +2045,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les commandes - else if ($modulepart == 'commande' || $modulepart == 'order') + else if (($modulepart == 'commande' || $modulepart == 'order') && !empty($conf->commande->dir_output)) { if ($fuser->rights->commande->lire || preg_match('/^specimen/i',$original_file)) { @@ -2055,7 +2056,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les projets - else if ($modulepart == 'project') + else if ($modulepart == 'project' && !empty($conf->projet->dir_output)) { if ($fuser->rights->projet->lire || preg_match('/^specimen/i',$original_file)) { @@ -2064,7 +2065,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->projet->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } - else if ($modulepart == 'project_task') + else if ($modulepart == 'project_task' && !empty($conf->projet->dir_output)) { if ($fuser->rights->projet->lire || preg_match('/^specimen/i',$original_file)) { @@ -2073,19 +2074,9 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->projet->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } - // Wrapping for interventions - else if ($modulepart == 'fichinter') - { - if ($fuser->rights->ficheinter->lire || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->ficheinter->dir_output.'/'.$original_file; - $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; - } // Wrapping pour les commandes fournisseurs - else if ($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') + else if (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) { if ($fuser->rights->fournisseur->commande->lire || preg_match('/^specimen/i',$original_file)) { @@ -2096,7 +2087,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les factures fournisseurs - else if ($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') + else if (($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') && !empty($conf->fournisseur->facture->dir_output)) { if ($fuser->rights->fournisseur->facture->lire || preg_match('/^specimen/i',$original_file)) { @@ -2107,7 +2098,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les rapport de paiements - else if ($modulepart == 'facture_paiement') + else if ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output)) { if ($fuser->rights->facture->lire || preg_match('/^specimen/i',$original_file)) { @@ -2118,7 +2109,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for accounting exports - else if ($modulepart == 'export_compta') + else if ($modulepart == 'export_compta' && !empty($conf->accounting->dir_output)) { if ($fuser->rights->accounting->ventilation->dispatch || preg_match('/^specimen/i',$original_file)) { @@ -2128,7 +2119,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les expedition - else if ($modulepart == 'expedition') + else if ($modulepart == 'expedition' && !empty($conf->expedition->dir_output)) { if ($fuser->rights->expedition->lire || preg_match('/^specimen/i',$original_file)) { @@ -2138,7 +2129,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les bons de livraison - else if ($modulepart == 'livraison') + else if ($modulepart == 'livraison' && !empty($conf->livraison->dir_output)) { if ($fuser->rights->expedition->livraison->lire || preg_match('/^specimen/i',$original_file)) { @@ -2148,7 +2139,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les actions - else if ($modulepart == 'actions') + else if ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) { if ($fuser->rights->agenda->myactions->read || preg_match('/^specimen/i',$original_file)) { @@ -2158,7 +2149,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les actions - else if ($modulepart == 'actionsreport') + else if ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp)) { if ($fuser->rights->agenda->allactions->read || preg_match('/^specimen/i',$original_file)) { @@ -2179,7 +2170,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les contrats - else if ($modulepart == 'contract') + else if ($modulepart == 'contract' && !empty($conf->contrat->dir_output)) { if ($fuser->rights->contrat->lire || preg_match('/^specimen/i',$original_file)) { @@ -2189,7 +2180,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les dons - else if ($modulepart == 'donation') + else if ($modulepart == 'donation' && !empty($conf->donation->dir_output)) { if ($fuser->rights->don->lire || preg_match('/^specimen/i',$original_file)) { @@ -2199,7 +2190,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour les remises de cheques - else if ($modulepart == 'remisecheque') + else if ($modulepart == 'remisecheque' && !empty($conf->banque->dir_output)) { if ($fuser->rights->banque->lire || preg_match('/^specimen/i',$original_file)) { @@ -2210,7 +2201,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for bank - else if ($modulepart == 'bank') + else if ($modulepart == 'bank' && !empty($conf->bank->dir_output)) { if ($fuser->rights->banque->lire) { @@ -2220,7 +2211,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for export module - else if ($modulepart == 'export') + else if ($modulepart == 'export' && !empty($conf->export->dir_temp)) { // Aucun test necessaire car on force le rep de download sur // le rep export qui est propre a l'utilisateur @@ -2229,21 +2220,21 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for import module - else if ($modulepart == 'import') + else if ($modulepart == 'import' && !empty($conf->import->dir_temp)) { $accessallowed=1; $original_file=$conf->import->dir_temp.'/'.$original_file; } // Wrapping pour l'editeur wysiwyg - else if ($modulepart == 'editor') + else if ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output)) { $accessallowed=1; $original_file=$conf->fckeditor->dir_output.'/'.$original_file; } // Wrapping for miscellaneous medias files - elseif ($modulepart == 'medias') + elseif ($modulepart == 'medias' && !empty($dolibarr_main_data_root)) { $accessallowed=1; global $dolibarr_main_data_root; @@ -2251,25 +2242,21 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for backups - else if ($modulepart == 'systemtools') + else if ($modulepart == 'systemtools' && !empty($conf->admin->dir_output)) { - if ($fuser->admin) - { - $accessallowed=1; - } + if ($fuser->admin) $accessallowed=1; $original_file=$conf->admin->dir_output.'/'.$original_file; } // Wrapping for upload file test - else if ($modulepart == 'admin_temp') + else if ($modulepart == 'admin_temp' && !empty($conf->admin->dir_temp)) { - if ($fuser->admin) - $accessallowed=1; + if ($fuser->admin) $accessallowed=1; $original_file=$conf->admin->dir_temp.'/'.$original_file; } // Wrapping pour BitTorrent - else if ($modulepart == 'bittorrent') + else if ($modulepart == 'bittorrent' && !empty($conf->bittorrent->dir_output)) { $accessallowed=1; $dir='files'; @@ -2278,7 +2265,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping pour Foundation module - else if ($modulepart == 'member') + else if ($modulepart == 'member' && !empty($conf->adherent->dir_output)) { if ($fuser->rights->adherent->lire || preg_match('/^specimen/i',$original_file)) { @@ -2288,7 +2275,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } // Wrapping for Scanner - else if ($modulepart == 'scanner_user_temp') + else if ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp)) { $accessallowed=1; $original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file; @@ -2301,6 +2288,9 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu // If modulepart=module Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart else { + if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a file called specimen. Test must be done before changing $original_file int full path. + if ($fuser->admin) $accessallowed=1; // If user is admin + // Define $accessallowed if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg)) { @@ -2353,8 +2343,6 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->$modulepart->dir_output.'/'.$original_file; } } - if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a specimen - if ($fuser->admin) $accessallowed=1; // If user is admin // For modules who wants to manage different levels of permissions for documents $subPermCategoryConstName = strtoupper($modulepart).'_SUBPERMCATEGORY_FOR_DOCUMENTS'; From fbbcec2ba3e1346202c50a74a553296568270fb6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 14:04:06 +0100 Subject: [PATCH 044/410] FIX #6444 --- htdocs/core/lib/files.lib.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 337b0fdc460..664c2e0a03d 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1066,7 +1066,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable } // Security: - // On interdit fichiers caches, remontees de repertoire ainsi que les pipes dans les noms de fichiers. + // We refuse cache files/dirs, upload using .. and pipes into filenames. if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file)) { dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING); @@ -1150,6 +1150,14 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n dol_syslog("dol_delete_file file=".$file." disableglob=".$disableglob." nophperrors=".$nophperrors." nohook=".$nohook); + // Security: + // We refuse cache files/dirs, upload using .. and pipes into filenames. + if (preg_match('/^\./',$file) || preg_match('/\.\./',$file) || preg_match('/[<>|]/',$file)) + { + dol_syslog("Refused to delete file ".$file, LOG_WARNING); + return False; + } + if (empty($nohook)) { $hookmanager->initHooks(array('fileslib')); From 277fa7dbe16fe37fc1f3553bb844276ec4a8ac91 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 14:08:53 +0100 Subject: [PATCH 045/410] FIX #6444 --- htdocs/core/lib/files.lib.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 664c2e0a03d..c7cc2687463 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1139,6 +1139,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable * @param int $nohook Disable all hooks * @param object $object Current object in use * @return boolean True if no error (file is deleted or if glob is used and there's nothing to delete), False if error + * @see dol_delete_dir */ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=null) { @@ -1151,8 +1152,8 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n dol_syslog("dol_delete_file file=".$file." disableglob=".$disableglob." nophperrors=".$nophperrors." nohook=".$nohook); // Security: - // We refuse cache files/dirs, upload using .. and pipes into filenames. - if (preg_match('/^\./',$file) || preg_match('/\.\./',$file) || preg_match('/[<>|]/',$file)) + // We refuse transversal using .. and pipes into filenames. + if (preg_match('/\.\./',$file) || preg_match('/[<>|]/',$file)) { dol_syslog("Refused to delete file ".$file, LOG_WARNING); return False; @@ -1222,9 +1223,18 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n * @param string $dir Directory to delete * @param int $nophperrors Disable all PHP output errors * @return boolean True if success, false if error + * @see dol_delete_file */ function dol_delete_dir($dir,$nophperrors=0) { + // Security: + // We refuse transversal using .. and pipes into filenames. + if (preg_match('/\.\./',$dir) || preg_match('/[<>|]/',$dir)) + { + dol_syslog("Refused to delete dir ".$dir, LOG_WARNING); + return False; + } + $dir_osencoded=dol_osencode($dir); return ($nophperrors?@rmdir($dir_osencoded):rmdir($dir_osencoded)); } From 135358780cbae665e6de61aaaf59113254f4c06b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 14:48:26 +0100 Subject: [PATCH 046/410] FIX #6445 --- htdocs/core/login/functions_dolibarr.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/login/functions_dolibarr.php b/htdocs/core/login/functions_dolibarr.php index ee162bd9cc8..daf82b2f995 100644 --- a/htdocs/core/login/functions_dolibarr.php +++ b/htdocs/core/login/functions_dolibarr.php @@ -47,7 +47,7 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= { dol_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest." passwordtotest=".preg_replace('/./','*',$passwordtotest)." entitytotest=".$entitytotest); - // If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko + // If test username/password asked, we define $test=false if ko and $login var to login if ok, set also $_SESSION["dol_loginmesg"] if ko $table = MAIN_DB_PREFIX."user"; $usernamecol1 = 'login'; $usernamecol2 = 'email'; @@ -59,6 +59,9 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= if (preg_match('/@/',$usertotest)) $sql.=' OR '.$usernamecol2." = '".$db->escape($usertotest)."'"; $sql.=') AND '.$entitycol." IN (0," . ($entity ? $entity : 1) . ")"; $sql.=' AND statut = 1'; + // Required to first found the user into entity, then the superadmin. + // For the case (TODO and that we must avoid) a user has renamed its login with same value than a user in entity 0. + $sql.=' ORDER BY entity DESC'; $resql=$db->query($sql); if ($resql) From c3179963ca3079a53141a1fd4e27a2a5dd817e18 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 14:59:57 +0100 Subject: [PATCH 047/410] Fix search fails under certain circumstances. --- htdocs/admin/modules.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 341cdd00ebc..d4e9b8b7ea0 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -390,6 +390,7 @@ if ($mode != 'marketplace') // Check filters $modulename=$objMod->getName(); + $moduletechnicalname=$objMod->name; $moduledesc=$objMod->getDesc(); $moduledesclong=$objMod->getDescLong(); $moduleauthor=$objMod->getPublisher(); @@ -399,6 +400,7 @@ if ($mode != 'marketplace') { $qualified=0; if (preg_match('/'.preg_quote($search_keyword).'/i', $modulename) + || preg_match('/'.preg_quote($search_keyword).'/i', $moduletechnicalname) || preg_match('/'.preg_quote($search_keyword).'/i', $moduledesc) || preg_match('/'.preg_quote($search_keyword).'/i', $moduledesclong) || preg_match('/'.preg_quote($search_keyword).'/i', $moduleauthor) From 8f338a155a5a8d1d1063b17e8fadbebbee8989bd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 15:19:15 +0100 Subject: [PATCH 048/410] Fix last_insert_id at a better place --- htdocs/core/db/Database.interface.php | 2 +- htdocs/core/modules/import/import_csv.modules.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php index ab38cdf378c..28623f780a5 100644 --- a/htdocs/core/db/Database.interface.php +++ b/htdocs/core/db/Database.interface.php @@ -195,7 +195,7 @@ interface Database * Execute a SQL request and return the resultset * * @param string $query SQL query string - * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollbock to savepoint if error (this allow to have some request with errors inside global transactions). + * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollback to savepoint if error (this allow to have some request with errors inside global transactions). * Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints. * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) * @return resource Resultset of answer diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 3e3ec91dd60..96f0dca04fa 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -588,9 +588,9 @@ class ImportCsv extends ModeleImports { $updatedone = false; $insertdone = false; - if(!empty($updatekeys)) { + if (!empty($updatekeys)) { // We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields) - if(empty($lastinsertid)) { + if (empty($lastinsertid)) { $sqlSelect = 'SELECT rowid FROM '.$tablename; $data = array_combine($listfields, $listvalues); @@ -627,7 +627,7 @@ class ImportCsv extends ModeleImports } } - if(!empty($lastinsertid)) { + if (!empty($lastinsertid)) { // Build SQL UPDATE request $sqlstart = 'UPDATE '.$tablename; @@ -660,7 +660,7 @@ class ImportCsv extends ModeleImports } // Update not done, we do insert - if(!$error && !$updatedone) { + if (!$error && !$updatedone) { // Build SQL INSERT request $sqlstart = 'INSERT INTO '.$tablename.'('.implode(', ', $listfields).', import_key'; $sqlend = ') VALUES('.implode(', ', $listvalues).", '".$importid."'"; @@ -679,10 +679,10 @@ class ImportCsv extends ModeleImports if ($sql) { $resql=$this->db->query($sql); - $last_insert_id_array[$tablename] = $this->db->last_insert_id($tablename); // store the last inserted auto_increment id for each table, so that dependent tables can be inserted with the appropriate id. This must be done just after the INSERT request, else we risk losing the id (because another sql query will be issued somewhere in Dolibarr). if ($resql) { - $insertdone = true; + $last_insert_id_array[$tablename] = $this->db->last_insert_id($tablename); // store the last inserted auto_increment id for each table, so that child tables can be inserted with the appropriate id. This must be done just after the INSERT request, else we risk losing the id (because another sql query will be issued somewhere in Dolibarr). + $insertdone = true; } else { From 57c297117517f961d1903e11b85534dba270dbfd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 16:19:18 +0100 Subject: [PATCH 049/410] Fix dol_banner for agenda --- htdocs/core/class/html.form.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 0bb01da357d..3a99965e301 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5851,7 +5851,13 @@ class Form { $ret.=dol_htmlentities($object->getFullName($langs)); } + else if (in_array($object->element, array('action', 'agenda'))) + { + $ret.=$object->label; + } else if ($fieldref != 'none') $ret.=dol_htmlentities($object->$fieldref); + + if ($morehtmlref) { $ret.=' '.$morehtmlref; From 618c27d63c7ecfffc22404fe95dea5d72edb42bb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 16:26:43 +0100 Subject: [PATCH 050/410] Optimize space --- htdocs/comm/action/index.php | 24 +++++++++++++++++------- htdocs/core/lib/functions.lib.php | 14 ++++++++++---- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index f8b50fb588a..25d410e7bdb 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1353,7 +1353,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '
      '; // always 1 li per ul, 1 ul per event print '
    • '; print '
    '; } if (! empty($head['text'])) { diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 0a802475f01..5d03c087f06 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -577,13 +577,13 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } -.tdoverflowmax100 { +.tdoverflowmax100 { /* For tdoverflow, the max-midth become a minimum ! */ max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.tdoverflowmax300 { +.tdoverflowmax300 { /* For tdoverflow, the max-midth become a minimum ! */ max-width: 300px; overflow: hidden; text-overflow: ellipsis; From 80702e4c0a63ad7a7e79127a575cd9f058e4dc16 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 11:22:27 +0100 Subject: [PATCH 034/410] Fix Better HTML5 compliant --- htdocs/core/boxes/box_actions.php | 8 +++--- htdocs/core/boxes/box_activity.php | 26 +++++++++---------- htdocs/core/boxes/box_bookmarks.php | 4 +-- htdocs/core/boxes/box_clients.php | 6 ++--- htdocs/core/boxes/box_commandes.php | 12 ++++----- htdocs/core/boxes/box_comptes.php | 10 +++---- htdocs/core/boxes/box_contacts.php | 8 +++--- htdocs/core/boxes/box_contracts.php | 12 ++++----- htdocs/core/boxes/box_external_rss.php | 2 +- htdocs/core/boxes/box_factures.php | 12 ++++----- htdocs/core/boxes/box_factures_fourn.php | 14 +++++----- htdocs/core/boxes/box_factures_fourn_imp.php | 12 ++++----- htdocs/core/boxes/box_factures_imp.php | 12 ++++----- htdocs/core/boxes/box_ficheinter.php | 10 +++---- htdocs/core/boxes/box_fournisseurs.php | 8 +++--- htdocs/core/boxes/box_goodcustomers.php | 8 +++--- .../boxes/box_graph_invoices_permonth.php | 2 +- .../box_graph_invoices_supplier_permonth.php | 2 +- .../core/boxes/box_graph_orders_permonth.php | 2 +- .../box_graph_orders_supplier_permonth.php | 2 +- .../boxes/box_graph_propales_permonth.php | 2 +- htdocs/core/boxes/box_members.php | 8 +++--- htdocs/core/boxes/box_produits.php | 12 ++++----- .../core/boxes/box_produits_alerte_stock.php | 10 +++---- htdocs/core/boxes/box_project.php | 14 +++++----- htdocs/core/boxes/box_propales.php | 12 ++++----- htdocs/core/boxes/box_prospect.php | 8 +++--- htdocs/core/boxes/box_services_contracts.php | 4 +-- htdocs/core/boxes/box_services_expired.php | 8 +++--- htdocs/core/boxes/box_supplier_orders.php | 12 ++++----- htdocs/core/boxes/box_task.php | 10 +++---- 31 files changed, 136 insertions(+), 136 deletions(-) diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php index c406ada6fa5..b6d38d17b53 100644 --- a/htdocs/core/boxes/box_actions.php +++ b/htdocs/core/boxes/box_actions.php @@ -110,14 +110,14 @@ class box_actions extends ModeleBoxes $label = empty($objp->label)?$objp->type_label:$objp->label; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $actionstatic->getNomUrl(1), 'text2'=> $late, 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => ($societestatic->id > 0 ? $societestatic->getNomUrl(1) : ''), 'asis' => 1, ); @@ -128,7 +128,7 @@ class box_actions extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => ($objp->percentage>= 0?$objp->percentage.'%':''), ); @@ -149,7 +149,7 @@ class box_actions extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 34666507488..96a451f70f8 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -148,19 +148,19 @@ class box_activity extends ModeleBoxes ); $this->info_box_contents[$line][1] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(1,$data[$j]->fk_statut,0)." ".$data[$j]->annee, ); $this->info_box_contents[$line][2] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(1,$data[$j]->fk_statut,0), 'text' => $data[$j]->nb, 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", ); $this->info_box_contents[$line][3] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency) ); @@ -230,19 +230,19 @@ class box_activity extends ModeleBoxes ); $this->info_box_contents[$line][1] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), ); $this->info_box_contents[$line][2] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => $data[$j]->nb, 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", ); $totalnb += $data[$j]->nb; $this->info_box_contents[$line][3] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); $totalMnt += $objp->Mnttot; @@ -260,7 +260,7 @@ class box_activity extends ModeleBoxes ); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } @@ -323,12 +323,12 @@ class box_activity extends ModeleBoxes ); $this->info_box_contents[$line][1] = array( - 'td' => 'align="left"', + 'td' => '', 'text' =>$langs->trans("Orders")." ".$commandestatic->LibStatut($data[$j]->fk_statut,0,0), ); $this->info_box_contents[$line][2] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => $data[$j]->nb, 'tooltip' => $langs->trans("Orders")." ".$commandestatic->LibStatut($data[$j]->fk_statut,0,0), 'url' => DOL_URL_ROOT."/commande/list.php?mainmenu=commercial&leftmenu=orders&viewstatut=".$data[$j]->fk_statut, @@ -336,7 +336,7 @@ class box_activity extends ModeleBoxes $totalnb += $data[$j]->nb; $this->info_box_contents[$line][3] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); $totalMnt += $data[$j]->Mnttot; @@ -413,12 +413,12 @@ class box_activity extends ModeleBoxes ); $this->info_box_contents[$line][1] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), ); $this->info_box_contents[$line][2] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => $data[$j]->nb, 'tooltip' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), 'url' => DOL_URL_ROOT."/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&viewstatut=".$data[$j]->fk_statut, @@ -426,7 +426,7 @@ class box_activity extends ModeleBoxes $totalnb += $data[$j]->nb; $this->info_box_contents[$line][3] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); $totalMnt += $data[$j]->Mnttot; diff --git a/htdocs/core/boxes/box_bookmarks.php b/htdocs/core/boxes/box_bookmarks.php index e99a0b30387..b6df56f52a2 100644 --- a/htdocs/core/boxes/box_bookmarks.php +++ b/htdocs/core/boxes/box_bookmarks.php @@ -94,7 +94,7 @@ class box_bookmarks extends ModeleBoxes 'target' => $objp->target?'newtab':'', ); $this->info_box_contents[$line][1] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->title, 'url' => $objp->url, 'tooltip' => $objp->title, @@ -117,7 +117,7 @@ class box_bookmarks extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php index 307dcc7cbfd..0649d43a049 100644 --- a/htdocs/core/boxes/box_clients.php +++ b/htdocs/core/boxes/box_clients.php @@ -117,13 +117,13 @@ class box_clients extends ModeleBoxes $thirdpartystatic->logo = $objp->logo; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $thirdpartystatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datem, "day") ); @@ -140,7 +140,7 @@ class box_clients extends ModeleBoxes $db->free($result); } else { - $this->info_box_contents[0][0] = array( 'td' => 'align="left"', + $this->info_box_contents[0][0] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql)); } diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php index 7653206333d..fe460f7d512 100644 --- a/htdocs/core/boxes/box_commandes.php +++ b/htdocs/core/boxes/box_commandes.php @@ -115,33 +115,33 @@ class box_commandes extends ModeleBoxes $societestatic->logo = $objp->logo; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $commandestatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $societestatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency), ); if (! empty($conf->global->ORDER_BOX_LAST_ORDERS_SHOW_VALIDATE_USER)) { if ($objp->fk_user_valid > 0) $userstatic->fetch($objp->fk_user_valid); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => (($objp->fk_user_valid > 0)?$userstatic->getNomUrl(1):''), 'asis' => 1, ); } $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($date,'day'), ); @@ -158,7 +158,7 @@ class box_commandes extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); diff --git a/htdocs/core/boxes/box_comptes.php b/htdocs/core/boxes/box_comptes.php index a1c3625e78c..2372a31f035 100644 --- a/htdocs/core/boxes/box_comptes.php +++ b/htdocs/core/boxes/box_comptes.php @@ -111,18 +111,18 @@ class box_comptes extends ModeleBoxes $solde_total[$objp->currency_code] += $solde; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $account_static->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->number, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($solde, 0, $langs, 0, -1, -1, $objp->currency_code) ); @@ -151,14 +151,14 @@ class box_comptes extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index 45963af9bb1..d6c38a9fce8 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -110,19 +110,19 @@ class box_contacts extends ModeleBoxes $societestatic->fournisseur = $objp->fournisseur; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $contactstatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => ($objp->fk_soc > 0 ? $societestatic->getNomUrl(1) : ''), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datem, "day"), ); @@ -144,7 +144,7 @@ class box_contacts extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); diff --git a/htdocs/core/boxes/box_contracts.php b/htdocs/core/boxes/box_contracts.php index fe864e1df16..cd436f3eb85 100644 --- a/htdocs/core/boxes/box_contracts.php +++ b/htdocs/core/boxes/box_contracts.php @@ -106,25 +106,25 @@ class box_contracts extends ModeleBoxes // if ($objp->fk_statut == 1 && $dateterm < ($now - $conf->contrat->cloture->warning_delay)) { $late = img_warning($langs->trans("Late")); } $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $contractstatic->getNomUrl(1), 'text2'=> $late, 'asis'=>1 ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', 'text' => $thirdpartytmp->getNomUrl(1), 'asis'=>1 ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datec,'day'), ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right" class="nowrap"', + 'td' => 'class="nowrap right"', 'text' => $contractstatic->getLibStatut(6), 'asis'=>1, ); @@ -141,14 +141,14 @@ class box_contracts extends ModeleBoxes $db->free($resql); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_external_rss.php b/htdocs/core/boxes/box_external_rss.php index dbe71a6ca41..71b643665b3 100644 --- a/htdocs/core/boxes/box_external_rss.php +++ b/htdocs/core/boxes/box_external_rss.php @@ -163,7 +163,7 @@ class box_external_rss extends ModeleBoxes ); $this->info_box_contents[$line][1] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $title, 'url' => $href, 'tooltip' => $tooltip, diff --git a/htdocs/core/boxes/box_factures.php b/htdocs/core/boxes/box_factures.php index 22a90929a0b..b7c9dfa0e91 100644 --- a/htdocs/core/boxes/box_factures.php +++ b/htdocs/core/boxes/box_factures.php @@ -122,25 +122,25 @@ class box_factures extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $facturestatic->getNomUrl(1), 'text2'=> $late, 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $societestatic->getNomUrl(1, '', 40), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency), ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($date,'day'), ); @@ -161,7 +161,7 @@ class box_factures extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); @@ -169,7 +169,7 @@ class box_factures extends ModeleBoxes } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php index b43d9cfc47b..4f88d99bb09 100644 --- a/htdocs/core/boxes/box_factures_fourn.php +++ b/htdocs/core/boxes/box_factures_fourn.php @@ -122,32 +122,32 @@ class box_factures_fourn extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $facturestatic->getNomUrl(1), 'text2'=> $late, 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->ref_supplier, 'tooltip' => $langs->trans('SupplierInvoice').': '.($objp->ref?$objp->ref:$objp->facid).'
    '.$langs->trans('RefSupplier').': '.$objp->ref_supplier, 'url' => DOL_URL_ROOT."/fourn/facture/card.php?facid=".$objp->facid, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $thirdpartytmp->getNomUrl(1, 'supplier'), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency), ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($date,'day'), ); @@ -171,14 +171,14 @@ class box_factures_fourn extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->transnoentities("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php index 0d6bc28f077..3313b4cbd50 100644 --- a/htdocs/core/boxes/box_factures_fourn_imp.php +++ b/htdocs/core/boxes/box_factures_fourn_imp.php @@ -119,25 +119,25 @@ class box_factures_fourn_imp extends ModeleBoxes $tooltip = $langs->trans('SupplierInvoice') . ': ' . ($objp->ref?$objp->ref:$objp->facid) . '
    ' . $langs->trans('RefSupplier') . ': ' . $objp->ref_supplier; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $facturestatic->getNomUrl(1), 'text2'=> $late, 'asis' => 1 ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $thirdpartytmp->getNomUrl(1, '', 40), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency), ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datelimite,'day'), ); @@ -161,14 +161,14 @@ class box_factures_fourn_imp extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_factures_imp.php b/htdocs/core/boxes/box_factures_imp.php index 67c4d4dbfcc..6bd2e662b64 100644 --- a/htdocs/core/boxes/box_factures_imp.php +++ b/htdocs/core/boxes/box_factures_imp.php @@ -126,25 +126,25 @@ class box_factures_imp extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $facturestatic->getNomUrl(1), 'text2'=> $late, 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $societestatic->getNomUrl(1, '', 44), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency), ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datelimite,'day'), ); @@ -163,7 +163,7 @@ class box_factures_imp extends ModeleBoxes else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); @@ -171,7 +171,7 @@ class box_factures_imp extends ModeleBoxes } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_ficheinter.php b/htdocs/core/boxes/box_ficheinter.php index d57a2a991df..9fcd8ec6cd7 100644 --- a/htdocs/core/boxes/box_ficheinter.php +++ b/htdocs/core/boxes/box_ficheinter.php @@ -98,7 +98,7 @@ class box_ficheinter extends ModeleBoxes 'logo' => $this->boximg, 'url' => DOL_URL_ROOT."/fichinter/card.php?id=".$objp->rowid); - $this->info_box_contents[$i][1] = array('td' => 'align="left"', + $this->info_box_contents[$i][1] = array('td' => '', 'text' => ($objp->ref?$objp->ref:$objp->rowid), // Some interventions have no ref 'url' => DOL_URL_ROOT."/fichinter/card.php?id=".$objp->rowid); @@ -106,11 +106,11 @@ class box_ficheinter extends ModeleBoxes 'logo' => 'company', 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); - $this->info_box_contents[$i][3] = array('td' => 'align="left"', + $this->info_box_contents[$i][3] = array('td' => '', 'text' => dol_trunc($objp->name,40), 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); - $this->info_box_contents[$i][4] = array('td' => 'align="right"', + $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => dol_print_date($datec,'day')); $this->info_box_contents[$i][5] = array('td' => 'align="right" class="nowrap"', @@ -127,14 +127,14 @@ class box_ficheinter extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array( 'td' => 'align="left"', + $this->info_box_contents[0][0] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql)); } } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } } diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php index ed3680af455..432d34897d0 100644 --- a/htdocs/core/boxes/box_fournisseurs.php +++ b/htdocs/core/boxes/box_fournisseurs.php @@ -94,13 +94,13 @@ class box_fournisseurs extends ModeleBoxes $thirdpartytmp->logo = $objp->logo; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $thirdpartytmp->getNomUrl(1, '', 40), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datem, "day"), ); @@ -120,14 +120,14 @@ class box_fournisseurs extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_goodcustomers.php b/htdocs/core/boxes/box_goodcustomers.php index 552ed92b8a3..73208b1423a 100644 --- a/htdocs/core/boxes/box_goodcustomers.php +++ b/htdocs/core/boxes/box_goodcustomers.php @@ -114,18 +114,18 @@ class box_goodcustomers extends ModeleBoxes $nbimpaye = $objp->nbfact - $objp->nbfactpaye; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $thirdpartystatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datem, "day") ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => $nbfact.( $nbimpaye != 0 ? ' ('.$nbimpaye.')':'') ); @@ -142,7 +142,7 @@ class box_goodcustomers extends ModeleBoxes $db->free($result); } else { - $this->info_box_contents[0][0] = array( 'td' => 'align="left"', + $this->info_box_contents[0][0] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql)); } diff --git a/htdocs/core/boxes/box_graph_invoices_permonth.php b/htdocs/core/boxes/box_graph_invoices_permonth.php index e4639070203..d313d10b310 100644 --- a/htdocs/core/boxes/box_graph_invoices_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_permonth.php @@ -255,7 +255,7 @@ class box_graph_invoices_permonth extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } } diff --git a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php index 254195b42f1..ddc51aa79fe 100644 --- a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php @@ -252,7 +252,7 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } } diff --git a/htdocs/core/boxes/box_graph_orders_permonth.php b/htdocs/core/boxes/box_graph_orders_permonth.php index 6b023b9c157..0d3077a82ce 100644 --- a/htdocs/core/boxes/box_graph_orders_permonth.php +++ b/htdocs/core/boxes/box_graph_orders_permonth.php @@ -253,7 +253,7 @@ class box_graph_orders_permonth extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } } diff --git a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php index 646f28e949c..d16bfbc0f90 100644 --- a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php @@ -252,7 +252,7 @@ class box_graph_orders_supplier_permonth extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } } diff --git a/htdocs/core/boxes/box_graph_propales_permonth.php b/htdocs/core/boxes/box_graph_propales_permonth.php index 39fe12ed7a3..2a29cf27314 100644 --- a/htdocs/core/boxes/box_graph_propales_permonth.php +++ b/htdocs/core/boxes/box_graph_propales_permonth.php @@ -254,7 +254,7 @@ class box_graph_propales_permonth extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } } diff --git a/htdocs/core/boxes/box_members.php b/htdocs/core/boxes/box_members.php index afcbe8e68a6..1bbcec45881 100644 --- a/htdocs/core/boxes/box_members.php +++ b/htdocs/core/boxes/box_members.php @@ -117,19 +117,19 @@ class box_members extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $memberstatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $memberstatic->getFullName($langs), 'url' => DOL_URL_ROOT."/adherents/card.php?rowid=".$objp->rowid, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datem, "day"), ); @@ -150,7 +150,7 @@ class box_members extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 5cce3254bfb..10ec22ce5f5 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -106,13 +106,13 @@ class box_produits extends ModeleBoxes $productstatic->entity = $objp->entity; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $productstatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->label, ); @@ -139,7 +139,7 @@ class box_produits extends ModeleBoxes } } $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => $price, ); @@ -149,7 +149,7 @@ class box_produits extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datem,'day'), ); @@ -174,14 +174,14 @@ class box_produits extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php index 3ec0fc7070c..1367caed866 100644 --- a/htdocs/core/boxes/box_produits_alerte_stock.php +++ b/htdocs/core/boxes/box_produits_alerte_stock.php @@ -113,13 +113,13 @@ class box_produits_alerte_stock extends ModeleBoxes $productstatic->entity = $objp->entity; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $productstatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->label, ); @@ -148,7 +148,7 @@ class box_produits_alerte_stock extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => $price, ); @@ -180,7 +180,7 @@ class box_produits_alerte_stock extends ModeleBoxes else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); @@ -188,7 +188,7 @@ class box_produits_alerte_stock extends ModeleBoxes } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index 4c0689cd282..c2cc1cb041b 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -104,14 +104,14 @@ class box_project extends ModeleBoxes ); $this->info_box_contents[$i][1] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->ref, 'tooltip' => $tooltip, 'url' => DOL_URL_ROOT."/projet/card.php?id=".$objp->rowid, ); $this->info_box_contents[$i][2] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->title, ); @@ -123,20 +123,20 @@ class box_project extends ModeleBoxes if ($resultTask) { $objTask = $db->fetch_object($resultTask); $this->info_box_contents[$i][3] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => number_format($objTask->nb, 0, ',', ' ')." ".$langs->trans("Tasks"), ); if ($objTask->nb > 0 ) $this->info_box_contents[$i][4] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => number_format(($objTask->totprogress/$objTask->nb), 0, ',', ' ')."%", ); else - $this->info_box_contents[$i][4] = array('td' => 'align="right"', 'text' => "N/A "); + $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); $totalnbTask += $objTask->nb; } else { - $this->info_box_contents[$i][3] = array('td' => 'align="right"', 'text' => number_format(0, 0, ',', ' ')); - $this->info_box_contents[$i][4] = array('td' => 'align="right"', 'text' => "N/A "); + $this->info_box_contents[$i][3] = array('td' => 'class="right"', 'text' => number_format(0, 0, ',', ' ')); + $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); } $i++; diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index b0a1e4a3798..d3945ddb940 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -109,25 +109,25 @@ class box_propales extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $propalstatic->getNomUrl(1), 'text2'=> $late, 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $societestatic->getNomUrl(1,'',40), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency), ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($date,'day'), ); @@ -148,14 +148,14 @@ class box_propales extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php index 40adb98b405..1acd77addfc 100644 --- a/htdocs/core/boxes/box_prospect.php +++ b/htdocs/core/boxes/box_prospect.php @@ -117,13 +117,13 @@ class box_prospect extends ModeleBoxes $thirdpartystatic->logo = $objp->logo; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $thirdpartystatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($datem, "day"), ); @@ -149,14 +149,14 @@ class box_prospect extends ModeleBoxes $db->free($resql); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 752509a0616..b33079d2ab0 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -155,13 +155,13 @@ class box_services_contracts extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array( 'td' => 'align="left"', + $this->info_box_contents[0][0] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql)); } } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index 90f36ef6d30..2754a4cece6 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -98,7 +98,7 @@ class box_services_expired extends ModeleBoxes 'logo' => $this->boximg, 'url' => DOL_URL_ROOT."/contrat/card.php?id=".$objp->rowid); - $this->info_box_contents[$i][1] = array('td' => 'align="left"', + $this->info_box_contents[$i][1] = array('td' => '', 'text' => ($objp->ref?$objp->ref:$objp->rowid), // Some contracts have no ref 'url' => DOL_URL_ROOT."/contrat/card.php?id=".$objp->rowid); @@ -114,7 +114,7 @@ class box_services_expired extends ModeleBoxes 'text' => dol_print_date($dateline,'day'), 'text2'=> $late); - $this->info_box_contents[$i][5] = array('td' => 'align="right"', + $this->info_box_contents[$i][5] = array('td' => 'class="right"', 'text' => $objp->nb_services); @@ -131,7 +131,7 @@ class box_services_expired extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array( 'td' => 'align="left"', + $this->info_box_contents[0][0] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql)); } @@ -140,7 +140,7 @@ class box_services_expired extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array('td' => 'align="left"', + $this->info_box_contents[0][0] = array('td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed")); } } diff --git a/htdocs/core/boxes/box_supplier_orders.php b/htdocs/core/boxes/box_supplier_orders.php index 1f0e1ece2ef..29b6009b367 100644 --- a/htdocs/core/boxes/box_supplier_orders.php +++ b/htdocs/core/boxes/box_supplier_orders.php @@ -112,25 +112,25 @@ class box_supplier_orders extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $objp->ref, 'tooltip' => $tooltip, 'url' => $urlo, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $thirdpartytmp->getNomUrl(1, 'supplier'), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency), ); $this->info_box_contents[$line][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => dol_print_date($date,'day'), ); @@ -151,7 +151,7 @@ class box_supplier_orders extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); @@ -160,7 +160,7 @@ class box_supplier_orders extends ModeleBoxes else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php index 29dd9390597..ed02e2fc6eb 100644 --- a/htdocs/core/boxes/box_task.php +++ b/htdocs/core/boxes/box_task.php @@ -99,19 +99,19 @@ class box_task extends ModeleBoxes { $objp = $db->fetch_object($result); $this->info_box_contents[$i][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' =>$langs->trans("Task")." ".$taskstatic->LibStatut($objp->fk_statut,0), ); $this->info_box_contents[$i][] = array( - 'td' => 'align="right"', + 'td' => 'class="right"', 'text' => $objp->nb." ".$langs->trans("Tasks"), 'url' => DOL_URL_ROOT."/projet/tasks/list.php?leftmenu=projects&viewstatut=".$objp->fk_statut, ); $totalnb += $objp->nb; - $this->info_box_contents[$i][] = array('td' => 'align="right"', 'text' => ConvertSecondToTime($objp->plannedtot,'all',25200,5)); + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => ConvertSecondToTime($objp->plannedtot,'all',25200,5)); $totalplannedtot += $objp->plannedtot; - $this->info_box_contents[$i][] = array('td' => 'align="right"', 'text' => ConvertSecondToTime($objp->durationtot,'all',25200,5)); + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => ConvertSecondToTime($objp->durationtot,'all',25200,5)); $totaldurationtot += $objp->durationtot; $this->info_box_contents[$i][] = array('td' => 'align="right" width="18"', 'text' => $taskstatic->LibStatut($objp->fk_statut,3)); @@ -124,7 +124,7 @@ class box_task extends ModeleBoxes // Add the sum à the bottom of the boxes - $this->info_box_contents[$i][] = array('tr' => 'class="liste_total"', 'td' => 'align="left"', 'text' => $langs->trans("Total")." ".$textHead); + $this->info_box_contents[$i][] = array('tr' => 'class="liste_total"', 'td' => '', 'text' => $langs->trans("Total")." ".$textHead); $this->info_box_contents[$i][] = array('td' => 'align="right" ', 'text' => number_format($totalnb, 0, ',', ' ')." ".$langs->trans("Tasks")); $this->info_box_contents[$i][] = array('td' => 'align="right" ', 'text' => ConvertSecondToTime($totalplannedtot,'all',25200,5)); $this->info_box_contents[$i][] = array('td' => 'align="right" ', 'text' => ConvertSecondToTime($totaldurationtot,'all',25200,5)); From 46eedeafe82073253709d07eb166915078f8c7fd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 11:30:46 +0100 Subject: [PATCH 035/410] Fix message shown to many times --- htdocs/core/ajax/box.php | 5 ++++- htdocs/core/class/html.formother.class.php | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/core/ajax/box.php b/htdocs/core/ajax/box.php index be4d9231c5f..fbb8fc759ad 100644 --- a/htdocs/core/ajax/box.php +++ b/htdocs/core/ajax/box.php @@ -73,7 +73,10 @@ if ($boxorder && $zone != '' && $userid > 0) if ($result > 0) { $langs->load("boxes"); - setEventMessages($langs->trans("BoxAdded"), null); + if (empty(GETPOST('closing'))) + { + setEventMessages($langs->trans("BoxAdded"), null); + } } } diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index bcad9dbac44..5f8fe76e320 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -1046,7 +1046,7 @@ class FormOther if (boxorder==\'A:A-B:B\' && closing == 1) // There is no more boxes on screen, and we are after a delete of a box so we must hide title { jQuery.ajax({ - url: \''.DOL_URL_ROOT.'/core/ajax/box.php?boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.', + url: \''.DOL_URL_ROOT.'/core/ajax/box.php?closing=\'+closing+\'&boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.', async: false }); // We force reload to be sure to get all boxes into list @@ -1055,7 +1055,7 @@ class FormOther else { jQuery.ajax({ - url: \''.DOL_URL_ROOT.'/core/ajax/box.php?boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.', + url: \''.DOL_URL_ROOT.'/core/ajax/box.php?closing=\'+closing+\'&boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.', async: true }); } From fda84995e87a1fb1c0540a7854169cb1951c9448 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 11:50:57 +0100 Subject: [PATCH 036/410] If manage zero is set, we must NOT set length. So we can here make a shortcut to avoid useless code. --- htdocs/accountancy/admin/index.php | 9 +++++++-- htdocs/admin/index.php | 2 +- htdocs/core/lib/accounting.lib.php | 6 ++++-- htdocs/langs/en_US/accountancy.lang | 6 +++--- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 85c290eef7f..74479a9d39f 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -87,7 +87,8 @@ if ($action == 'update') { setEventMessages($langs->trans("Error"), null, 'errors'); } - foreach ($list as $constname) { + foreach ($list as $constname) + { $constvalue = GETPOST($constname, 'alpha'); if (! dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { @@ -278,13 +279,17 @@ foreach ($list as $key) $var = ! $var; print '
    '.$label.''; - print ''; + print ''; print '
    '; @@ -1413,7 +1413,9 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa { $savlabel=$event->libelle; $event->libelle=$daterange; + //print ''; print $event->getNomUrl(0); + //print ''; $event->libelle=$savlabel; } else @@ -1421,7 +1423,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print $daterange; } //print ' '; - print "
    \n"; + print " "; } else { @@ -1535,14 +1537,22 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa * Change color with a delta * * @param string $color Color - * @param int $minus Delta + * @param int $minus Delta (1 = 16 unit) + * @param int $minusunit Minus unit * @return string New color */ -function dol_color_minus($color, $minus) +function dol_color_minus($color, $minus, $minusunit = 16) { $newcolor=$color; - $newcolor[0]=((hexdec($newcolor[0])-$minus)<0)?0:dechex((hexdec($newcolor[0])-$minus)); - $newcolor[2]=((hexdec($newcolor[2])-$minus)<0)?0:dechex((hexdec($newcolor[2])-$minus)); - $newcolor[4]=((hexdec($newcolor[4])-$minus)<0)?0:dechex((hexdec($newcolor[4])-$minus)); + if ($minusunit == 16) + { + $newcolor[0]=dechex(max(min(hexdec($newcolor[0])-$minus, 15), 0)); + $newcolor[2]=dechex(max(min(hexdec($newcolor[2])-$minus, 15), 0)); + $newcolor[4]=dechex(max(min(hexdec($newcolor[4])-$minus, 15), 0)); + } + else + { + // Not yet implemented + } return $newcolor; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6a0ffad4149..0c19d216164 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1047,9 +1047,15 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r } } } + if ($showbarcode) $morehtmlleft.='
    '.$form->showbarcode($object).'
    '; - if ($object->element == 'societe' && ! empty($conf->use_javascript_ajax) && $user->rights->societe->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) { - $morehtmlstatus.=ajax_object_onoff($object, 'status', 'status', 'InActivity', 'ActivityCeased'); + + if ($object->element == 'societe') + { + if (! empty($conf->use_javascript_ajax) && $user->rights->societe->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) + { + $morehtmlstatus.=ajax_object_onoff($object, 'status', 'status', 'InActivity', 'ActivityCeased'); + } } elseif ($object->element == 'product') { @@ -1099,9 +1105,9 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r if ($object->element == 'product' || $object->element == 'bank_account') { - if(! empty($object->label)) $morehtmlref.='
    '.$object->label.'
    '; + if (! empty($object->label)) $morehtmlref.='
    '.$object->label.'
    '; } - + if ($object->element != 'product' && $object->element != 'bookmark') { $morehtmlref.='
    '; From a9b39f302812465c5cb4ca4c0b17a80f9ac79472 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 16:19:18 +0100 Subject: [PATCH 051/410] Fix dol_banner for agenda --- htdocs/core/class/html.form.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 51d24f7c729..9a5aadd2148 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5745,7 +5745,13 @@ class Form { $ret.=dol_htmlentities($object->getFullName($langs)); } + else if (in_array($object->element, array('action', 'agenda'))) + { + $ret.=$object->label; + } else if ($fieldref != 'none') $ret.=dol_htmlentities($object->$fieldref); + + if ($morehtmlref) { $ret.=' '.$morehtmlref; From 2a3d3b4b50cac7d5e843bbf74e03fd60cf1fea08 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 16:40:38 +0100 Subject: [PATCH 052/410] Fix dol_banner for agenda --- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/tpl/resource_add.tpl.php | 2 +- htdocs/theme/eldy/style.css.php | 10 ++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9a5aadd2148..60ff30c6433 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5747,7 +5747,7 @@ class Form } else if (in_array($object->element, array('action', 'agenda'))) { - $ret.=$object->label; + $ret.=$object->ref.'
    '.$object->label; } else if ($fieldref != 'none') $ret.=dol_htmlentities($object->$fieldref); diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index 97cb933bcf7..68fccf6e540 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -8,7 +8,7 @@ $formresources = new FormResource($db); $out = '
    '; -$out .= '
    '; +$out .= ''; $out .= ''; $out .= ''; $out .= ''; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 5d03c087f06..7c699c31e7f 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2742,11 +2742,12 @@ div.pagination li.paginationafterarrows { } */ + /* Set the color for hover lines */ .odd:hover, .impair:hover, .even:hover, .pair:hover, .even:hover, .pair:hover, table.dataTable tr.even:hover, table.dataTable tr.odd:hover, .box_pair:hover, .box_impair:hover { - background: rgb() !important; + background-color: rgb() !important; } @@ -2757,10 +2758,10 @@ div.pagination li.paginationafterarrows { color: #202020; min-height: 18px; /* seems to not be used */ - background: #; + background-color: #; } #GanttChartDIV { - background: #; + background-color: #; } .even, .pair, .nohover .even:hover, .nohover .pair:hover, tr.even td.nohover, tr.pair td.nohover { @@ -2776,13 +2777,14 @@ table.dataTable tr.odd { } /* For no hover style */ -table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td { +table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td, form.nohover, form.nohover:hover { background-color: # !important; } tr.nohoverpair td { background-color: # !important; } + table.dataTable td { padding: 5px 2px 5px 3px !important; } From b6bdd985997bbb7be6839212ff5e5fd61a2ad27b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 16:44:30 +0100 Subject: [PATCH 053/410] Fix css --- htdocs/core/tpl/resource_add.tpl.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index 68fccf6e540..b521445701b 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -6,7 +6,7 @@ require_once(DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'); $form = new Form($db); $formresources = new FormResource($db); -$out = '
    '; +$out = '
    '; $out .= ''; $out .= ''; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index df3e374b565..4c5016268a8 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2648,7 +2648,7 @@ table.dataTable tr.odd { } /* For no hover style */ -table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td { +table.nohover tr.impair, table.nohover tr.pair, table.nohover tr.impair td, table.nohover tr.pair td, tr.nohover td, form.nohover, form.nohover:hover { background-color: # !important; } tr.nohoverpair td { From 209bd0b3e4cd7c09cf4794c70f88ebe18af2cc80 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Mar 2017 16:53:26 +0100 Subject: [PATCH 054/410] 2nd try to fix better compatibility --- htdocs/core/class/commonobject.class.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 2fc6d22fd62..7b812e7ee36 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1223,11 +1223,11 @@ abstract class CommonObject * @param int $id To force other object id (should not be used) * @param string $format Data format ('text', 'date'). 'text' is used if not defined * @param string $id_field To force rowid field name. 'rowid' is used if not defined - * @param User|string $user Update last update fields also if user object provided. If not provided, current user is used. + * @param User|string $fuser Update the user of last update field with this user. If not provided, current user is used except if value is 'none' * @param string $trigkey Trigger key to run (in most cases something like 'XXX_MODIFY') * @return int <0 if KO, >0 if OK */ - function setValueFrom($field, $value, $table='', $id=null, $format='', $id_field='', $user='', $trigkey='') + function setValueFrom($field, $value, $table='', $id=null, $format='', $id_field='', $fuser=null, $trigkey='') { global $user,$langs,$conf; @@ -1247,7 +1247,8 @@ abstract class CommonObject if ($format == 'text') $sql.= $field." = '".$this->db->escape($value)."'"; else if ($format == 'int') $sql.= $field." = ".$this->db->escape($value); else if ($format == 'date') $sql.= $field." = ".($value ? "'".$this->db->idate($value)."'" : "null"); - if (empty($user) && is_object($user)) $sql.=", fk_user_modif = ".$user->id; + if (! empty($fuser) && is_object($fuser)) $sql.=", fk_user_modif = ".$fuser->id; + elseif (empty($fuser) || $fuser != 'none') $sql.=", fk_user_modif = ".$user->id; $sql.= " WHERE ".$id_field." = ".$id; dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG); @@ -1256,7 +1257,7 @@ abstract class CommonObject { if ($trigkey) { - $result=$this->call_trigger($trigkey, $user); // This may set this->errors + $result=$this->call_trigger($trigkey, (! empty($fuser) && is_object($fuser)) ? $fuser : $user); // This may set this->errors if ($result < 0) $error++; } From 29c66b43a34d2933b619f8df3a0517dd639311a0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 00:07:14 +0100 Subject: [PATCH 055/410] Fix responsive --- htdocs/core/lib/company.lib.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 2e809fa6c3b..b010f8143b4 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -531,6 +531,7 @@ function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelin print "\n"; print load_fiche_titre($langs->trans("ProjectsDedicatedToThisThirdParty"),$buttoncreate,''); + print '
    '; print "\n".'
    '; $sql = "SELECT p.rowid as id, p.title, p.ref, p.public, p.dateo as do, p.datee as de, p.fk_statut as status"; @@ -597,7 +598,8 @@ function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelin dol_print_error($db); } print "
    "; - + print ''; + print "
    \n"; } From c0b3219c7258e7f6ee2ed65c8b6b798a797e6a7f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 00:33:04 +0100 Subject: [PATCH 056/410] Missing translation --- htdocs/langs/en_US/loan.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/loan.lang b/htdocs/langs/en_US/loan.lang index de0a6fd0295..a26e23bbbc2 100644 --- a/htdocs/langs/en_US/loan.lang +++ b/htdocs/langs/en_US/loan.lang @@ -43,6 +43,7 @@ LoanCalcDesc=This mortgage calculator can be used to figure out monthly p GoToInterest=%s will go towards INTEREST GoToPrincipal=%s will go towards PRINCIPAL YouWillSpend=You will spend %s in year %s +AddLoan=Create loan # Admin ConfigLoan=Configuration of the module loan LOAN_ACCOUNTING_ACCOUNT_CAPITAL=Accounting account capital by default From 5033c6ea99bffa1648db1aad5b55716c303fa248 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 00:35:39 +0100 Subject: [PATCH 057/410] Add hidden constant as this is not common --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 54643ad6780..69dde026c9b 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -406,7 +406,7 @@ $listofreferent=array( 'table'=>'stock_mouvement', 'datefieldname'=>'datem', 'disableamount'=>0, - 'test'=>$conf->stock->enabled && $user->rights->stock->mouvement->lire), + 'test'=>($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))) /* No need for this, available on dedicated tab "Agenda/Events" 'agenda'=>array( 'name'=>"Agenda", From 106d74184c1164f277f9a1ab72ed57caa45bdd35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 00:43:06 +0100 Subject: [PATCH 058/410] CSS change. More information on project list of thirdparty. --- htdocs/core/lib/company.lib.php | 33 ++++++++++++++++--- htdocs/projet/list.php | 5 ++- htdocs/theme/eldy/style.css.php | 58 +++++++++++++++++++-------------- htdocs/theme/md/style.css.php | 40 ++++++++++++++++------- 4 files changed, 94 insertions(+), 42 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 2e809fa6c3b..0e610df00e8 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -533,8 +533,10 @@ function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelin print load_fiche_titre($langs->trans("ProjectsDedicatedToThisThirdParty"),$buttoncreate,''); print "\n".''; - $sql = "SELECT p.rowid as id, p.title, p.ref, p.public, p.dateo as do, p.datee as de, p.fk_statut as status"; + $sql = "SELECT p.rowid as id, p.title, p.ref, p.public, p.dateo as do, p.datee as de, p.fk_statut as status, p.fk_opp_status, p.opp_amount, p.opp_percent, p.tms as date_update, p.budget_amount"; + $sql .= ", cls.code as opp_status_code"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls on p.fk_opp_status = cls.rowid"; $sql .= " WHERE p.fk_soc = ".$object->id; $sql .= " ORDER BY p.dateo DESC"; @@ -544,8 +546,14 @@ function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelin $num = $db->num_rows($result); print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print ''; if ($num > 0) @@ -574,9 +582,24 @@ function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelin // Label print ''; // Date start - print ''; + print ''; // Date end - print ''; + print ''; + // Opp amount + print ''; + // Opp status + print ''; + // Opp percent + print ''; // Status print ''; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 68077621771..35f65b75c2a 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -741,7 +741,7 @@ while ($i < min($num,$limit)) print ''; if (! $i) $totalarray['nbfield']++; } - // Amount + // Opp Amount if (! empty($arrayfields['p.opp_amount']['checked'])) { print ''; if (! $i) $totalarray['nbfield']++; } + // Opp percent if (! empty($arrayfields['p.opp_percent']['checked'])) { print ''; if (! $i) $totalarray['nbfield']++; } + // Budget if (! empty($arrayfields['p.budget_amount']['checked'])) { print '"; } From 2054ce0aab2e7fab9a81fa4544e1cd2baba16136 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 00:50:55 +0100 Subject: [PATCH 060/410] FIX Avoid flash on screen --- htdocs/core/class/html.formprojet.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index a0e37026ff8..571b24bca52 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -597,7 +597,7 @@ class FormProjets if ($num > 0) { $sellist = '"; } From 4737c62394f1a5654f2ade30f71df66953eae6d1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 00:50:55 +0100 Subject: [PATCH 062/410] FIX Avoid flash on screen --- htdocs/core/class/html.formprojet.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index ffce8300a0c..47706d90d7f 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -586,7 +586,7 @@ class FormProjets if ($num > 0) { $sellist = '
    '.$langs->trans("Ref").''.$langs->trans("Name").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").''.$langs->trans("Status").''.$langs->trans("Ref").''.$langs->trans("Name").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").''.$langs->trans("OpportunityAmountShort").''.$langs->trans("OpportunityStatusShort").''.$langs->trans("OpportunityProbabilityShort").''.$langs->trans("Status").'
    '.$obj->title.''.dol_print_date($db->jdate($obj->do),"day").''.dol_print_date($db->jdate($obj->do),"day").''.dol_print_date($db->jdate($obj->de),"day").''.dol_print_date($db->jdate($obj->de),"day").''; + if ($obj->opp_status_code) + { + print price($obj->opp_amount, 1, '', 1, -1, -1, ''); + } + print ''; + if ($obj->opp_status_code) print $langs->trans("OppStatusShort".$obj->opp_status_code); + print ''; + if ($obj->opp_percent) print price($obj->opp_percent, 1, '', 1, 0).'%'; + print ''.$projecttmp->getLibStatut(5).''; @@ -754,6 +754,7 @@ while ($i < min($num,$limit)) if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totaloppfield']=$totalarray['nbfield']; } + // Opp Status if (! empty($arrayfields['p.fk_opp_status']['checked'])) { print ''; @@ -761,6 +762,7 @@ while ($i < min($num,$limit)) print ''; @@ -768,6 +770,7 @@ while ($i < min($num,$limit)) print ''; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index ffb3e7b83f8..5ce9e9515c1 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -100,7 +100,6 @@ $usegradienttop=(isset($conf->global->THEME_ELDY_TOPMENU_BACK1)?0:1); $usegradienttitle=(isset($conf->global->THEME_ELDY_BACKTITLE1)?0:1); $useboldtitle=(isset($conf->global->THEME_ELDY_USEBOLDTITLE)?$conf->global->THEME_ELDY_USEBOLDTITLE:1); $borderwith=2; -$noborderline=0; // Case of option always editable if (! isset($conf->global->THEME_ELDY_BACKBODY)) $conf->global->THEME_ELDY_BACKBODY=$colorbackbody; @@ -273,7 +272,7 @@ input.select2-input { } .select2-choice { border: none; - border-bottom: 1px solid #aaa !important; + border-bottom: 1px solid #ccc !important; } textarea.cke_source:focus @@ -299,15 +298,19 @@ input { input, select { border-bottom: solid 1px rgba(0,0,0,.2); - padding:4px; + padding: 4px; margin-left:0px; margin-bottom:1px; margin-top:1px; - } +} +select { + padding: 4px 4px 4px 1px; +} textarea { border-radius: 0; - border: solid 1px rgba(0,0,0,.3); - border-top:solid 1px rgba(0,0,0,.3); + border-top:solid 1px rgba(0,0,0,.1); + border-left:solid 1px rgba(0,0,0,.1); + border-right:solid 1px rgba(0,0,0,.1); border-bottom:solid 1px rgba(0,0,0,.2); padding:4px; @@ -476,6 +479,9 @@ th .button { .valignbottom { vertical-align: bottom; } +.valigntextbottom { + vertical-align: text-bottom; +} .centpercent { width: 100%; } @@ -919,8 +925,8 @@ div.fiche { div.fiche { - margin-: px; - margin-: dol_optimize_smallscreen)?'12':'6')); ?>px; + margin-: px; + margin-: dol_optimize_smallscreen)?'16':'6')); ?>px; dol_hide_leftmenu) && ! empty($conf->dol_hide_topmenu)) print 'margin-top: 4px;'."\n"; ?> dol_hide_leftmenu)) print 'margin-bottom: 12px;'."\n"; ?> } @@ -1477,10 +1483,6 @@ form#login { -webkit-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); - /*-moz-box-shadow: 3px 2px 20px #CCC; - -webkit-box-shadow: 3px 2px 20px #CCC; - box-shadow: 3px 2px 20px #CCC;*/ - border-radius: 5px; /*border-top:solid 1px rgba(180,180,180,.4); border-left:solid 1px rgba(180,180,180,.4); @@ -2273,9 +2275,6 @@ tr.nocellnopadd td.nobordernopadding, tr.nocellnopadd td.nocellnopadd table.border, table.dataTable, .table-border, .table-border-col, .table-key-border-col, .table-val-border-col, div.border { - - border: 1px solid #E0E0E0; - border-collapse: collapse !important; padding: 1px 2px 1px 3px; /* t r b l */ } @@ -2295,18 +2294,14 @@ div .tdtop { } table.border td, div.border div div.tagtd { - - padding: 2px 2px 2px 2px; - border: 1px solid #E0E0E0; - padding: 3px 2px 3px 2px; - border-bottom: 1px solid #E0E0E0; - - padding: 3px 2px 3px 2px; - /* border: 1px solid #E0E0E0; */ - border-collapse: collapse; } +div.tabBar .fichecenter table.border>tbody>tr>td, div.tabBar .fichecenter div.border div div.tagtd +{ + padding-top: 4px; + border-bottom: 1px solid #E0E0E0; +} td.border, div.tagtable div div.border { border-top: 1px solid #000000; @@ -2854,6 +2849,7 @@ span.dashboardlineko { } .boxtable { margin-bottom: 8px !important; + border-bottom-width: 0 !important; } .tdboxstats { text-align: center; @@ -3910,6 +3906,9 @@ div.dataTables_length select { /* Select2 */ /* ============================================================================== */ +.select2-container .select2-choice { + border-bottom: 1px solid #ccc; +} .select2-container .select2-choice > .select2-chosen { margin-right: 23px; } @@ -3936,7 +3935,7 @@ div.dataTables_length select { border-top: none !important; border-left: none !important; border-right: none !important; - border-bottom: 1px solid #aaa; + border-bottom: 1px solid #ccc; } .select2-drop.select2-drop-above { box-shadow: none !important; @@ -4023,6 +4022,15 @@ a span.select2-chosen .select2-container-multi .select2-choices .select2-search-choice { margin-bottom: 3px; } +.select2-dropdown-open.select2-drop-above .select2-choice, .select2-dropdown-open.select2-drop-above .select2-choices, .select2-container-multi .select2-choices, +.select2-container-multi.select2-container-active .select2-choices +{ + border-bottom: 1px solid #ccc; + border-right: none; + border-top: none; + border-left: 1px solid #ddd; +} + /* Special case for the select2 add widget */ #addbox .select2-container .select2-choice > .select2-chosen { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 96cb8002719..b64ce9e3a89 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -273,7 +273,7 @@ input.select2-input { } .select2-choice { border: none; - border-bottom: 1px solid #aaa !important; + border-bottom: 1px solid #ccc !important; } textarea.cke_source:focus @@ -296,16 +296,22 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla input, select { border-bottom: solid 1px rgba(0,0,0,.2); - padding:4px; margin-left:0px; margin-bottom:1px; margin-top:1px; - } +} +input { + padding:4px; +} +select { + padding:1px; +} textarea { border-radius: 0; - border: solid 1px rgba(0,0,0,.3); - border-top:solid 1px rgba(0,0,0,.3); + border-top:solid 1px rgba(0,0,0,.1); + border-left:solid 1px rgba(0,0,0,.1); + border-right:solid 1px rgba(0,0,0,.1); border-bottom:solid 1px rgba(0,0,0,.2); background-color: #FFF; @@ -481,6 +487,9 @@ th .button { .valignbottom { vertical-align: bottom; } +.valigntextbottom { + vertical-align: text-bottom; +} .centpercent { width: 100%; } @@ -1512,9 +1521,6 @@ form#login { -moz-box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); -webkit-box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); - /*-moz-box-shadow: 3px 2px 20px #CCC; - -webkit-box-shadow: 3px 2px 20px #CCC; - box-shadow: 3px 2px 20px #CCC;*/ border-radius: 4px; border:solid 1px rgba(80,80,80,.4); @@ -2184,9 +2190,7 @@ tr.nocellnopadd td.nobordernopadding, tr.nocellnopadd td.nocellnopadd table.border, table.dataTable, .table-border, .table-border-col, .table-key-border-col, .table-val-border-col, div.border { - border: 1px solid #f4f4f4; - border-collapse: collapse !important; padding: 1px 2px 1px 3px; /* t r b l */ } @@ -2776,6 +2780,7 @@ span.dashboardlineko { } .boxtable { margin-bottom: 8px !important; + border-bottom-width: 0 !important; } .tdboxstats { text-align: center; @@ -3856,6 +3861,9 @@ div.dataTables_length select { /* Select2 */ /* ============================================================================== */ +.select2-container .select2-choice { + border-bottom: 1px solid #ccc; +} .select2-container .select2-choice > .select2-chosen { margin-right: 23px; } @@ -3883,7 +3891,7 @@ div.dataTables_length select { border-top: none !important; border-left: none !important; border-right: none !important; - border-bottom: 1px solid #aaa; + border-bottom: 1px solid #ccc; } .select2-drop.select2-drop-above { box-shadow: none !important; @@ -3970,6 +3978,16 @@ a span.select2-chosen .select2-container-multi .select2-choices .select2-search-choice { margin-bottom: 3px; } +.select2-dropdown-open.select2-drop-above .select2-choice, .select2-dropdown-open.select2-drop-above .select2-choices, .select2-container-multi .select2-choices, +.select2-container-multi.select2-container-active .select2-choices +{ + border-bottom: 1px solid #ccc; + border-right: none; + border-top: none; + border-left: 1px solid #ddd; +} + + /* Special case for the select2 add widget */ #addbox .select2-container .select2-choice > .select2-chosen { From 21189048e7b7efafda508a746ae8fb60120f137e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 00:50:31 +0100 Subject: [PATCH 059/410] FIX choice of category was lost if an error occurs during creation --- htdocs/projet/card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 7c8a3e3a71a..1b0ccb36ed0 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -595,6 +595,7 @@ if ($action == 'create' && $user->rights->projet->creer) // Categories print '
    '.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1); + $arrayselected=GETPOST('categories', 'array'); print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); print "
    '.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1); + $arrayselected=GETPOST('categories', 'array'); print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); print "
    '; // New value From 47dd53abbe322413c3e47926d6719bb7a2d2e633 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 02:36:22 +0100 Subject: [PATCH 064/410] NEW The substitution keys available for emailing edition is now into a popup --- htdocs/comm/mailing/card.php | 18 +++--------------- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/theme/eldy/style.css.php | 9 ++++----- htdocs/theme/md/style.css.php | 3 +-- 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index ea4b21d78be..2ce6a638191 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -846,11 +846,6 @@ else print '
    '; -/* print ''; - print ''; -*/ // Description print ''; - - // Status - /* - print ''; - */ // Nb of distinct emails print ''; @@ -1191,7 +1179,7 @@ else $htmltext.=''; // Print mail content - print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto($langs->trans("AvailableVariables"), $htmltext), 'title_generic'); + print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto($langs->trans("AvailableVariables"), $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'title_generic'); dol_fiche_head(); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 3a99965e301..a427d67ac83 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -447,7 +447,7 @@ class Form else $paramfortooltipimg =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag if ($tooltipon == 1 || $tooltipon == 3) { - $paramfortooltiptd=' class="'.$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'" '; + $paramfortooltiptd=' class="'.($tooltipon == 3 ? 'cursorpointer ' : '').$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'" '; if ($tooltiptrigger == '') $paramfortooltiptd.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td tag to store tooltip else $paramfortooltiptd.=' dolid="'.$tooltiptrigger.'"'; } @@ -524,7 +524,7 @@ class Form elseif ($type == 'warning') $img = img_warning($alt); else $img = img_picto($alt, $type); - return $this->textwithtooltip($text, $htmltext, 2, $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger); + return $this->textwithtooltip($text, $htmltext, ($tooltiptrigger?3:2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger); } /** diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 5ce9e9515c1..e424f65ca3f 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -304,7 +304,7 @@ input, select { margin-top:1px; } select { - padding: 4px 4px 4px 1px; + /* padding: 4px 4px 2px 1px; */ } textarea { border-radius: 0; @@ -387,7 +387,7 @@ fieldset { border: 1px solid #AAAAAA !important; } border-color: #c5c5c5; border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); display: inline-block; - padding: 4px 14px; + padding: 3px 14px; margin-bottom: 0; margin-top: 0; text-align: center; @@ -3942,6 +3942,7 @@ div.dataTables_length select { } .select2-drop.select2-drop-above.select2-drop-active { border-top: 1px solid #ccc; + border-bottom: 1px solid #ccc; } .select2-container-active .select2-choice, .select2-container-active .select2-choices { @@ -3977,8 +3978,6 @@ div.dataTables_length select { } .select2-dropdown-open.select2-drop-above .select2-choice, .select2-dropdown-open.select2-drop-above .select2-choices { background-image: none; - border-left: 1px solid #ccc !important; - border-right: 1px solid #ccc !important; border-radius: 0 !important; } div.select2-drop-above @@ -4025,7 +4024,7 @@ a span.select2-chosen .select2-dropdown-open.select2-drop-above .select2-choice, .select2-dropdown-open.select2-drop-above .select2-choices, .select2-container-multi .select2-choices, .select2-container-multi.select2-container-active .select2-choices { - border-bottom: 1px solid #ccc; + border-bottom: none; border-right: none; border-top: none; border-left: 1px solid #ddd; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b64ce9e3a89..76776e1c41e 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3898,6 +3898,7 @@ div.dataTables_length select { } .select2-drop.select2-drop-above.select2-drop-active { border-top: 1px solid #ccc; + border-bottom: 1px solid #ccc; } .select2-container-active .select2-choice, .select2-container-active .select2-choices { @@ -3933,8 +3934,6 @@ div.dataTables_length select { } .select2-dropdown-open.select2-drop-above .select2-choice, .select2-dropdown-open.select2-drop-above .select2-choices { background-image: none; - border-left: 1px solid #ccc !important; - border-right: 1px solid #ccc !important; border-radius: 0 !important; } div.select2-drop-above From c7713a88392b63be7e304a164cde84d4083b8fce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 03:01:45 +0100 Subject: [PATCH 065/410] CSS --- htdocs/theme/eldy/style.css.php | 14 +++++++------- htdocs/theme/md/style.css.php | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 691513e4231..85fdd49f8ef 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -272,7 +272,7 @@ input.select2-input { } .select2-choice { border: none; - border-bottom: 1px solid #ccc !important; + border-bottom: solid 1px rgba(0,0,0,.1) !important; /* required to avoid to lose bottom line when focus is lost on select2. */ } textarea.cke_source:focus @@ -288,7 +288,7 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla font-family: ; border: none; - border-bottom: 1px solid #C0C0C0; + border-bottom: solid 1px rgba(0,0,0,.1); outline: none; margin: 0px 0px 0px 0px; } @@ -296,7 +296,7 @@ input { line-height: 17px; } input, select { - border-bottom: solid 1px rgba(0,0,0,.2); + border-bottom: solid 1px rgba(0,0,0,.1); padding: 4px; margin-left:0px; @@ -311,7 +311,7 @@ textarea { border-top:solid 1px rgba(0,0,0,.1); border-left:solid 1px rgba(0,0,0,.1); border-right:solid 1px rgba(0,0,0,.1); - border-bottom:solid 1px rgba(0,0,0,.2); + border-bottom:solid 1px rgba(0,0,0,.1); padding:4px; margin-left:0px; @@ -3909,7 +3909,7 @@ div.dataTables_length select { /* ============================================================================== */ .select2-container .select2-choice { - border-bottom: 1px solid #ccc; + border-bottom: solid 1px rgba(0,0,0,.1); } .select2-container .select2-choice > .select2-chosen { margin-right: 23px; @@ -3937,14 +3937,14 @@ div.dataTables_length select { border-top: none !important; border-left: none !important; border-right: none !important; - border-bottom: 1px solid #ccc; + border-bottom: solid 1px rgba(0,0,0,.1); } .select2-drop.select2-drop-above { box-shadow: none !important; } .select2-drop.select2-drop-above.select2-drop-active { border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; + border-bottom: solid 1px rgba(0,0,0,.1); } .select2-container-active .select2-choice, .select2-container-active .select2-choices { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 3917967acef..481c3483724 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -288,13 +288,13 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla font-size: px; font-family: ; border: none; - border-bottom: 1px solid #C0C0C0; + border-bottom: solid 1px rgba(0,0,0,.1); outline: none; margin: 0px 0px 0px 0px; } input, select { - border-bottom: solid 1px rgba(0,0,0,.2); + border-bottom: solid 1px rgba(0,0,0,.1); margin-left:0px; margin-bottom:1px; From 0ff4f7e6949ce945a8870beed633610704bed57d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 03:10:57 +0100 Subject: [PATCH 066/410] Fix translation --- htdocs/langs/en_US/companies.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index ea1c2e805a0..166633ef2ae 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -13,7 +13,7 @@ MenuNewPrivateIndividual=New private individual NewCompany=New company (prospect, customer, supplier) NewThirdParty=New third party (prospect, customer, supplier) CreateDolibarrThirdPartySupplier=Create a third party (supplier) -CreateThirdPartyOnly=Create thirdpary +CreateThirdPartyOnly=Create third party CreateThirdPartyAndContact=Create a third party + a child contact ProspectionArea=Prospection area IdThirdParty=Id third party From aa0db5783ad2973f22f07284a63bda9565f05444 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 03:35:02 +0100 Subject: [PATCH 067/410] Update favorite icon to use standard icon. --- htdocs/theme/eldy/img/object_bookmark.png | Bin 201 -> 326 bytes htdocs/theme/md/img/object_bookmark.png | Bin 201 -> 326 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/htdocs/theme/eldy/img/object_bookmark.png b/htdocs/theme/eldy/img/object_bookmark.png index 39109ef5ee61c102adfab2c4c7378fd83f76c040..42f702a584c43a444d8962c418f95deb2501e607 100644 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh0wlLOK8*rWOiAAEE)4(M`_JqL@;D1TB8wRq zxP?KOkzv*x37{Z*iKnkC`$J}KCI!i2w&NgO*F9YvLnJQuUa<9Y4wPtl_&i2`#mcQ6 zvrM8`E=5KBU>3hVfwhC%psBaO!D4E}&F;Ou9JeAP;<&FXuq{&frX|tq%A*#$@7>%) ziG7Keyw6^dd0KPE_R{rV#|4bBhBS+Yu-_8 zzHz*%t9ohVRr}N*UaMYLY*w}~PdD5rp|!lvI6;90X`wF z|NsAAyLRo~y?c)xJ2qv?lzaE?egFRb`Sa)3u3g)@b?dov=ia}6zjW!+mX?;D>e*9) zx)@7>{DK)Ap4~_Ta%??a978y+Cnp?Ws{raQk(7{NW!*Z>z@XsGy?xc{%*@$QuQsVD wOqE*7y2wcF97|xPYpO$6;LRHmtjnYs7Mk%eyI5Cl1{%cR>FVdQ&MBb@0LwH@(f|Me diff --git a/htdocs/theme/md/img/object_bookmark.png b/htdocs/theme/md/img/object_bookmark.png index 39109ef5ee61c102adfab2c4c7378fd83f76c040..42f702a584c43a444d8962c418f95deb2501e607 100644 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh0wlLOK8*rWOiAAEE)4(M`_JqL@;D1TB8wRq zxP?KOkzv*x37{Z*iKnkC`$J}KCI!i2w&NgO*F9YvLnJQuUa<9Y4wPtl_&i2`#mcQ6 zvrM8`E=5KBU>3hVfwhC%psBaO!D4E}&F;Ou9JeAP;<&FXuq{&frX|tq%A*#$@7>%) ziG7Keyw6^dd0KPE_R{rV#|4bBhBS+Yu-_8 zzHz*%t9ohVRr}N*UaMYLY*w}~PdD5rp|!lvI6;90X`wF z|NsAAyLRo~y?c)xJ2qv?lzaE?egFRb`Sa)3u3g)@b?dov=ia}6zjW!+mX?;D>e*9) zx)@7>{DK)Ap4~_Ta%??a978y+Cnp?Ws{raQk(7{NW!*Z>z@XsGy?xc{%*@$QuQsVD wOqE*7y2wcF97|xPYpO$6;LRHmtjnYs7Mk%eyI5Cl1{%cR>FVdQ&MBb@0LwH@(f|Me From 9cbc5387ef35cf6dbd9883cdec6cb8dfde891941 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 11:41:02 +0100 Subject: [PATCH 068/410] Fix text --- htdocs/langs/en_US/stocks.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 1448ec061a2..f97d95725fa 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -62,7 +62,7 @@ ReStockOnBill=Increase real stocks on suppliers invoices/credit notes validation ReStockOnValidateOrder=Increase real stocks on suppliers orders approbation ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receiving OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses. -StockDiffPhysicTeoric=Explanation for difference between physical and theoretical stock +StockDiffPhysicTeoric=Explanation for difference between physical and virtual stock NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required. DispatchVerb=Dispatch StockLimitShort=Limit for alert From 9d63697d2afea0c146e569b52469e485c5ca69aa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 12:04:01 +0100 Subject: [PATCH 069/410] Fix missing translation --- htdocs/langs/en_US/stocks.lang | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index f97d95725fa..58a71b08857 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -60,7 +60,7 @@ DeStockOnShipment=Decrease real stocks on shipping validation DeStockOnShipmentOnClosing=Decrease real stocks on shipping classification closed ReStockOnBill=Increase real stocks on suppliers invoices/credit notes validation ReStockOnValidateOrder=Increase real stocks on suppliers orders approbation -ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receiving +ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receipt of goods OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses. StockDiffPhysicTeoric=Explanation for difference between physical and virtual stock NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required. @@ -69,7 +69,10 @@ StockLimitShort=Limit for alert StockLimit=Stock limit for alert PhysicalStock=Physical stock RealStock=Real Stock +RealStockDesc=Physical or real stock is the stock you currently have into your internal warehouses/emplacements. +RealStockWillAutomaticallyWhen=The real stock will automatically change according to this rules (see stock module setup to change this): VirtualStock=Virtual stock +VirtualStockDesc=Virtual stock is the stock you will get once all opened pending actions that affect stocks will be closed (supplier order received, customer order shipped, ...) IdWarehouse=Id warehouse DescWareHouse=Description warehouse LieuWareHouse=Localisation warehouse From 4ca634b41c93f2cfed9795e839249457a843301f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 12:04:28 +0100 Subject: [PATCH 070/410] Better look and feel --- htdocs/product/stock/product.php | 95 +++++++------- .../product/stock/tpl/stockcorrection.tpl.php | 11 +- .../product/stock/tpl/stocktransfer.tpl.php | 5 + htdocs/societe/soc.php | 4 +- htdocs/theme/eldy/style.css.php | 52 ++++---- htdocs/theme/md/style.css.php | 1 - htdocs/variants/combinations.php | 120 +++++++++++------- 7 files changed, 160 insertions(+), 128 deletions(-) diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 14cd07ec817..f12316591d0 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -110,7 +110,7 @@ $parameters=array('id'=>$id, 'ref'=>$ref, 'objcanvas'=>$objcanvas); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if($action == 'addlimitstockwarehouse') { +if ($action == 'addlimitstockwarehouse') { $seuil_stock_alerte = GETPOST('seuil_stock_alerte'); $desiredstock = GETPOST('desiredstock'); @@ -625,7 +625,8 @@ if ($id > 0 || $ref) print ''; // Real stock - $text_stock_options = ''; + $text_stock_options = $langs->trans("RealStockDesc").'
    '; + $text_stock_options.= $langs->trans("RealStockWillAutomaticallyWhen").'
    '; $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)?$langs->trans("DeStockOnShipment").'
    ':''); $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)?$langs->trans("DeStockOnValidateOrder").'
    ':''); $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_BILL)?$langs->trans("DeStockOnBill").'
    ':''); @@ -642,57 +643,55 @@ if ($id > 0 || $ref) $stocktheo = price2num($object->stock_theorique, 'MS'); + $found=0; + $helpondiff=''.$langs->trans("StockDiffPhysicTeoric").':
    '; + // Number of customer orders running + if (! empty($conf->commande->enabled)) + { + if ($found) $helpondiff.='
    '; else $found=1; + $helpondiff.=$langs->trans("ProductQtyInCustomersOrdersRunning").': '.$object->stats_commande['qty']; + $result=$object->load_stats_commande(0,'0'); + if ($result < 0) dol_print_error($db,$object->error); + $helpondiff.=' ('.$langs->trans("ProductQtyInDraft").': '.$object->stats_commande['qty'].')'; + } + + // Number of product from customer order already sent (partial shipping) + if (! empty($conf->expedition->enabled)) + { + if ($found) $helpondiff.='
    '; else $found=1; + $result=$object->load_stats_sending(0,'2'); + $helpondiff.=$langs->trans("ProductQtyInShipmentAlreadySent").': '.$object->stats_expedition['qty']; + } + + // Number of supplier order running + if (! empty($conf->fournisseur->enabled)) + { + if ($found) $helpondiff.='
    '; else $found=1; + $result=$object->load_stats_commande_fournisseur(0,'3,4'); + $helpondiff.=$langs->trans("ProductQtyInSuppliersOrdersRunning").': '.$object->stats_commande_fournisseur['qty']; + $result=$object->load_stats_commande_fournisseur(0,'0,1,2'); + if ($result < 0) dol_print_error($db,$object->error); + $helpondiff.=' ('.$langs->trans("ProductQtyInDraftOrWaitingApproved").': '.$object->stats_commande_fournisseur['qty'].')'; + } + + // Number of product from supplier order already received (partial receipt) + if (! empty($conf->fournisseur->enabled)) + { + if ($found) $helpondiff.='
    '; else $found=1; + $helpondiff.=$langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied").': '.$object->stats_reception['qty']; + } + // Calculating a theorical value - print '
    '; - print "'; + print "'; print ''; - print ''; - print ''; - // Last movement $sql = "SELECT max(m.datem) as datem"; $sql.= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m"; diff --git a/htdocs/product/stock/tpl/stockcorrection.tpl.php b/htdocs/product/stock/tpl/stockcorrection.tpl.php index 757407a6692..28fd3dfadea 100644 --- a/htdocs/product/stock/tpl/stockcorrection.tpl.php +++ b/htdocs/product/stock/tpl/stockcorrection.tpl.php @@ -21,12 +21,14 @@ element == 'product') $productref = $object->ref; $langs->load("productbatch"); - if (empty($id)) $id = $object->id; + + if (empty($id)) $id = $object->id; print ' - - - + '; + print dol_fiche_head(); + + ?> +
    '.$langs->trans("Ref").''; - print $form->showrefnav($object,'id', $linkback); - print '
    '.$form->editfieldkey("MailTitle",'titre',$object->titre,$object,$user->rights->mailing->creer && $object->statut < 3,'string').''; print $form->editfieldval("MailTitle",'titre',$object->titre,$object,$user->rights->mailing->creer && $object->statut < 3,'string'); @@ -865,13 +860,6 @@ else print '
    '.$form->editfieldkey("MailErrorsTo",'email_errorsto',$object->email_errorsto,$object,$user->rights->mailing->creer && $object->statut < 3,'string').''; print $form->editfieldval("MailErrorsTo",'email_errorsto',$object->email_errorsto,$object,$user->rights->mailing->creer && $object->statut < 3,'string'); print '
    '.$langs->trans("Status").''.$object->getLibStatut(4); - if ($object->statut == 2) print ' ('.$object->countNbOfTargets('alreadysent').'/'.$object->nbemail.')'; - print'
    '; @@ -1062,7 +1050,7 @@ else $htmltext.=''; // Print mail content - print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto($langs->trans("AvailableVariables"), $htmltext), 'title_generic'); + print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto($langs->trans("AvailableVariables"), $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'title_generic'); dol_fiche_head(''); @@ -1085,7 +1073,7 @@ else } else { - print $langs->trans("NoAttachedFiles").'
    '; + print ''.$langs->trans("NoAttachedFiles").'
    '; } print '
    '.$langs->trans("VirtualStock").'".(empty($stocktheo)?0:$stocktheo); + print '
    '; + print $form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")); + print '"; + //print (empty($stocktheo)?0:$stocktheo); + print $form->textwithpicto((empty($stocktheo)?0:$stocktheo), $helpondiff); if ($object->seuil_stock_alerte != '' && ($object->stock_theorique < $object->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockLowerThanLimit")); print '
    '; - print $langs->trans("StockDiffPhysicTeoric"); - print ''; - - $found=0; - // Number of customer orders running - if (! empty($conf->commande->enabled)) - { - if ($found) print '
    '; else $found=1; - print $langs->trans("ProductQtyInCustomersOrdersRunning").': '.$object->stats_commande['qty']; - $result=$object->load_stats_commande(0,'0'); - if ($result < 0) dol_print_error($db,$object->error); - print ' ('.$langs->trans("ProductQtyInDraft").': '.$object->stats_commande['qty'].')'; - } - - // Number of product from customer order already sent (partial shipping) - if (! empty($conf->expedition->enabled)) - { - if ($found) print '
    '; else $found=1; - $result=$object->load_stats_sending(0,'2'); - print $langs->trans("ProductQtyInShipmentAlreadySent").': '.$object->stats_expedition['qty']; - } - - // Number of supplier order running - if (! empty($conf->fournisseur->enabled)) - { - if ($found) print '
    '; else $found=1; - $result=$object->load_stats_commande_fournisseur(0,'3,4'); - print $langs->trans("ProductQtyInSuppliersOrdersRunning").': '.$object->stats_commande_fournisseur['qty']; - $result=$object->load_stats_commande_fournisseur(0,'0,1,2'); - if ($result < 0) dol_print_error($db,$object->error); - print ' ('.$langs->trans("ProductQtyInDraftOrWaitingApproved").': '.$object->stats_commande_fournisseur['qty'].')'; - } - - // Number of product from supplier order already received (partial receipt) - if (! empty($conf->fournisseur->enabled)) - { - if ($found) print '
    '; else $found=1; - print $langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied").': '.$object->stats_reception['qty']; - } - - print '
    - + - - + - + - + - + - + - +
    - +
    >
    -
    -
    - + + +
    + +
    + + - - + '; + } + else + { if ($action === 'delete') { if ($prodcomb->fetch($valueid) > 0) { @@ -565,7 +583,22 @@ if (! empty($id) || ! empty($ref)) { " class="button">

    - + '; + print '
    '; + if ($productCombinations) { + print ''.$langs->trans('Copy').''; + } + print ''.$langs->trans('NewProductCombination').''; + print ''.$langs->trans('ProductCombinationGenerator').''; + print '
    '; + print ''; + + + + ?> @@ -618,17 +651,6 @@ if (! empty($id) || ! empty($ref)) { '; - print ' '; - print ''; - } } From 53238c2b0d8d4c55fc058e6191b291a37467ae4e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 12:27:42 +0100 Subject: [PATCH 071/410] Fix sort order and number of lines --- htdocs/product/reassortlot.php | 15 +++++++++------ htdocs/product/stock/mouvement.php | 10 +++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index 471aa7e3e6d..01285f09417 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -126,10 +126,7 @@ $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot as pl on pl.fk_product = p.rowi if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp"; $sql.= " WHERE p.entity IN (".getEntity('product', 1).")"; if ($search_categ) $sql.= " AND p.rowid = cp.fk_product"; // Join for the needed table to filter by categ -if ($sall) -{ - $sql.= " AND (p.ref LIKE '%".$db->escape($sall)."%' OR p.label LIKE '%".$db->escape($sall)."%' OR p.description LIKE '%".$db->escape($sall)."%' OR p.note LIKE '%".$db->escape($sall)."%')"; -} +if ($sall) $sql.=natural_search(array('p.ref','p.label','p.description','p.note'), $sall); // if the type is not 1, we show all products (type = 0,2,3) if (dol_strlen($type)) { @@ -163,6 +160,12 @@ $sql.= " pb.batch, pb.eatby, pb.sellby,"; $sql.= " pl.eatby, pl.sellby"; if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('ps.reel IS NULL', '0', 'ps.reel').") < p.seuil_stock_alerte"; // Not used yet $sql.= $db->order($sortfield,$sortorder); +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} $sql.= $db->plimit($limit + 1, $offset); $resql = $db->query($sql); @@ -193,11 +196,11 @@ if ($resql) if ($sref || $snom || $sall || GETPOST('search')) { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, 0, 'title_products'); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products'); } else { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, 0, 'title_products'); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products'); } if (! empty($catid)) diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index 8e6775e2e6e..7c4b4dcab08 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -89,7 +89,7 @@ $arrayfields=array( 'm.batch'=>array('label'=>$langs->trans("BatchNumberShort"), 'checked'=>1, 'enabled'=>(! empty($conf->productbatch->enabled))), 'pl.eatby'=>array('label'=>$langs->trans("EatByDate"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))), 'pl.sellby'=>array('label'=>$langs->trans("SellByDate"), 'checked'=>0, 'position'=>10, 'enabled'=>(! empty($conf->productbatch->enabled))), - 'm.warehouse'=>array('label'=>$langs->trans("Warehouse"), 'checked'=>1, 'enabled'=>(! $id > 0)), // If we are on specific warehouse, we hide it + 'e.label'=>array('label'=>$langs->trans("Warehouse"), 'checked'=>1, 'enabled'=>(! $id > 0)), // If we are on specific warehouse, we hide it 'm.fk_user_author'=>array('label'=>$langs->trans("Author"), 'checked'=>0), 'm.inventorycode'=>array('label'=>$langs->trans("InventoryCodeShort"), 'checked'=>1), 'm.label'=>array('label'=>$langs->trans("LabelMovement"), 'checked'=>1), @@ -710,7 +710,7 @@ if ($resql) if (! empty($arrayfields['m.batch']['checked'])) print_liste_field_titre($arrayfields['m.batch']['label'],$_SERVER["PHP_SELF"],'m.batch','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['pl.eatby']['checked'])) print_liste_field_titre($arrayfields['pl.eatby']['label'],$_SERVER["PHP_SELF"],'pl.eatby','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['pl.sellby']['checked'])) print_liste_field_titre($arrayfields['pl.sellby']['label'],$_SERVER["PHP_SELF"],'pl.sellby','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['m.warehouse']['checked'])) print_liste_field_titre($arrayfields['m.warehouse']['label'],$_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder); // We are on a specific warehouse card, no filter on other should be possible + if (! empty($arrayfields['e.label']['checked'])) print_liste_field_titre($arrayfields['e.label']['label'],$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder); // We are on a specific warehouse card, no filter on other should be possible if (! empty($arrayfields['m.fk_user_author']['checked'])) print_liste_field_titre($arrayfields['m.fk_user_author']['label'],$_SERVER["PHP_SELF"], "m.fk_user_author","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['m.inventorycode']['checked'])) print_liste_field_titre($arrayfields['m.inventorycode']['label'],$_SERVER["PHP_SELF"], "m.inventorycode","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['m.label']['checked'])) print_liste_field_titre($arrayfields['m.label']['label'],$_SERVER["PHP_SELF"], "m.label","",$param,"",$sortfield,$sortorder); @@ -774,7 +774,7 @@ if ($resql) // Batch if (! empty($arrayfields['m.batch']['checked'])) { - print ''; + print ''; } if (! empty($arrayfields['pl.eatby']['checked'])) { @@ -787,7 +787,7 @@ if ($resql) print ''; } // Warehouse - if (! empty($arrayfields['m.warehouse']['checked'])) + if (! empty($arrayfields['e.label']['checked'])) { print ''; } // Warehouse - if (! empty($arrayfields['m.warehouse']['checked'])) + if (! empty($arrayfields['e.label']['checked'])) { print ''; print ''; + // Project + if (! empty($conf->projet->enabled)) + { + $formproject=new FormProjets($db); + + // Associated project + $langs->load("projects"); + + print ''; + } + // Payment Mode print ''; } + // Project + if (! empty($conf->projet->enabled)){ + print ''; + } + // Mode of payment print ''; + print ''; } print '
    '; //print ''; @@ -949,7 +949,7 @@ if ($resql) print ''. dol_print_date($objp->sellby,'day') .''; print $warehousestatic->getNomUrl(1); From 4e6ee4d12cb2449953556f7e6888f9dd5ee7d418 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 12:37:18 +0100 Subject: [PATCH 072/410] Fix dol_banner on card for lot --- .../product/stock/class/productlot.class.php | 29 ++++++++++++++++ htdocs/product/stock/productlot_card.php | 34 ++++--------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index 6128f8dcf17..1f97fa3f4d7 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -524,6 +524,35 @@ class Productlot extends CommonObject } } + + /** + * Return label of status of object + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut(0,$mode); + } + + /** + * Return label of a given status + * + * @param int $statut Status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label of status + */ + function LibStatut($statut,$mode=0) + { + global $langs; + + //$langs->load('stocks'); + + return ''; + } + + /** * Return a link to the a lot card (with optionaly the picto) * Use this->id,this->lastname, this->firstname diff --git a/htdocs/product/stock/productlot_card.php b/htdocs/product/stock/productlot_card.php index 3407c75a6f5..0df3df3ac4f 100644 --- a/htdocs/product/stock/productlot_card.php +++ b/htdocs/product/stock/productlot_card.php @@ -270,24 +270,6 @@ llxHeader('','ProductLot',''); $form=new Form($db); -// Put here content of your page - -// Example : Adding jquery code -print ''; - - // Part to create if ($action == 'create') { @@ -335,19 +317,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print $formconfirm; } - print ''."\n"; $linkback = '' . $langs->trans("BackToList") . ''; - // Ref - print ''; - print ''; - print ''; + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'batch'); + + print '
    ' . $langs->trans('Batch') . ''; - print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'batch'); - print '
    '."\n"; // Product - print ''; print ''; @@ -364,7 +342,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Sell by print ''; print ''; From 910859145fbe27e5b7062c879d28a1febdb3fe87 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 12:40:47 +0100 Subject: [PATCH 073/410] Fix filter on lot was lost --- htdocs/product/stock/mouvement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index 7c4b4dcab08..de46538a037 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -640,6 +640,7 @@ if ($resql) if ($search_inventorycode) $param.='&search_inventorycode='.urlencode($search_inventorycode); if ($search_product_ref) $param.='&search_product_ref='.urlencode($search_product_ref); if ($search_product) $param.='&search_product='.urlencode($search_product); + if ($search_batch) $param.='&search_batch='.urlencode($search_batch); if ($search_warehouse > 0) $param.='&search_warehouse='.urlencode($search_warehouse); if (!empty($sref)) $param.='&sref='.urlencode($sref); // FIXME $sref is not defined if (!empty($snom)) $param.='&snom='.urlencode($snom); // FIXME $snom is not defined From f06126c46318c877289772df2ac07f3d53c8f57d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 12:45:18 +0100 Subject: [PATCH 074/410] Fix style --- htdocs/product/stock/productlot_card.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/product/stock/productlot_card.php b/htdocs/product/stock/productlot_card.php index 0df3df3ac4f..4d1b82307f8 100644 --- a/htdocs/product/stock/productlot_card.php +++ b/htdocs/product/stock/productlot_card.php @@ -322,7 +322,10 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'batch'); - print '
    '.$langs->trans("Product").''; + print '
    '.$langs->trans("Product").''; $producttmp = new Product($db); $producttmp->fetch($object->fk_product); print $producttmp->getNomUrl(1, 'stock'); @@ -356,7 +334,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Eat by print '
    '; print $form->editfieldkey($langs->trans('Eatby'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker'); - print ''; + print ''; print $form->editfieldval($langs->trans('Eatby'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker'); print '
    '; print $form->editfieldkey($langs->trans('Sellby'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker'); - print ''; + print ''; print $form->editfieldval($langs->trans('Sellby'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker'); print '
    '."\n"; + print '
    '; + print '
    '; + + print '
    '."\n"; // Product print '
    '.$langs->trans("Product").''; @@ -353,6 +356,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; + print ''; + dol_fiche_end(); From 7103d7921e44584d9ab59ad5c28f9da7e4849d82 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Mar 2017 13:42:16 +0100 Subject: [PATCH 075/410] Uniformize look --- htdocs/product/traduction.php | 20 +++++++++++++++----- htdocs/theme/eldy/style.css.php | 5 +++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index e7986fde074..b5f4b8b34ae 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -244,8 +244,9 @@ if ($action == 'edit') foreach ($object->multilangs as $key => $value) { $s=picto_from_langcode($key); - print "
    ".($s?$s.' ':'')." ".$langs->trans('Language_'.$key).": ".''.img_delete('', '')."
    "; + print "
    ".($s?$s.' ':'')." ".$langs->trans('Language_'.$key).": ".''.img_delete('', 'class="valigntextbottom"')."
    "; + print '
    '; print ''; print ''; print ''; + print '
    '; print '
    '.$langs->trans('Label').'
    '.$langs->trans('Description').''; @@ -263,6 +264,8 @@ if ($action == 'edit') } } + print '
    '; + print '
    '; print ''; print '     '; @@ -274,17 +277,20 @@ if ($action == 'edit') } else if ($action != 'add') { - if ($cnt_trans) print '
    '; + //if ($cnt_trans) print '
    '; if (! empty($object->multilangs)) { foreach ($object->multilangs as $key => $value) { $s=picto_from_langcode($key); + //print '
    '; + print ($s?$s.' ':'')." ".$langs->trans('Language_'.$key).": ".''.img_delete('', 'class="valigntextbottom"').''; + //print '
    '; - print ''; print ''; - print ''; + print ''; if (! empty($conf->global->PRODUCT_USE_OTHER_FIELD_IN_TRANSLATION)) { print ''; @@ -312,6 +318,8 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service print ''; print ''; + dol_fiche_head(); + print '
    '.($s?$s.' ':'')." ".$langs->trans('Language_'.$key).": ".''.img_delete('', '').'
    '.$langs->trans('Label').''.$object->multilangs[$key]["label"].'
    '.$langs->trans('Description').''.$object->multilangs[$key]["description"].'
    '.$langs->trans('Description').''.$object->multilangs[$key]["description"].'
    '.$langs->trans('Other').' ('.$langs->trans("NotUsed").')'.$object->multilangs[$key]["other"].'
    '; print '
    '.$langs->trans('Language').''; print $formadmin->select_language('','forcelangprod',0,$object->multilangs,1); @@ -331,7 +339,9 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service } print '
    '; - print '
    '; + dol_fiche_end(); + + print '
    '; print ''; print '     '; print ''; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 6c6869ce7d4..1f2f1a225e3 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2559,10 +2559,11 @@ div.pagination li.paginationafterarrows { /* Set the color for hover lines */ -.oddeven:hover, .odd:hover, .impair:hover, .even:hover, .pair:hover, .even:hover, .pair:hover, table.dataTable tr.even:hover, table.dataTable tr.odd:hover +.oddeven:hover, .odd:hover, .impair:hover, .even:hover, .pair:hover, .even:hover, .pair:hover, +table.dataTable tr.even:hover, table.dataTable tr.odd:hover { - background-color: rgb() !important; + background: rgb() !important; /* Must be background to be stronger than background of odd or even */ } From a39dccad197451e06aa3f5ce12bf6f1c65b1a1d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 11 Mar 2017 19:00:44 +0100 Subject: [PATCH 076/410] FIX #6503: SQL error in "Last pending payment invoices" Close #6503 --- htdocs/core/boxes/box_factures_imp.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_factures_imp.php b/htdocs/core/boxes/box_factures_imp.php index 67c4d4dbfcc..d3336500263 100644 --- a/htdocs/core/boxes/box_factures_imp.php +++ b/htdocs/core/boxes/box_factures_imp.php @@ -78,8 +78,9 @@ class box_factures_imp extends ModeleBoxes $sql.= " f.total_ttc,"; $sql.= " f.paye, f.fk_statut, f.rowid as facid"; $sql.= ", sum(pf.amount) as am"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= ", ".MAIN_DB_PREFIX."facture as f"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid=pf.fk_facture "; $sql.= " WHERE f.fk_soc = s.rowid"; $sql.= " AND f.entity = ".$conf->entity; From e9c7b020499de09ce33603f7aa7f1c99f67fdd65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 11 Mar 2017 19:22:01 +0100 Subject: [PATCH 077/410] FIX #6507: Statistics counter show wrong total Contract numbers when the user does not have full access Close #6507 --- htdocs/contrat/class/contrat.class.php | 2 +- htdocs/contrat/list.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 81a3d26c818..6ad972a11eb 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2045,7 +2045,7 @@ class Contrat extends CommonObject $sql = "SELECT count(c.rowid) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."contrat as c"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid"; - if (!$user->rights->contrat->lire && !$user->societe_id) + if (!$user->rights->societe->client->voir && !$user->societe_id) { $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql.= " WHERE sc.fk_user = " .$user->id; diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 57cf487e8e9..ba3e8c0a80d 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -201,7 +201,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) } $sql.= $db->plimit($limit + 1, $offset); - +echo $sql; $resql=$db->query($sql); if ($resql) { From f15c6da8871068f22ea1d889c74b83f6e6393635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 11 Mar 2017 19:24:05 +0100 Subject: [PATCH 078/410] Typo --- htdocs/contrat/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index ba3e8c0a80d..57cf487e8e9 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -201,7 +201,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) } $sql.= $db->plimit($limit + 1, $offset); -echo $sql; + $resql=$db->query($sql); if ($resql) { From c6c07bf9f4bbbc7e0aa15a191c0824844344f82b Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 12 Mar 2017 14:32:49 +0100 Subject: [PATCH 079/410] New : Add project to social contributions --- htdocs/compta/sociales/card.php | 67 +++++++++++++++---- .../sociales/class/chargesociales.class.php | 42 +++++++----- htdocs/core/class/html.formprojet.class.php | 3 +- .../install/mysql/migration/5.0.0-6.0.0.sql | 2 + .../mysql/tables/llx_chargesociales.sql | 36 +++++----- htdocs/langs/en_US/compta.lang | 2 + htdocs/projet/element.php | 58 ++++++++++------ 7 files changed, 139 insertions(+), 71 deletions(-) diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index 92cb36059e4..76456aee99b 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2004-2016 Laurent Destailleur * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2016 Frédéric France - * Copyright (C) 2016 Alexandre Spangaro + * Copyright (C) 2017 Alexandre Spangaro * * 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 @@ -28,6 +28,11 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsocialcontrib.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; +if (! empty($conf->projet->enabled)) +{ + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} $langs->load("compta"); $langs->load("bills"); @@ -35,6 +40,7 @@ $langs->load("bills"); $id=GETPOST('id','int'); $action=GETPOST("action"); $confirm=GETPOST('confirm'); +$projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0); // Security check $socid = GETPOST('socid','int'); @@ -43,8 +49,6 @@ $result = restrictedArea($user, 'tax', $id, 'chargesociales','charges'); $object = new ChargeSociales($db); - - /* *************************************************************************** */ /* */ /* Actions */ @@ -122,6 +126,7 @@ if ($action == 'add' && $user->rights->tax->charges->creer) $dateperiod=dol_mktime(GETPOST('periodhour'),GETPOST('periodmin'),GETPOST('periodsec'),GETPOST('periodmonth'),GETPOST('periodday'),GETPOST('periodyear')); $amount=price2num(GETPOST('amount')); $actioncode=GETPOST('actioncode'); + if (! $dateech) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateDue")), null, 'errors'); @@ -149,13 +154,14 @@ if ($action == 'add' && $user->rights->tax->charges->creer) } else { - $object->type=$actioncode; - $object->lib=GETPOST('label'); - $object->date_ech=$dateech; - $object->periode=$dateperiod; - $object->amount=$amount; - $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->fk_account = GETPOST('fk_account', 'int'); + $object->type = $actioncode; + $object->lib = GETPOST('label'); + $object->date_ech = $dateech; + $object->periode = $dateperiod; + $object->amount = $amount; + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->fk_account = GETPOST('fk_account', 'int'); + $object->fk_project = GETPOST('fk_project'); $id=$object->create($user); if ($id <= 0) @@ -172,6 +178,7 @@ if ($action == 'update' && ! $_POST["cancel"] && $user->rights->tax->charges->cr $dateech=dol_mktime(GETPOST('echhour'),GETPOST('echmin'),GETPOST('echsec'),GETPOST('echmonth'),GETPOST('echday'),GETPOST('echyear')); $dateperiod=dol_mktime(GETPOST('periodhour'),GETPOST('periodmin'),GETPOST('periodsec'),GETPOST('periodmonth'),GETPOST('periodday'),GETPOST('periodyear')); $amount=price2num(GETPOST('amount')); + if (! $dateech) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateDue")), null, 'errors'); @@ -196,10 +203,11 @@ if ($action == 'update' && ! $_POST["cancel"] && $user->rights->tax->charges->cr { $result=$object->fetch($id); - $object->lib=GETPOST('label'); - $object->date_ech=$dateech; - $object->periode=$dateperiod; - $object->amount=price2num($amount); + $object->lib = GETPOST('label'); + $object->date_ech = $dateech; + $object->periode = $dateperiod; + $object->amount = price2num($amount); + $object->fk_project = GETPOST("fk_project"); $result=$object->update($user); if ($result <= 0) @@ -325,6 +333,21 @@ if ($action == 'create') print '
    '.$langs->trans("Project").''; + + $numproject=$formproject->select_projects(-1, $projectid,'fk_project',0,0,1,1); + + print '
    ' . $langs->trans('PaymentMode') . ''; $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id'); @@ -485,6 +508,22 @@ if ($id > 0) print '
    '.$langs->trans("AmountTTC").''.price($object->amount,0,$outputlangs,1,-1,-1,$conf->currency).'
    '; + print $langs->trans("Project"); + print ''; + if ($action == 'edit') { + $formproject=new FormProjets($db); + $numproject=$formproject->select_projects(-1,$object->fk_project,'fk_project',16,0,1,1); + } else { + $project=new Project($db); + $project->fetch($object->fk_project); + print $project->getNomUrl(1,'',1);; + } + print '
    '; print ' - fetch($currcomb->fk_product_child); ?> - > - - - - - - - - - - + fetch($currcomb->fk_product_child); + ?> + > + + + + + + + + + + '; + } + ?>
    '; diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index 61546b39061..dae1fe109ca 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2002 Rodolphe Quiedeville * Copyright (C) 2004-2007 Laurent Destailleur * Copyright (C) 2016 Frédéric France + * Copyright (C) 2017 Alexandre Spangaro * * 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 @@ -52,6 +53,7 @@ class ChargeSociales extends CommonObject var $date_modification; var $date_validation; var $fk_account; + var $fk_project; /** @@ -75,7 +77,7 @@ class ChargeSociales extends CommonObject function fetch($id, $ref='') { $sql = "SELECT cs.rowid, cs.date_ech"; - $sql.= ", cs.libelle as lib, cs.fk_type, cs.amount, cs.paye, cs.periode, cs.import_key"; + $sql.= ", cs.libelle as lib, cs.fk_type, cs.amount, cs.fk_projet as fk_project, cs.paye, cs.periode, cs.import_key"; $sql.= ", cs.fk_account, cs.fk_mode_reglement"; $sql.= ", c.libelle"; $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; @@ -93,20 +95,21 @@ class ChargeSociales extends CommonObject { $obj = $this->db->fetch_object($resql); - $this->id = $obj->rowid; - $this->ref = $obj->rowid; - $this->date_ech = $this->db->jdate($obj->date_ech); - $this->lib = $obj->lib; - $this->type = $obj->fk_type; - $this->type_libelle = $obj->libelle; - $this->fk_account = $obj->fk_account; - $this->mode_reglement_id = $obj->fk_mode_reglement; - $this->mode_reglement_code = $obj->mode_reglement_code; - $this->mode_reglement = $obj->mode_reglement_libelle; - $this->amount = $obj->amount; - $this->paye = $obj->paye; - $this->periode = $this->db->jdate($obj->periode); - $this->import_key = $this->import_key; + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + $this->date_ech = $this->db->jdate($obj->date_ech); + $this->lib = $obj->lib; + $this->type = $obj->fk_type; + $this->type_libelle = $obj->libelle; + $this->fk_account = $obj->fk_account; + $this->mode_reglement_id = $obj->fk_mode_reglement; + $this->mode_reglement_code = $obj->mode_reglement_code; + $this->mode_reglement = $obj->mode_reglement_libelle; + $this->amount = $obj->amount; + $this->fk_project = $obj->fk_project; + $this->paye = $obj->paye; + $this->periode = $this->db->jdate($obj->periode); + $this->import_key = $this->import_key; $this->db->free($resql); @@ -166,13 +169,15 @@ class ChargeSociales extends CommonObject $this->db->begin(); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."chargesociales (fk_type, fk_account, fk_mode_reglement, libelle, date_ech, periode, amount, entity, fk_user_author, date_creation)"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."chargesociales (fk_type, fk_account, fk_mode_reglement, libelle, date_ech, periode, amount, fk_projet, entity, fk_user_author, date_creation)"; $sql.= " VALUES (".$this->type; $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); $sql.= ", ".($this->mode_reglement_id>0?"'".$this->mode_reglement_id."'":"NULL"); $sql.= ", '".$this->db->escape($this->lib)."'"; - $sql.= ", '".$this->db->idate($this->date_ech)."','".$this->db->idate($this->periode)."'"; + $sql.= ", '".$this->db->idate($this->date_ech)."'"; + $sql.= ", '".$this->db->idate($this->periode)."'"; $sql.= ", '".price2num($newamount)."'"; + $sql.= ", ".($this->fk_project>0?$this->fk_project:'NULL'); $sql.= ", ".$conf->entity; $sql.= ", ".$user->id; $sql.= ", '".$this->db->idate($now)."'"; @@ -283,6 +288,7 @@ class ChargeSociales extends CommonObject $sql.= ", date_ech='".$this->db->idate($this->date_ech)."'"; $sql.= ", periode='".$this->db->idate($this->periode)."'"; $sql.= ", amount='".price2num($this->amount,'MT')."'"; + $sql.= ", fk_projet='".$this->db->escape($this->fk_project)."'"; $sql.= ", fk_user_modif=".$user->id; $sql.= " WHERE rowid=".$this->id; @@ -302,7 +308,7 @@ class ChargeSociales extends CommonObject } /** - * Enter description here ... + * Calculate amount remaining to pay by year * * @param int $year Year * @return number diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 571b24bca52..0a6837ecb53 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -464,7 +464,7 @@ class FormProjets if ($table_element == 'projet_task') return ''; // Special cas of element we never link to a project (already always done) $linkedtothirdparty=false; - if (! in_array($table_element, array('don','expensereport_det','expensereport','loan','stock_mouvement'))) $linkedtothirdparty=true; + if (! in_array($table_element, array('don','expensereport_det','expensereport','loan','stock_mouvement','chargesociales'))) $linkedtothirdparty=true; $sqlfilter=''; $projectkey="fk_projet"; @@ -507,6 +507,7 @@ class FormProjets $sql = 'SELECT t.rowid, t.label as ref'; $projectkey='fk_origin'; break; + case "chargesociales": default: $sql = "SELECT t.rowid, t.ref"; break; diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 0dfc5f36925..e6d525df983 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -114,3 +114,5 @@ UPDATE llx_const set value='moono-lisa' where value = 'moono' AND name = 'FCKEDI ALTER TABLE llx_product_price ADD COLUMN default_vat_code varchar(10) after tva_tx; ALTER TABLE llx_product_fournisseur_price ADD COLUMN default_vat_code varchar(10) after tva_tx; +ALTER TABLE llx_chargesociales ADD COLUMN fk_projet integer DEFAULT NULL; + diff --git a/htdocs/install/mysql/tables/llx_chargesociales.sql b/htdocs/install/mysql/tables/llx_chargesociales.sql index 95ab50661b6..5c07c9a74fc 100644 --- a/htdocs/install/mysql/tables/llx_chargesociales.sql +++ b/htdocs/install/mysql/tables/llx_chargesociales.sql @@ -1,6 +1,7 @@ -- ======================================================================== -- Copyright (C) 2001-2002 Rodolphe Quiedeville -- Copyright (C) 2005-2009 Regis Houssin +-- Copyright (C) 2017 Alexandre Spangaro -- -- 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 @@ -19,23 +20,24 @@ create table llx_chargesociales ( - rowid integer AUTO_INCREMENT PRIMARY KEY, - date_ech datetime NOT NULL, -- date echeance - libelle varchar(80) NOT NULL, - entity integer DEFAULT 1 NOT NULL, -- multi company id - tms timestamp, - date_creation datetime, -- date de creation - date_valid datetime, -- date de validation - fk_user_author integer, -- user making creation - fk_user_modif integer, -- user making last change - fk_user_valid integer, -- user validating - fk_type integer NOT NULL, - fk_account integer, -- bank account - fk_mode_reglement integer, -- mode de reglement - amount real default 0 NOT NULL, - paye smallint default 0 NOT NULL, - periode date, - import_key varchar(14) + rowid integer AUTO_INCREMENT PRIMARY KEY, + date_ech datetime NOT NULL, -- date echeance + libelle varchar(80) NOT NULL, + entity integer DEFAULT 1 NOT NULL, -- multi company id + tms timestamp, + date_creation datetime, -- date de creation + date_valid datetime, -- date de validation + fk_user_author integer, -- user making creation + fk_user_modif integer, -- user making last change + fk_user_valid integer, -- user validating + fk_type integer NOT NULL, + fk_account integer, -- bank account + fk_mode_reglement integer, -- mode de reglement + amount real default 0 NOT NULL, + paye smallint default 0 NOT NULL, + periode date, + fk_projet integer DEFAULT NULL, + import_key varchar(14) )ENGINE=innodb; -- diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index eca26d337c2..aa5f2195a56 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -56,6 +56,7 @@ MenuTaxAndDividends=Taxes and dividends MenuSocialContributions=Social/fiscal taxes MenuNewSocialContribution=New social/fiscal tax NewSocialContribution=New social/fiscal tax +AddSocialContribution=Add social/fiscal tax ContributionsToPay=Social/fiscal taxes to pay AccountancyTreasuryArea=Accountancy/Treasury area NewPayment=New payment @@ -205,3 +206,4 @@ ImportDataset_tax_contrib=Social/fiscal taxes ImportDataset_tax_vat=Vat payments ErrorBankAccountNotFound=Error: Bank account not found FiscalPeriod=Accounting period +ListSocialContributionAssociatedProject=List of social contributions associated with the project diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 69dde026c9b..89bab45896f 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2012-2016 Juanjo Menent - * Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 2015-2017 Alexandre Spangaro * Copyright (C) 2015 Marcos García * Copyright (C) 2016 Josep Lluís Amador * @@ -34,25 +34,27 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; -if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; -if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; -if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; +if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; if (! empty($conf->supplier_proposal->enabled)) require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; -if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; -if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; -if (! empty($conf->contrat->enabled)) require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; -if (! empty($conf->ficheinter->enabled)) require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; -if (! empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; -if (! empty($conf->expensereport->enabled)) require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; -if (! empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; -if (! empty($conf->don->enabled)) require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; -if (! empty($conf->loan->enabled)) require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; -if (! empty($conf->stock->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; +if (! empty($conf->contrat->enabled)) require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; +if (! empty($conf->ficheinter->enabled)) require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; +if (! empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; +if (! empty($conf->expensereport->enabled)) require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; +if (! empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; +if (! empty($conf->don->enabled)) require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; +if (! empty($conf->loan->enabled)) require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +if (! empty($conf->stock->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; +if (! empty($conf->tax->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; $langs->load("projects"); $langs->load("companies"); $langs->load("suppliers"); +$langs->load("compta"); if (! empty($conf->facture->enabled)) $langs->load("bills"); if (! empty($conf->commande->enabled)) $langs->load("orders"); if (! empty($conf->propal->enabled)) $langs->load("propal"); @@ -406,7 +408,20 @@ $listofreferent=array( 'table'=>'stock_mouvement', 'datefieldname'=>'datem', 'disableamount'=>0, - 'test'=>($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))) + 'test'=>($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))), +'chargesociales'=>array( + 'name'=>"SocialContribution", + 'title'=>"ListSocialContributionAssociatedProject", + 'class'=>'ChargeSociales', + 'margin'=>'add', + 'table'=>'chargesociales', + 'datefieldname'=>'date_ech', + 'disableamount'=>0, + 'urlnew'=>DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$id, + 'lang'=>'compta', + 'buttonnew'=>'AddSocialContribution', + 'testnew'=>$user->rights->tax->charges->lire, + 'test'=>$conf->tax->enabled && $user->rights->tax->charges->lire) /* No need for this, available on dedicated tab "Agenda/Events" 'agenda'=>array( 'name'=>"Agenda", @@ -539,7 +554,7 @@ foreach ($listofreferent as $key => $value) // Special cases if ($tablename != 'expensereport_det' && method_exists($element, 'fetch_thirdparty')) $element->fetch_thirdparty(); - if ($tablename == 'don') $total_ht_by_line=$element->amount; + if ($tablename == 'don' || $tablename == 'chargesociales') $total_ht_by_line=$element->amount; elseif ($tablename == 'stock_mouvement') $total_ht_by_line=$element->price*abs($element->qty); elseif ($tablename == 'projet_task') { @@ -564,7 +579,7 @@ foreach ($listofreferent as $key => $value) if ($qualifiedfortotal) $total_ht = $total_ht + $total_ht_by_line; - if ($tablename == 'don') $total_ttc_by_line=$element->amount; + if ($tablename == 'don' || $tablename == 'chargesociales') $total_ttc_by_line=$element->amount; elseif ($tablename == 'stock_mouvement') $total_ttc_by_line=$element->price*abs($element->qty); elseif ($tablename == 'projet_task') { @@ -865,9 +880,10 @@ foreach ($listofreferent as $key => $value) $date=''; $total_time_by_line = null; if ($tablename == 'expensereport_det') $date = $element->date; // No draft status on lines elseif ($tablename == 'stock_mouvement') $date = $element->datem; + if ($tablename == 'chargesociales') $date = $element->date_ech; elseif (! empty($element->status) || ! empty($element->statut) || ! empty($element->fk_status)) { - if ($tablename=='don') $date = $element->datedon; + if ($tablename == 'don') $date = $element->datedon; if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') { $date=($element->date_commande?$element->date_commande:$element->date_valid); @@ -927,7 +943,7 @@ foreach ($listofreferent as $key => $value) { $total_ht_by_line=null; $othermessage=''; - if ($tablename == 'don') $total_ht_by_line=$element->amount; + if ($tablename == 'don' || $tablename == 'chargesociales') $total_ht_by_line=$element->amount; elseif ($tablename == 'stock_mouvement') $total_ht_by_line=$element->price*abs($element->qty); elseif (in_array($tablename, array('projet_task'))) { @@ -967,7 +983,7 @@ foreach ($listofreferent as $key => $value) if (empty($value['disableamount'])) { $total_ttc_by_line=null; - if ($tablename == 'don') $total_ttc_by_line=$element->amount; + if ($tablename == 'don' || $tablename == 'chargesociales') $total_ttc_by_line=$element->amount; elseif ($tablename == 'stock_mouvement') $total_ttc_by_line=$element->price*abs($element->qty); elseif ($tablename == 'projet_task') { From e9d5b44009a3e96abbba9b9d6a1e7348d4224e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sun, 12 Mar 2017 15:31:39 +0100 Subject: [PATCH 080/410] Fixed Project counter showing total amount of projects instead of just the projects current user can see --- htdocs/projet/class/project.class.php | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 1de78f46021..15170a23cbc 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2016 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2013 Florian Henry - * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2014-2017 Marcos García * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1689,17 +1689,21 @@ class Project extends CommonObject */ function load_state_board() { - global $conf; + global $user; $this->nb=array(); - - $sql = "SELECT count(u.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet as u"; - $sql.= " WHERE"; - //$sql.= " WHERE u.fk_statut > 0"; - //$sql.= " AND employee != 0"; - $sql.= " u.entity IN (".getEntity('projet', 1).")"; - + + $sql = "SELECT DISTINCT + count(p.rowid) as nb +FROM ".MAIN_DB_PREFIX."projet AS p LEFT JOIN ".MAIN_DB_PREFIX."societe AS s ON p.fk_soc = s.rowid + LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status AS cls ON p.fk_opp_status = cls.rowid +WHERE p.entity IN (".getEntity('projet', 1).")"; + + if (! $user->rights->projet->all->lire) { + $projectsListId = $this->getProjectsAuthorizedForUser($user,0,1); + $sql .= "AND p.rowid IN (".$projectsListId.")"; + } + $resql=$this->db->query($sql); if ($resql) { From e8a1f0ba46ed8272b123170feaa0a0ffa137f9a5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 12 Mar 2017 17:10:32 +0100 Subject: [PATCH 081/410] Uniformize code --- htdocs/variants/combinations.php | 71 +++++++++++++++++++------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 03e45a328e8..dabace75ac0 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -615,35 +615,48 @@ if (! empty($id) || ! empty($ref)) { trans('OnBuy') ?>
    getNomUrl(1) ?> - fetchByFkCombination($currcomb->id); - $iMax = count($productCombination2ValuePairs); - - for ($i = 0; $i < $iMax; $i++) { - echo dol_htmlentities($productCombination2ValuePairs[$i]); - - if ($i !== ($iMax - 1)) { - echo ', '; - } - } ?> - variation_price >= 0 ? '+' : '').price($currcomb->variation_price).($currcomb->variation_price_percentage ? ' %' : '') ?>variation_weight >= 0 ? '+' : '').price($currcomb->variation_weight).' '.measuring_units_string($prodstatic->weight_units, 'weight') ?>getLibStatut(2, 0) ?>getLibStatut(2, 1) ?> - - -
    getNomUrl(1) ?> + fetchByFkCombination($currcomb->id); + $iMax = count($productCombination2ValuePairs); + + for ($i = 0; $i < $iMax; $i++) { + echo dol_htmlentities($productCombination2ValuePairs[$i]); + + if ($i !== ($iMax - 1)) { + echo ', '; + } + } ?> + variation_price >= 0 ? '+' : '').price($currcomb->variation_price).($currcomb->variation_price_percentage ? ' %' : '') ?>variation_weight >= 0 ? '+' : '').price($currcomb->variation_weight).' '.measuring_units_string($prodstatic->weight_units, 'weight') ?>getLibStatut(2, 0) ?>getLibStatut(2, 1) ?> + + +
    '.$langs->trans("None").'
    From 520bdac5109ae86112f1a8f8248d8f24891a978a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Mar 2017 01:35:04 +0100 Subject: [PATCH 082/410] Translation --- htdocs/core/modules/modNotification.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modNotification.class.php b/htdocs/core/modules/modNotification.class.php index c29c77b8f24..72c90ca7a6d 100644 --- a/htdocs/core/modules/modNotification.class.php +++ b/htdocs/core/modules/modNotification.class.php @@ -44,7 +44,7 @@ class modNotification extends DolibarrModules $this->family = "technic"; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); - $this->description = "Gestion des notifications (par mail) sur evenement Dolibarr"; + $this->description = "EMail notifications (push) on business Dolibarr events"; $this->version = 'dolibarr'; // 'experimental' or 'dolibarr' or version $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->special = 1; From b8b32ae2e34805bebc26928dd27a17457c135629 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Mar 2017 02:10:22 +0100 Subject: [PATCH 083/410] FIX colspan --- htdocs/societe/rib.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/htdocs/societe/rib.php b/htdocs/societe/rib.php index 65bd12b2be4..feea1aca0ce 100644 --- a/htdocs/societe/rib.php +++ b/htdocs/societe/rib.php @@ -359,14 +359,16 @@ if ($socid && $action != 'edit' && $action != "create") print load_fiche_titre($langs->trans("DefaultRIB"), '', ''); + print '
    '; print '
    '; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; // Show fields of bank account foreach($account->getFieldsToShow(1) as $val) @@ -407,24 +409,24 @@ if ($socid && $action != 'edit' && $action != "create") } print ''; - print ''; + print ''; print ''; } - print '\n"; - print '\n"; - print '\n"; print '
    '.$langs->trans("LabelRIB").''.$account->label.'
    '.$account->label.'
    '.$langs->trans("BankName").''.$account->bank.'
    '.$account->bank.'
    '.$langs->trans($val).''.$content.''.$content.'
    '.$langs->trans("BankAccountDomiciliation").''; + print '
    '.$langs->trans("BankAccountDomiciliation").''; print $account->domiciliation; print "
    '.$langs->trans("BankAccountOwner").''; + print '
    '.$langs->trans("BankAccountOwner").''; print $account->proprio; print "
    '.$langs->trans("BankAccountOwnerAddress").''; + print '
    '.$langs->trans("BankAccountOwnerAddress").''; print $account->owner_address; print "
    '; - + print '
    '; print '
    '; @@ -611,7 +613,7 @@ if ($socid && $action != 'edit' && $action != "create") { $colspan=8; if (! empty($conf->prelevement->enabled)) $colspan+=2; - print '
    '.$langs->trans("NoBANRecord").'
    '.$langs->trans("NoBANRecord").'
    '; From 17eee4e1418b6e5a0d1df648c602fc43fec0a08c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Mar 2017 02:11:03 +0100 Subject: [PATCH 084/410] Prepare 5.0.1 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index bea82d34bb9..f385fa2a524 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','5.0.0'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','5.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); From d3e1a0127334b9fa9e0e69efa4d7a7cb38154530 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Mar 2017 01:35:04 +0100 Subject: [PATCH 085/410] Translation --- htdocs/core/modules/modNotification.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modNotification.class.php b/htdocs/core/modules/modNotification.class.php index c29c77b8f24..72c90ca7a6d 100644 --- a/htdocs/core/modules/modNotification.class.php +++ b/htdocs/core/modules/modNotification.class.php @@ -44,7 +44,7 @@ class modNotification extends DolibarrModules $this->family = "technic"; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); - $this->description = "Gestion des notifications (par mail) sur evenement Dolibarr"; + $this->description = "EMail notifications (push) on business Dolibarr events"; $this->version = 'dolibarr'; // 'experimental' or 'dolibarr' or version $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->special = 1; From 3affcd7f52ee10a417e70952081b48d96ce4e032 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Mar 2017 02:10:22 +0100 Subject: [PATCH 086/410] FIX colspan --- htdocs/societe/rib.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/htdocs/societe/rib.php b/htdocs/societe/rib.php index 4d3e32e326f..122c5282a40 100644 --- a/htdocs/societe/rib.php +++ b/htdocs/societe/rib.php @@ -358,14 +358,16 @@ if ($socid && $action != 'edit' && $action != "create") print load_fiche_titre($langs->trans("DefaultRIB"), '', ''); + print '
    '; print '
    '; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; // Show fields of bank account foreach($account->getFieldsToShow(1) as $val) @@ -406,24 +408,24 @@ if ($socid && $action != 'edit' && $action != "create") } print ''; - print ''; + print ''; print ''; } - print '\n"; - print '\n"; - print '\n"; print '
    '.$langs->trans("LabelRIB").''.$account->label.'
    '.$account->label.'
    '.$langs->trans("BankName").''.$account->bank.'
    '.$account->bank.'
    '.$langs->trans($val).''.$content.''.$content.'
    '.$langs->trans("BankAccountDomiciliation").''; + print '
    '.$langs->trans("BankAccountDomiciliation").''; print $account->domiciliation; print "
    '.$langs->trans("BankAccountOwner").''; + print '
    '.$langs->trans("BankAccountOwner").''; print $account->proprio; print "
    '.$langs->trans("BankAccountOwnerAddress").''; + print '
    '.$langs->trans("BankAccountOwnerAddress").''; print $account->owner_address; print "
    '; - + print '
    '; print '
    '; @@ -610,7 +612,7 @@ if ($socid && $action != 'edit' && $action != "create") { $colspan=8; if (! empty($conf->prelevement->enabled)) $colspan+=2; - print '
    '.$langs->trans("NoBANRecord").'
    '.$langs->trans("NoBANRecord").'
    '; From ca80c588532b718b79f794d3bbb85595400995bc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Mar 2017 02:14:42 +0100 Subject: [PATCH 087/410] Fix PHP error --- htdocs/core/ajax/box.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/ajax/box.php b/htdocs/core/ajax/box.php index fbb8fc759ad..7826747769b 100644 --- a/htdocs/core/ajax/box.php +++ b/htdocs/core/ajax/box.php @@ -73,7 +73,7 @@ if ($boxorder && $zone != '' && $userid > 0) if ($result > 0) { $langs->load("boxes"); - if (empty(GETPOST('closing'))) + if (! GETPOST('closing')) { setEventMessages($langs->trans("BoxAdded"), null); } From 6aeae12775b69e826cf64466101ddce9c7f184dc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Mar 2017 02:28:58 +0100 Subject: [PATCH 088/410] Fix medias could not be loaded --- htdocs/core/lib/files.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index c7cc2687463..21344f5eca9 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1807,7 +1807,8 @@ function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta function dol_check_secure_access_document($modulepart,$original_file,$entity,$fuser='',$refname='') { global $user, $conf, $db; - + global $dolibarr_main_data_root; + if (! is_object($fuser)) $fuser=$user; if (empty($modulepart)) return 'ErrorBadParameter'; @@ -2255,7 +2256,6 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu elseif ($modulepart == 'medias' && !empty($dolibarr_main_data_root)) { $accessallowed=1; - global $dolibarr_main_data_root; $original_file=$dolibarr_main_data_root.'/medias/'.$original_file; } From 38ccf7ffdd74ae5d36f3a3ff20702a97f8c79119 Mon Sep 17 00:00:00 2001 From: hugome Date: Thu, 2 Mar 2017 20:16:12 +0100 Subject: [PATCH 089/410] Fix : Agenda getCalendarEvents hook Return of getCalendarEvents on agenda page : The array_merge change key of merged array. --- htdocs/comm/action/index.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 5366720bfc6..321d15ba485 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -919,7 +919,14 @@ if (count($listofextcals)) // Complete $eventarray with events coming from external module $parameters=array(); $object=null; $reshook=$hookmanager->executeHooks('getCalendarEvents',$parameters,$object,$action); -if (! empty($hookmanager->resArray['eventarray'])) $eventarray=array_merge($eventarray, $hookmanager->resArray['eventarray']); +if (! empty($hookmanager->resArray['eventarray'])) { + foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) { + if (!isset($eventarray[$keyDate])) { + $eventarray[$keyDate]=array(); + } + $eventarray[$keyDate]=array_merge($eventarray[$keyDate], $events); + } +} From 017d73792c355fc0e6ea68fec42259350e5b1a20 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 13 Mar 2017 15:00:44 +0100 Subject: [PATCH 090/410] Fix: add md5 password for OpenLdap --- htdocs/adherents/class/adherent.class.php | 69 ++++++++--------- htdocs/core/lib/security.lib.php | 9 ++- htdocs/user/class/user.class.php | 93 ++++++++++++----------- 3 files changed, 87 insertions(+), 84 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 945ed849f57..a709e07f3ff 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2009-2012 Regis Houssin + * Copyright (C) 2009-2017 Regis Houssin * Copyright (C) 2014-2016 Alexandre Spangaro * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Frederic France @@ -496,7 +496,7 @@ class Adherent extends CommonObject if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) { $isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1; - + // If password to set differs from the one found into database $result=$this->setPassword($user,$this->pass,$isencrypted,$notrigger,$nosyncuserpass); if (! $nbrowsaffected) $nbrowsaffected++; @@ -862,7 +862,7 @@ class Adherent extends CommonObject $this->pass=$password; $this->pass_indatabase=$password_indatabase; $this->pass_indatabase_crypted=$password_crypted; - + if ($this->user_id && ! $nosyncuser) { require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; @@ -1122,7 +1122,7 @@ class Adherent extends CommonObject $this->pass = $obj->pass; $this->pass_indatabase = $obj->pass; $this->pass_indatabase_crypted = $obj->pass_crypted; - + $this->state_id = $obj->state_id; $this->state_code = $obj->state_id?$obj->state_code:''; $this->state = $obj->state_id?$obj->state:''; @@ -1160,7 +1160,7 @@ class Adherent extends CommonObject $this->user_id = $obj->user_id; $this->user_login = $obj->user_login; - + $this->model_pdf = $obj->model_pdf; // Retreive all extrafield for thirdparty @@ -1456,7 +1456,7 @@ class Adherent extends CommonObject if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled)) { $result=$mailmanspip->add_to_mailman($this); - + if ($result < 0) { if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error; @@ -1815,9 +1815,9 @@ class Adherent extends CommonObject public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) { global $conf,$langs; - + $langs->load("orders"); - + // Positionne le modele sur le nom du modele a utiliser if (! dol_strlen($modele)) { @@ -1830,13 +1830,13 @@ class Adherent extends CommonObject $modele = 'standard'; } } - + $modelpath = "core/modules/member/doc/"; - + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); } - - + + /** * Initialise an instance with random values. * Used to build previews or test instances. @@ -1926,27 +1926,28 @@ class Adherent extends CommonObject $this->fullname=$this->getFullName($langs); // Member - if ($this->fullname && ! empty($conf->global->LDAP_MEMBER_FIELD_FULLNAME)) $info[$conf->global->LDAP_MEMBER_FIELD_FULLNAME] = $this->fullname; - if ($this->lastname && ! empty($conf->global->LDAP_MEMBER_FIELD_NAME)) $info[$conf->global->LDAP_MEMBER_FIELD_NAME] = $this->lastname; - if ($this->firstname && ! empty($conf->global->LDAP_MEMBER_FIELD_FIRSTNAME)) $info[$conf->global->LDAP_MEMBER_FIELD_FIRSTNAME] = $this->firstname; - if ($this->login && ! empty($conf->global->LDAP_MEMBER_FIELD_LOGIN)) $info[$conf->global->LDAP_MEMBER_FIELD_LOGIN] = $this->login; - if ($this->pass && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte - if ($this->poste && ! empty($conf->global->LDAP_MEMBER_FIELD_TITLE)) $info[$conf->global->LDAP_MEMBER_FIELD_TITLE] = $this->poste; - if ($this->address && ! empty($conf->global->LDAP_MEMBER_FIELD_ADDRESS)) $info[$conf->global->LDAP_MEMBER_FIELD_ADDRESS] = $this->address; - if ($this->zip && ! empty($conf->global->LDAP_MEMBER_FIELD_ZIP)) $info[$conf->global->LDAP_MEMBER_FIELD_ZIP] = $this->zip; - if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN)) $info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town; - if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY)) $info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code; - if ($this->email && ! empty($conf->global->LDAP_MEMBER_FIELD_MAIL)) $info[$conf->global->LDAP_MEMBER_FIELD_MAIL] = $this->email; - if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE)) $info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype; - if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone; - if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso; - if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE)) $info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile; - if ($this->fax && ! empty($conf->global->LDAP_MEMBER_FIELD_FAX)) $info[$conf->global->LDAP_MEMBER_FIELD_FAX] = $this->fax; - if ($this->note_private && ! empty($conf->global->LDAP_MEMBER_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_MEMBER_FIELD_DESCRIPTION] = $this->note_private; - if ($this->note_public && ! empty($conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC)) $info[$conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC] = $this->note_public; - if ($this->birth && ! empty($conf->global->LDAP_MEMBER_FIELD_BIRTHDATE)) $info[$conf->global->LDAP_MEMBER_FIELD_BIRTHDATE] = dol_print_date($this->birth,'dayhourldap'); - if (isset($this->statut) && ! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) $info[$conf->global->LDAP_FIELD_MEMBER_STATUS] = $this->statut; - if ($this->datefin && ! empty($conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION)) $info[$conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION] = dol_print_date($this->datefin,'dayhourldap'); + if ($this->fullname && ! empty($conf->global->LDAP_MEMBER_FIELD_FULLNAME)) $info[$conf->global->LDAP_MEMBER_FIELD_FULLNAME] = $this->fullname; + if ($this->lastname && ! empty($conf->global->LDAP_MEMBER_FIELD_NAME)) $info[$conf->global->LDAP_MEMBER_FIELD_NAME] = $this->lastname; + if ($this->firstname && ! empty($conf->global->LDAP_MEMBER_FIELD_FIRSTNAME)) $info[$conf->global->LDAP_MEMBER_FIELD_FIRSTNAME] = $this->firstname; + if ($this->login && ! empty($conf->global->LDAP_MEMBER_FIELD_LOGIN)) $info[$conf->global->LDAP_MEMBER_FIELD_LOGIN] = $this->login; + if ($this->pass && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte + if ($this->pass && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // md5 for OpenLdap TODO add type of encryption + if ($this->poste && ! empty($conf->global->LDAP_MEMBER_FIELD_TITLE)) $info[$conf->global->LDAP_MEMBER_FIELD_TITLE] = $this->poste; + if ($this->address && ! empty($conf->global->LDAP_MEMBER_FIELD_ADDRESS)) $info[$conf->global->LDAP_MEMBER_FIELD_ADDRESS] = $this->address; + if ($this->zip && ! empty($conf->global->LDAP_MEMBER_FIELD_ZIP)) $info[$conf->global->LDAP_MEMBER_FIELD_ZIP] = $this->zip; + if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN)) $info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town; + if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY)) $info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code; + if ($this->email && ! empty($conf->global->LDAP_MEMBER_FIELD_MAIL)) $info[$conf->global->LDAP_MEMBER_FIELD_MAIL] = $this->email; + if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE)) $info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype; + if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone; + if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso; + if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE)) $info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile; + if ($this->fax && ! empty($conf->global->LDAP_MEMBER_FIELD_FAX)) $info[$conf->global->LDAP_MEMBER_FIELD_FAX] = $this->fax; + if ($this->note_private && ! empty($conf->global->LDAP_MEMBER_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_MEMBER_FIELD_DESCRIPTION] = $this->note_private; + if ($this->note_public && ! empty($conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC)) $info[$conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC] = $this->note_public; + if ($this->birth && ! empty($conf->global->LDAP_MEMBER_FIELD_BIRTHDATE)) $info[$conf->global->LDAP_MEMBER_FIELD_BIRTHDATE] = dol_print_date($this->birth,'dayhourldap'); + if (isset($this->statut) && ! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) $info[$conf->global->LDAP_FIELD_MEMBER_STATUS] = $this->statut; + if ($this->datefin && ! empty($conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION)) $info[$conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION] = dol_print_date($this->datefin,'dayhourldap'); // Subscriptions if ($this->first_subscription_date && ! empty($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE)) $info[$conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE] = dol_print_date($this->first_subscription_date,'dayhourldap'); @@ -2080,7 +2081,7 @@ class Adherent extends CommonObject /** * Return if a member is late (subscription late) or not - * + * * @return boolean True if late, False if not late */ public function hasDelay() diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index c20169270bf..7870824285a 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -1,6 +1,6 @@ - * Copyright (C) 2008-2012 Regis Houssin + * Copyright (C) 2008-2017 Regis Houssin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -74,7 +74,7 @@ function dol_decode($chain) * If constant MAIN_SECURITY_SALT is defined, we use it as a salt. * * @param string $chain String to hash - * @param int $type Type of hash (0:auto, 1:sha1, 2:sha1+md5, 3:md5). Use 3 here, if hash is not needed for security purpose, for security need, prefer 0. + * @param int $type Type of hash (0:auto, 1:sha1, 2:sha1+md5, 3:md5, 4:md5 for OpenLdap). Use 3 here, if hash is not needed for security purpose, for security need, prefer 0. * @return string Hash of string */ function dol_hash($chain,$type=0) @@ -87,6 +87,7 @@ function dol_hash($chain,$type=0) if ($type == 1) return sha1($chain); else if ($type == 2) return sha1(md5($chain)); else if ($type == 3) return md5($chain); + else if ($type == 4) return '{md5}'.base64_encode(mhash(MHASH_MD5,$chain)); // For OpenLdap with md5 else if (! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1') return sha1($chain); else if (! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1md5') return sha1(md5($chain)); @@ -343,7 +344,7 @@ function restrictedArea($user, $features, $objectid=0, $tableandshare='', $featu * This function is also called by restrictedArea * * @param User $user User to check - * @param array $featuresarray Features/modules to check. Example: ('user','service') + * @param array $featuresarray Features/modules to check. Example: ('user','service') * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany modume. Param not used if objectid is null (optional). * @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'. @@ -367,7 +368,7 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh // For backward compatibility if ($feature == 'member') $feature='adherent'; - + $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie'); // Test on entity only (Objects with no link to company) $checksoc = array('societe'); // Test for societe object $checkother = array('contact'); // Test on entity and link to societe. Allowed if link is empty (Ex: contacts...). diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 9715abfd77b..af411045533 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -4,7 +4,7 @@ * Copyright (c) 2004-2012 Laurent Destailleur * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2016 Regis Houssin + * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2005 Lionel Cousteix * Copyright (C) 2011 Herve Prot * Copyright (C) 2013-2014 Philippe Grand @@ -115,21 +115,21 @@ class User extends CommonObject public $parentof; // To store an array of all parents for all ids. public $accountancy_code; // Accountancy code in prevision of the complete accountancy module - + public $thm; // Average cost of employee - Used for valuation of time spent public $tjm; // Average cost of employee - - public $salary; // Monthly salary - Denormalized value from llx_user_employment + + public $salary; // Monthly salary - Denormalized value from llx_user_employment public $salaryextra; // Monthly salary extra - Denormalized value from llx_user_employment public $weeklyhours; // Weekly hours - Denormalized value from llx_user_employment public $color; // Define background color for user in agenda - + public $dateemployment; // Define date of employment by company private $cache_childids; - - + + /** * Constructor de la classe * @@ -462,13 +462,13 @@ class User extends CommonObject if (! $error && ! $notrigger) { $this->context = array('audit'=>$langs->trans("PermissionsAdd")); - + // Call trigger $result=$this->call_trigger('USER_MODIFY',$user); if ($result < 0) { $error++; } // End call triggers } - + if ($error) { $this->db->rollback(); return -$error; @@ -571,13 +571,13 @@ class User extends CommonObject if (! $error && ! $notrigger) { $this->context = array('audit'=>$langs->trans("PermissionsDelete")); - + // Call trigger $result=$this->call_trigger('USER_MODIFY',$user); if ($result < 0) { $error++; } // End call triggers } - + if ($error) { $this->db->rollback(); return -$error; @@ -965,7 +965,7 @@ class User extends CommonObject $sql = "SELECT login FROM ".MAIN_DB_PREFIX."user"; $sql.= " WHERE login ='".$this->db->escape($this->login)."'"; $sql.= " AND entity IN (0,".$this->db->escape($conf->entity).")"; - + dol_syslog(get_class($this)."::create", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) @@ -998,7 +998,7 @@ class User extends CommonObject $this->db->rollback(); return -5; } - + // Update minor fields $result = $this->update($user,1,1); if ($result < 0) @@ -1018,7 +1018,7 @@ class User extends CommonObject $entrepot->country_id = $mysoc->country_id; $entrepot->create($user); } - + if (! $notrigger) { // Call trigger @@ -1087,7 +1087,7 @@ class User extends CommonObject $this->state_id = $contact->state_id; $this->country_id = $contact->country_id; $this->employee = 0; - + if (empty($login)) $login=strtolower(substr($contact->firstname, 0, 4)) . strtolower(substr($contact->lastname, 0, 4)); $this->login = $login; @@ -1350,7 +1350,7 @@ class User extends CommonObject $sql.= ", weeklyhours= ".($this->weeklyhours != ''?"'".$this->db->escape($this->weeklyhours)."'":"null"); $sql.= ", entity = '".$this->db->escape($this->entity)."'"; $sql.= " WHERE rowid = ".$this->id; - + dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) @@ -1387,7 +1387,7 @@ class User extends CommonObject if ($this->fk_member > 0 && ! $nosyncmember) { dol_syslog(get_class($this)."::update user is linked with a member. We try to update member too.", LOG_DEBUG); - + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; // This user is linked with a member, so we also update members informations @@ -1401,9 +1401,9 @@ class User extends CommonObject $adh->lastname=$this->lastname; $adh->login=$this->login; $adh->gender=$this->gender; - + $adh->pass=$this->pass; - + $adh->societe=(empty($adh->societe) && $this->societe_id ? $this->societe_id : $adh->societe); $adh->email=$this->email; @@ -1686,7 +1686,7 @@ class User extends CommonObject $appli=constant('DOL_APPLICATION_TITLE'); if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE; - + $subject = $outputlangs->transnoentitiesnoconv("SubjectNewPassword", $appli); // Define $urlwithroot @@ -1696,23 +1696,23 @@ class User extends CommonObject if (! $changelater) { $url = $urlwithroot.'/'; - + $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived").".\n"; $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyIs")." :\n\n"; $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n"; $mesg.= $outputlangs->transnoentitiesnoconv("Password")." = ".$password."\n\n"; $mesg.= "\n"; - + $mesg.= $outputlangs->transnoentitiesnoconv("ClickHereToGoTo", $appli).': '.$url."\n\n"; $mesg.= "--\n"; $mesg.= $user->getFullName($outputlangs); // Username that make then sending - + dol_syslog(get_class($this)."::send_password changelater is off, url=".$url); } else { $url = $urlwithroot.'/user/passwordforgotten.php?action=validatenewpassword&username='.$this->login."&passwordhash=".dol_hash($password); - + $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived")."\n"; $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyWillBe")." :\n\n"; $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n"; @@ -1721,7 +1721,7 @@ class User extends CommonObject $mesg.= $outputlangs->transnoentitiesnoconv("YouMustClickToChange")." :\n"; $mesg.= $url."\n\n"; $mesg.= $outputlangs->transnoentitiesnoconv("ForgetIfNothing")."\n\n"; - + dol_syslog(get_class($this)."::send_password changelater is on, url=".$url); } @@ -1870,7 +1870,7 @@ class User extends CommonObject { $this->newgroupid=$group; // deprecated. Remove this. $this->context = array('audit'=>$langs->trans("UserSetInGroup"), 'newgroupid'=>$group); - + // Call trigger $result=$this->call_trigger('USER_SETINGROUP',$user); if ($result < 0) { $error++; } @@ -1925,7 +1925,7 @@ class User extends CommonObject { $this->oldgroupid=$group; // deprecated. Remove this. $this->context = array('audit'=>$langs->trans("UserRemovedFromGroup"), 'oldgroupid'=>$group); - + // Call trigger $result=$this->call_trigger('USER_REMOVEFROMGROUP',$user); if ($result < 0) { $error++; } @@ -2000,7 +2000,7 @@ class User extends CommonObject $result = ''; $companylink = ''; $link = ''; - + $label = '' . $langs->trans("User") . ''; $label.= '
    '; $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,'',''); @@ -2047,10 +2047,10 @@ class User extends CommonObject if (! empty($_SESSION["disablemodules"])) $label.= '
    '.$langs->trans("DisabledModules").':
    '.join(', ',explode(',',$_SESSION["disablemodules"])); } - + if ($option == 'leave') $link.= 'fullname=$this->getFullName($langs); // Champs - if ($this->fullname && ! empty($conf->global->LDAP_FIELD_FULLNAME)) $info[$conf->global->LDAP_FIELD_FULLNAME] = $this->fullname; - if ($this->lastname && ! empty($conf->global->LDAP_FIELD_NAME)) $info[$conf->global->LDAP_FIELD_NAME] = $this->lastname; - if ($this->firstname && ! empty($conf->global->LDAP_FIELD_FIRSTNAME)) $info[$conf->global->LDAP_FIELD_FIRSTNAME] = $this->firstname; - if ($this->login && ! empty($conf->global->LDAP_FIELD_LOGIN)) $info[$conf->global->LDAP_FIELD_LOGIN] = $this->login; - if ($this->login && ! empty($conf->global->LDAP_FIELD_LOGIN_SAMBA)) $info[$conf->global->LDAP_FIELD_LOGIN_SAMBA] = $this->login; - if ($this->pass && ! empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte - if ($this->ldap_sid && ! empty($conf->global->LDAP_FIELD_SID)) $info[$conf->global->LDAP_FIELD_SID] = $this->ldap_sid; + if ($this->fullname && ! empty($conf->global->LDAP_FIELD_FULLNAME)) $info[$conf->global->LDAP_FIELD_FULLNAME] = $this->fullname; + if ($this->lastname && ! empty($conf->global->LDAP_FIELD_NAME)) $info[$conf->global->LDAP_FIELD_NAME] = $this->lastname; + if ($this->firstname && ! empty($conf->global->LDAP_FIELD_FIRSTNAME)) $info[$conf->global->LDAP_FIELD_FIRSTNAME] = $this->firstname; + if ($this->login && ! empty($conf->global->LDAP_FIELD_LOGIN)) $info[$conf->global->LDAP_FIELD_LOGIN] = $this->login; + if ($this->login && ! empty($conf->global->LDAP_FIELD_LOGIN_SAMBA)) $info[$conf->global->LDAP_FIELD_LOGIN_SAMBA] = $this->login; + if ($this->pass && ! empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte + if ($this->pass && ! empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // md5 for OpenLdap TODO add type of encryption + if ($this->ldap_sid && ! empty($conf->global->LDAP_FIELD_SID)) $info[$conf->global->LDAP_FIELD_SID] = $this->ldap_sid; if ($this->societe_id > 0) { $soc = new Societe($this->db); @@ -2466,7 +2467,7 @@ class User extends CommonObject * Return and array with all instanciated first level children users of current user * * @return void - * @see getAllChildIds + * @see getAllChildIds */ function get_children() { @@ -2597,7 +2598,7 @@ class User extends CommonObject foreach($this->users as $key => $val) { $result = $this->build_path_from_id_user($key,0); // Process a branch from the root user key (this user has no parent) - if ($result < 0) + if ($result < 0) { $this->error='ErrorLoopInHierarchy'; return -1; @@ -2640,7 +2641,7 @@ class User extends CommonObject function getAllChildIds($addcurrentuser=0) { $childids=array(); - + if (isset($this->cache_childids[$this->id])) { $childids = $this->cache_childids[$this->id]; @@ -2649,20 +2650,20 @@ class User extends CommonObject { // Init this->users $this->get_full_tree(); - + $idtoscan=$this->id; - + dol_syslog("Build childid for id = ".$idtoscan); foreach($this->users as $id => $val) { //var_dump($val['fullpath']); if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id']; } - } + } $this->cache_childids[$this->id] = $childids; - + if ($addcurrentuser) $childids[$this->id]=$this->id; - + return $childids; } @@ -2693,7 +2694,7 @@ class User extends CommonObject $useridfound=array($id_user); while (! empty($this->parentof[$cursor_user])) { - if (in_array($this->parentof[$cursor_user], $useridfound)) + if (in_array($this->parentof[$cursor_user], $useridfound)) { dol_syslog("The hierarchy of user has a recursive loop", LOG_WARNING); return -1; // Should not happen. Protection against looping hierarchy From cd349ab6cc19aadf4292c2cc98b76ab91b0d7d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Mon, 13 Mar 2017 20:17:31 +0100 Subject: [PATCH 091/410] FIX #6505 Project elements page shows greyed-out links even if the option to show actions not available is disabled Close #6505 --- htdocs/projet/element.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 9fc957fa66b..80cc6b11539 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -612,7 +612,9 @@ foreach ($listofreferent as $key => $value) { $addform.='
    '; if ($testnew) $addform.=''.($buttonnew?$langs->trans($buttonnew):$langs->trans("Create")).''; - else $addform.=''.($buttonnew?$langs->trans($buttonnew):$langs->trans("Create")).''; + elseif (empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) { + $addform.=''.($buttonnew?$langs->trans($buttonnew):$langs->trans("Create")).''; + } $addform.='
    '; } From 15d0e6abc5453c6301e7e92ca378b5077e196c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Mon, 13 Mar 2017 20:33:21 +0100 Subject: [PATCH 092/410] Corrected bug where product multiprices admin page would not render properly due to a PHP fatal error --- htdocs/product/admin/price_rules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/admin/price_rules.php b/htdocs/product/admin/price_rules.php index e284572e7e7..224acd9c04b 100644 --- a/htdocs/product/admin/price_rules.php +++ b/htdocs/product/admin/price_rules.php @@ -155,7 +155,6 @@ $genPriceOptions = function($level) use ($price_options) { return $return; }; - ?> @@ -173,7 +172,8 @@ $genPriceOptions = function($level) use ($price_options) {
    trans('SellingPrice').' '.$i; // Label of price - if (! empty($conf->global->{"PRODUIT_MULTIPRICES_LABEL$i"})) { + $keyforlabel='PRODUIT_MULTIPRICES_LABEL'.$i; + if (! empty($conf->global->$keyforlabel)) { print ' - '.$langs->trans($conf->global->$keyforlabel); } ?> From 14ed67499ed9e612e5a80444e61ee4d79fd10391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josep=20Llu=C3=ADs?= Date: Tue, 14 Mar 2017 00:26:47 +0100 Subject: [PATCH 093/410] FIX html tag Fix incorrect html tag not closed --- htdocs/societe/tpl/linesalesrepresentative.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/tpl/linesalesrepresentative.tpl.php b/htdocs/societe/tpl/linesalesrepresentative.tpl.php index 0c3dd0656b8..d8d4b4b08bb 100644 --- a/htdocs/societe/tpl/linesalesrepresentative.tpl.php +++ b/htdocs/societe/tpl/linesalesrepresentative.tpl.php @@ -3,7 +3,7 @@ print '
    '; print '
    '; print $langs->trans('SalesRepresentatives'); - print ''; + print ''; if ($user->rights->societe->creer && $user->rights->societe->client->voir) print ''.img_edit('',1).''; else From 192a825de8548ed7cbbbafbb4cc0f841c60527f7 Mon Sep 17 00:00:00 2001 From: arnaud Date: Tue, 14 Mar 2017 09:25:29 +0100 Subject: [PATCH 094/410] NEW ODT docs for USER USERGROUP CONTRACT and PRODUCT class --- htdocs/core/actions_builddoc.inc.php | 3 +- htdocs/core/class/html.formfile.class.php | 29 +- htdocs/core/lib/functions2.lib.php | 2 +- .../doc/doc_generic_contract_odt.modules.php | 495 +++++++++++++++++ .../doc/doc_generic_product_odt.modules.php | 499 +++++++++++++++++ .../user/doc/doc_generic_user_odt.modules.php | 433 +++++++++++++++ .../doc/doc_generic_usergroup_odt.modules.php | 501 ++++++++++++++++++ .../usergroup/modules_usergroup.class.php | 2 +- .../install/doctemplates/contracts/index.html | 0 .../contracts/template_contract.odt | Bin 0 -> 25866 bytes .../install/doctemplates/products/index.html | 0 .../products/template_product.odt | Bin 0 -> 17591 bytes .../doctemplates/usergroups/index.html | 0 .../usergroups/template_usergroup.odt | Bin 0 -> 17537 bytes htdocs/install/doctemplates/users/index.html | 0 .../doctemplates/users/template_user.odt | Bin 0 -> 13431 bytes .../install/mysql/migration/5.0.0-6.0.0.sql | 8 + htdocs/install/step1.php | 12 +- htdocs/product/admin/product.php | 264 ++++----- htdocs/product/card.php | 24 +- htdocs/user/group/card.php | 10 +- 21 files changed, 2141 insertions(+), 141 deletions(-) create mode 100644 htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php create mode 100644 htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php create mode 100644 htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php create mode 100644 htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php create mode 100644 htdocs/install/doctemplates/contracts/index.html create mode 100755 htdocs/install/doctemplates/contracts/template_contract.odt create mode 100644 htdocs/install/doctemplates/products/index.html create mode 100644 htdocs/install/doctemplates/products/template_product.odt create mode 100644 htdocs/install/doctemplates/usergroups/index.html create mode 100755 htdocs/install/doctemplates/usergroups/template_usergroup.odt create mode 100644 htdocs/install/doctemplates/users/index.html create mode 100755 htdocs/install/doctemplates/users/template_user.odt diff --git a/htdocs/core/actions_builddoc.inc.php b/htdocs/core/actions_builddoc.inc.php index adbc17a4161..94f4229e0db 100644 --- a/htdocs/core/actions_builddoc.inc.php +++ b/htdocs/core/actions_builddoc.inc.php @@ -33,13 +33,14 @@ // Build doc if ($action == 'builddoc' && $permissioncreate) { + if (is_numeric(GETPOST('model'))) { $error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Model")); } else { - // Reload to get all modified line records and be ready for hooks + // Reload to get all modified line records and be ready for hooks $ret = $object->fetch($id); $ret = $object->fetch_thirdparty(); /*if (empty($object->id) || ! $object->id > 0) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 44b6a8adcd7..5aa699c055c 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -333,7 +333,7 @@ class FormFile $titletoshow=$langs->trans("Documents"); if (! empty($title)) $titletoshow=$title; - + // Show table if ($genallowed) { @@ -439,6 +439,15 @@ class FormFile $modellist=ModelePDFTask::liste_modeles($this->db); } } + elseif ($modulepart == 'product') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php'; + $modellist=ModelePDFProduct::liste_modeles($this->db); + } + } elseif ($modulepart == 'export') { if (is_array($genallowed)) $modellist=$genallowed; @@ -524,6 +533,24 @@ class FormFile { $modellist=''; } + elseif ($modulepart == 'user') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.class.php'; + $modellist=ModelePDFUser::liste_modeles($this->db); + } + } + elseif ($modulepart == 'usergroup') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/usergroup/modules_usergroup.class.php'; + $modellist=ModelePDFUserGroup::liste_modeles($this->db); + } + } else //if ($modulepart != 'agenda') { // For normalized standard modules diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 0a4eb1b0fe1..dc0541e39ef 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1509,7 +1509,7 @@ function getListOfModels($db,$type,$maxfilenamelength=0) $sql.= " WHERE type = '".$type."'"; $sql.= " AND entity IN (0,".(! empty($conf->multicompany->enabled) && ! empty($conf->multicompany->transverse_mode)?"1,":"").$conf->entity.")"; $sql.= " ORDER BY description DESC"; - + dol_syslog('/core/lib/function2.lib.php::getListOfModels', LOG_DEBUG); $resql = $db->query($sql); if ($resql) diff --git a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php new file mode 100644 index 00000000000..a58d00455e8 --- /dev/null +++ b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php @@ -0,0 +1,495 @@ + + * Copyright (C) 2012 Juanjo Menent +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* or see http://www.gnu.org/ +*/ + +/** + * \file htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php + * \ingroup societe + * \brief File of class to build ODT documents for third parties + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_contract_odt extends ModelePDFContract +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'CONTRACT_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva CONTRACT_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".
    \n"; + $texte.= '
    '; + $texte.= ''; + $texte.= ''; + $texte.= ''; + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + $texte.= ''; + $texte.= ''; + $texte.= ''; + } + $texte.= ''; + + // List of directories area + $texte.= ''; + + $texte.= ''; + $texte.= ''; + + $texte.= '
    '; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->CONTRACT_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.(ods|odt)'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + + // Scan directories + if (count($listofdir)) + { + $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + // Model for creation + $liste=ModelePDFContract::liste_modeles($this->db); + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '"; + + $texte.= ''; + $texte.= ''; + $texte.= '"; + $texte.= ''; + + $texte.= ''; + $texte.= '"; + $texte.= '
    '.$langs->trans("DefaultModelPropalCreate").''; + $texte.= $form->selectarray('value2',$liste,$conf->global->CONTRACT_ADDON_PDF_ODT_DEFAULT); + $texte.= "
    '.$langs->trans("DefaultModelPropalToBill").''; + $texte.= $form->selectarray('value3',$liste,$conf->global->CONTRACT_ADDON_PDF_ODT_TOBILL); + $texte.= "
    '.$langs->trans("DefaultModelPropalClosed").''; + $texte.= $form->selectarray('value4',$liste,$conf->global->CONTRACT_ADDON_PDF_ODT_CLOSED); + $texte.= "
    '; + } + } + + $texte.= '
    '; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
    '; + $texte.= '
    '; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param Contract $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$langs,$conf,$mysoc,$hookmanager; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + + if ($conf->contrat->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Contract($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->contrat->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.od(t|s)/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + + $newfiletmp=$objectref.'_'.$newfiletmp; + + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + if ( ! empty($conf->global->MAIN_DOC_USE_TIMING)) + { + $format=$conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') $format='%Y%m%d%H%M%S'; + $filename=$newfiletmp.'-'.dol_print_date(dol_now(),$format).'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } + $file=$dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->contrat->dir_temp=".$conf->contrat->dir_temp; + + dol_mkdir($conf->contrat->dir_temp); + + + // If CUSTOMER contact defined on contract, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else { + $socobject = $object->client; + // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + $contactobject = $object->contact; + } + } + else + { + $socobject=$object->client; + } + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->name, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Line of free text + $newfreetext=''; + $paramfreetext='contract_FREE_TEXT'; + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->contrat->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } + catch(Exception $e) + { + $this->error=$e->getMessage(); + return -1; + } + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + // Make substitutions into odt of freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + + // Make substitutions into odt + $array_contract=$this->get_substitutionarray_each_var_object($object, $outputlangs); + $array_user=$this->get_substitutionarray_user($user,$outputlangs); + $array_soc=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + $array_thirdparty=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + $array_objet=$this->get_substitutionarray_object($object,$outputlangs); + $array_other=$this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in contract as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact) + $array_thirdparty_contact=$this->get_substitutionarray_contact($contactobject,$outputlangs,'contact'); + + $tmparray = array_merge($array_contract,$array_user,$array_soc,$array_thirdparty,$array_objet,$array_other,$array_thirdparty_contact); + complete_substitutions_array($tmparray, $outputlangs, $object); + $object->fetch_optionals(); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of lines + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_lines($line,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace labels translated + $tmparray=$outputlangs->get_translations_for_substitutions(); + foreach($tmparray as $key=>$value) + { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + } + + // Call the beforeODTSave hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Write new file + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + try { + $odfHandler->exportAsAttachedPDF($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + else { + try { + $odfHandler->saveToDisk($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + + $reshook=$hookmanager->executeHooks('afterODTCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} + diff --git a/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php b/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php new file mode 100644 index 00000000000..3341ad20f08 --- /dev/null +++ b/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php @@ -0,0 +1,499 @@ + + * Copyright (C) 2012 Juanjo Menent +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* or see http://www.gnu.org/ +*/ + +/** + * \file htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php + * \ingroup societe + * \brief File of class to build ODT documents for third parties + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_product_odt extends ModelePDFProduct +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'PRODUCT_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva PRODUCT_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".
    \n"; + $texte.= '
    '; + $texte.= ''; + $texte.= ''; + $texte.= ''; + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + $texte.= ''; + $texte.= ''; + $texte.= ''; + } + $texte.= ''; + + // List of directories area + $texte.= ''; + + $texte.= ''; + $texte.= ''; + + $texte.= '
    '; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->PRODUCT_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.(ods|odt)'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + + // Scan directories + if (count($listofdir)) + { + $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + + /*if ($conf->global->MAIN_PRODUCT_CHOOSE_ODT_DOCUMENT > 0) + { + // Model for creation + $liste=ModelePDFProduct::liste_modeles($this->db); + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '"; + + $texte.= ''; + $texte.= ''; + $texte.= '"; + $texte.= ''; + + $texte.= ''; + $texte.= '"; + $texte.= '
    '.$langs->trans("DefaultModelPropalCreate").''; + $texte.= $form->selectarray('value2',$liste,$conf->global->PRODUCT_ADDON_PDF_ODT_DEFAULT); + $texte.= "
    '.$langs->trans("DefaultModelPropalToBill").''; + $texte.= $form->selectarray('value3',$liste,$conf->global->PRODUCT_ADDON_PDF_ODT_TOBILL); + $texte.= "
    '.$langs->trans("DefaultModelPropalClosed").''; + $texte.= $form->selectarray('value4',$liste,$conf->global->PRODUCT_ADDON_PDF_ODT_CLOSED); + $texte.= "
    '; + }*/ + } + + $texte.= '
    '; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
    '; + $texte.= '
    '; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param Product $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $product,$langs,$conf,$mysoc,$hookmanager,$user; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + if ($conf->produit->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Product($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + $productFournisseur = new ProductFournisseur($this->db); + $supplierprices = $productFournisseur->list_product_fournisseur_price($object->id); + $object->supplierprices = $supplierprices; + + $dir = $conf->produit->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.od(t|s)/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + + $newfiletmp=$objectref.'_'.$newfiletmp; + + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + if ( ! empty($conf->global->MAIN_DOC_USE_TIMING)) + { + $format=$conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') $format='%Y%m%d%H%M%S'; + $filename=$newfiletmp.'-'.dol_print_date(dol_now(),$format).'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } + $file=$dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->produit->dir_temp=".$conf->produit->dir_temp; + + dol_mkdir($conf->produit->dir_temp); + + + // If CUSTOMER contact defined on product, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else { + $socobject = $object->client; + // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + $contactobject = $object->contact; + } + } + else + { + $socobject=$object->client; + } + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->name, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Line of free text + $newfreetext=''; + $paramfreetext='product_FREE_TEXT'; + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->produit->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } + catch(Exception $e) + { + $this->error=$e->getMessage(); + return -1; + } + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + // Make substitutions into odt of freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + + // Make substitutions into odt + $array_global = $this->get_substitutionarray_each_var_object($object, $outputlangs); + $array_user=$this->get_substitutionarray_user($user,$outputlangs); + $array_soc=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + $array_thirdparty=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + //$array_objet=$this->get_substitutionarray_object($object,$outputlangs); + $array_other=$this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in product as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact) + $array_thirdparty_contact=$this->get_substitutionarray_contact($contactobject,$outputlangs,'contact'); + + $tmparray = array_merge($array_global,$array_user,$array_soc,$array_thirdparty,$array_other,$array_thirdparty_contact); + complete_substitutions_array($tmparray, $outputlangs, $object); + $object->fetch_optionals(); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of lines + try + { + $listlines = $odfHandler->setSegment('supplierprices'); + if(!empty($object->supplierprices)){ + foreach ($object->supplierprices as $supplierprice) + { + $array_lines = $this->get_substitutionarray_each_var_object($supplierprice, $outputlangs); + complete_substitutions_array($array_lines, $outputlangs, $object, $supplierprice, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$array_lines,'line'=>$supplierprice); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($array_lines as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace labels translated + $tmparray=$outputlangs->get_translations_for_substitutions(); + foreach($tmparray as $key=>$value) + { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + } + + // Call the beforeODTSave hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Write new file + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + try { + $odfHandler->exportAsAttachedPDF($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + else { + try { + $odfHandler->saveToDisk($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + + $reshook=$hookmanager->executeHooks('afterODTCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} + diff --git a/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php new file mode 100644 index 00000000000..b7079dde30e --- /dev/null +++ b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php @@ -0,0 +1,433 @@ + + * Copyright (C) 2012 Juanjo Menent +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* or see http://www.gnu.org/ +*/ + +/** + * \file htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php + * \ingroup societe + * \brief File of class to build ODT documents for third parties + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_user_odt extends ModelePDFUser +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'USER_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva USER_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".
    \n"; + $texte.= '
    '; + $texte.= ''; + $texte.= ''; + $texte.= ''; + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + $texte.= ''; + $texte.= ''; + $texte.= ''; + } + $texte.= ''; + + // List of directories area + $texte.= ''; + + $texte.= ''; + $texte.= ''; + + $texte.= '
    '; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->USER_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.(ods|odt)'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + + // Scan directories + if (count($listofdir)) + { + $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + // Model for creation + $liste=ModelePDFUser::liste_modeles($this->db); + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '"; + + $texte.= ''; + $texte.= ''; + $texte.= '"; + $texte.= ''; + + $texte.= ''; + $texte.= '"; + $texte.= '
    '.$langs->trans("DefaultModelPropalCreate").''; + $texte.= $form->selectarray('value2',$liste,$conf->global->USER_ADDON_PDF_ODT_DEFAULT); + $texte.= "
    '.$langs->trans("DefaultModelPropalToBill").''; + $texte.= $form->selectarray('value3',$liste,$conf->global->USER_ADDON_PDF_ODT_TOBILL); + $texte.= "
    '.$langs->trans("DefaultModelPropalClosed").''; + $texte.= $form->selectarray('value4',$liste,$conf->global->USER_ADDON_PDF_ODT_CLOSED); + $texte.= "
    '; + } + } + + $texte.= '
    '; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
    '; + $texte.= '
    '; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param User $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$langs,$conf,$mysoc,$hookmanager; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + + if ($conf->user->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new User($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->user->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.od(t|s)/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + + $newfiletmp=$objectref.'_'.$newfiletmp; + + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + if ( ! empty($conf->global->MAIN_DOC_USE_TIMING)) + { + $format=$conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') $format='%Y%m%d%H%M%S'; + $filename=$newfiletmp.'-'.dol_print_date(dol_now(),$format).'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } + $file=$dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->user->dir_temp=".$conf->user->dir_temp; + + dol_mkdir($conf->user->dir_temp); + + + // If CUSTOMER contact defined on user, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else { + $socobject = $object->client; + // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + $contactobject = $object->contact; + } + } + else + { + $socobject=$object->client; + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->user->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } + catch(Exception $e) + { + $this->error=$e->getMessage(); + return -1; + } + + // Make substitutions into odt + $array_user=$this->get_substitutionarray_user($object,$outputlangs); + $array_soc=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + $array_thirdparty=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + $array_other=$this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in user as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact) + $array_thirdparty_contact=$this->get_substitutionarray_contact($contactobject,$outputlangs,'contact'); + + $tmparray = array_merge($array_user,$array_soc,$array_thirdparty,$array_other,$array_thirdparty_contact); + complete_substitutions_array($tmparray, $outputlangs, $object); + $object->fetch_optionals(); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Replace labels translated + $tmparray=$outputlangs->get_translations_for_substitutions(); + foreach($tmparray as $key=>$value) + { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + } + + // Call the beforeODTSave hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Write new file + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + try { + $odfHandler->exportAsAttachedPDF($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + else { + try { + $odfHandler->saveToDisk($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + + $reshook=$hookmanager->executeHooks('afterODTCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + + function get_substitutionarray_object($object,$outputlangs) { + foreach($object as $key => $value) { + if(!is_array($value) && !is_object($value)) { + $array_other['object_'.$key] = $value; + } + } + return $array_other; + } + +} + diff --git a/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php new file mode 100644 index 00000000000..35367052796 --- /dev/null +++ b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php @@ -0,0 +1,501 @@ + + * Copyright (C) 2012 Juanjo Menent +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* or see http://www.gnu.org/ +*/ + +/** + * \file htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php + * \ingroup societe + * \brief File of class to build ODT documents for third parties + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/usergroup/modules_usergroup.class.php'; +require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; +require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_usergroup_odt extends ModelePDFUserGroup +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'USERGROUP_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva USERGROUP_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".
    \n"; + $texte.= '
    '; + $texte.= ''; + $texte.= ''; + $texte.= ''; + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + $texte.= ''; + $texte.= ''; + $texte.= ''; + } + $texte.= ''; + + // List of directories area + $texte.= ''; + + $texte.= ''; + $texte.= ''; + + $texte.= '
    '; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->USERGROUP_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.(ods|odt)'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + $texte.= ''; + $texte.= '
    '; + + // Scan directories + if (count($listofdir)) + { + $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + // Model for creation + $liste=ModelePDFUserGroup::liste_modeles($this->db); + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '"; + + $texte.= ''; + $texte.= ''; + $texte.= '"; + $texte.= ''; + + $texte.= ''; + $texte.= '"; + $texte.= '
    '.$langs->trans("DefaultModelPropalCreate").''; + $texte.= $form->selectarray('value2',$liste,$conf->global->USERGROUP_ADDON_PDF_ODT_DEFAULT); + $texte.= "
    '.$langs->trans("DefaultModelPropalToBill").''; + $texte.= $form->selectarray('value3',$liste,$conf->global->USERGROUP_ADDON_PDF_ODT_TOBILL); + $texte.= "
    '.$langs->trans("DefaultModelPropalClosed").''; + $texte.= $form->selectarray('value4',$liste,$conf->global->USERGROUP_ADDON_PDF_ODT_CLOSED); + $texte.= "
    '; + } + } + + $texte.= '
    '; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
    '; + $texte.= '
    '; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param UserGroup $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$langs,$conf,$mysoc,$hookmanager; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + + if ($conf->user->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new UserGroup($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->usergroup->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.od(t|s)/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + + $newfiletmp=$objectref.'_'.$newfiletmp; + + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + if ( ! empty($conf->global->MAIN_DOC_USE_TIMING)) + { + $format=$conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') $format='%Y%m%d%H%M%S'; + $filename=$newfiletmp.'-'.dol_print_date(dol_now(),$format).'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } + $file=$dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->user->dir_temp=".$conf->user->dir_temp; + + dol_mkdir($conf->user->dir_temp); + + + // If CUSTOMER contact defined on user, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else { + $socobject = $object->client; + // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + $contactobject = $object->contact; + } + } + else + { + $socobject=$object->client; + } + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->name, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Line of free text + $newfreetext=''; + $paramfreetext='user_FREE_TEXT'; + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->user->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } + catch(Exception $e) + { + $this->error=$e->getMessage(); + return -1; + } + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + // Make substitutions into odt of freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + + // Make substitutions into odt + $array_user=$this->get_substitutionarray_user($user,$outputlangs); + $array_global=$this->get_substitutionarray_each_var_object($object,$outputlangs); + $array_soc=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + $array_thirdparty=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + $array_objet=$this->get_substitutionarray_each_var_object($object,$outputlangs); + $array_other=$this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in user as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact) + $array_thirdparty_contact=$this->get_substitutionarray_contact($contactobject,$outputlangs,'contact'); + + $tmparray = array_merge($array_global,$array_user,$array_soc,$array_thirdparty,$array_objet,$array_other,$array_thirdparty_contact); + complete_substitutions_array($tmparray, $outputlangs, $object); + $object->fetch_optionals(); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key=>$value) + { + try + { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of lines + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->members as $u) + { + $tmparray=$this->get_substitutionarray_each_var_object($u,$outputlangs); + unset($tmparray['object_pass']); + unset($tmparray['object_pass_indatabase']); + complete_substitutions_array($tmparray, $outputlangs, $object, $user, "completesubstitutionarray_users"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$u); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key => $val) + { + try + { + if(!is_array($val)) { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace labels translated + $tmparray=$outputlangs->get_translations_for_substitutions(); + foreach($tmparray as $key=>$value) + { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + } + + // Call the beforeODTSave hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Write new file + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + try { + $odfHandler->exportAsAttachedPDF($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + else { + try { + $odfHandler->saveToDisk($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + + $reshook=$hookmanager->executeHooks('afterODTCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} + diff --git a/htdocs/core/modules/usergroup/modules_usergroup.class.php b/htdocs/core/modules/usergroup/modules_usergroup.class.php index f7d4778efe1..26edb08d57c 100644 --- a/htdocs/core/modules/usergroup/modules_usergroup.class.php +++ b/htdocs/core/modules/usergroup/modules_usergroup.class.php @@ -52,7 +52,7 @@ abstract class ModelePDFUserGroup extends CommonDocGenerator { global $conf; - $type='usergroup'; + $type='group'; $liste=array(); include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; diff --git a/htdocs/install/doctemplates/contracts/index.html b/htdocs/install/doctemplates/contracts/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/install/doctemplates/contracts/template_contract.odt b/htdocs/install/doctemplates/contracts/template_contract.odt new file mode 100755 index 0000000000000000000000000000000000000000..8ece83c989c9ff688337dbb0edf6febd47eb0dcf GIT binary patch literal 25866 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 jUx%REKSA)Nd85A==G7F@&=G4A!~e?R literal 0 HcmV?d00001 diff --git a/htdocs/install/doctemplates/products/index.html b/htdocs/install/doctemplates/products/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/install/doctemplates/products/template_product.odt b/htdocs/install/doctemplates/products/template_product.odt new file mode 100644 index 0000000000000000000000000000000000000000..344fcfa391aefbfef2b4ae85c5436e6c707adaa2 GIT binary patch literal 17591 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 literal 0 HcmV?d00001 diff --git a/htdocs/install/doctemplates/users/index.html b/htdocs/install/doctemplates/users/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/install/doctemplates/users/template_user.odt b/htdocs/install/doctemplates/users/template_user.odt new file mode 100755 index 0000000000000000000000000000000000000000..f1f1fcc2c5af013e85cb5dcdf394b8053b10e749 GIT binary patch literal 13431 zcmc(GWmp``)-Dh%1a}DT?gV!aZoz`P+u$193GN=;-QC^YJ-EBfCFlG0*>d*T&%M9y zn(3ZuS#MXZu6nC#)fzd;ci^ZXAkZKn466E{wfdM~$w5Fser<23KrBry4FN7ThPpO3 z7N+{T08?u#dPge*I%{2fQ+qmV8$&AtYkdbxLn{Csz|a{W_b0G5)Jh#7A_&N@4f735 z$;81@&q~+S!k!-RTawPk$~ag~Mhp%H8|Lj6I0T0HMUrilD8&79*Lw5&DHwPzeTR#i60)0z=QXJ`O4H2_*$0*xJjX7)fUFQA%W!Bi21IFeorIE<7qMI3_VRG$1}aHYqwZF(J`EJS#LIFCeWd(YG-^X=O4cH>fT_8_i~?Xv6)-oozcd|Kl?u$s9?LJBEo|s7 zuU@Rn8LBCmtZVIVYg^092j-Ll3$uZxZ~MlryjoyMHL$h_*jNOtYu%`-1Xec#+p2+0 zEx_ikfyTbs_KD?|uC1CbU`rRUdF-Nn9N0d8*jb+1QJ&jVU)0r7H{Vv$)zs71G&|Qe z*INzj>ug!-Z|Z)N-oc*1uAafs;hyfHzJZ~^-l5^)p3b$Nk?G!%rP1!?;nB&liSgcv z+1|;;(TVA?>BZ6I_35GB$FJs2*`>LKx!Hx4rMc z@p5f%Z*OP!YWwJF`}FbW-o@Dt@aW`f=lpK_>iOj2=J@*Y=>GY9_xS2)=kny>;dJNr z6nJ-eeEB9fPuGtx_tzIMSHS1To7dOZw}t=&0;zXPZ{FHSlZ3E0j?}?;L-M$hKD;SZB0e-RyrlaXYT;XX6RBcC+rU!#G{J zD798jC@O2eKBZmuylu2ze_pg+QRt0yKh1bOY}V$xt>$alby|CPw$^!m@bc26cfIJP z_qe(~+d6xFnD%mNqP6Z=W6ST|JsnK;Lg?Lmo~doD18WGlkiq!U z8c~*Z#*TZY5QyIqTR*E;-@u>D`i^w7#&r>IOb?XCy!|X(Yb@C|g+i**eN+fEz-n8H zu)~|`yt332qkmFr;972}cL~Q@inBzE4)j`6gVxGiYPoRK&vcUfQKN|rqJ4dOw89+6 zdsiy`0JL1Ck=sFW(JrADsh$PLo+a^X45*lS!tR7hrHfke>MK^WN25z`xc~Q)500NL znz{|lF>Aiw`L2E_QgpD`>a)Gp9U*@xS)m#|+mWfmT-{X{w*)iyV~UD26>*L84gJc*~CC|d;H zEYn=Qe27mR<~c8;w*QokqB6VaEVqPvQTIUGtQ8up3#cu~AMtj4sl3NxyJ131ictw} zij{7eTfmiL68}bFUt2I(8&$y9cZl3))7dgPOAk>1yP@apv@ZSxX-PMrpv1qE-S?&4 zOL4eLTaCB5WwY#v@8aN&?;-djufq!~8w<_HPj%P<9N)G@w03HO_YX6`Fc|BaaH2k| z9{J5Y5f-QdC+JT?>Cdht4gHKlj31SD7aJqD1{-5GTTVNkLlkF4La+8^OpW#upDMJ-ZI>P8|%xRUvzDR&>d>?Eb!rK?pdi;KUGvVg2+*8!K_V5a^O8->hL_V;P!vKB0jc z?*K#o*O;eK=SK_`Nm4&Oe{3nef*C}qqFKH8J~Ig_fn0CNZKOyM+BiiKXu|ZeooeV} z{}CyqGb=%HX+tAqGZ>X2(pZ`=vt3G+nYeVmpBwxXwv#S|ZMP~wrhSJ)7n7A_vZh!f z2y25X#?$0%Ha~wgWD51=tkvPQvvLLrxB1kksg)erfLr!n%I&AO@6Z(LwsSL^H%Dan z5i%|kie~95tuw{9cSM%AwgGZix|}0!iQlkB{2$#3JKTNG0-F4=`S!7$i1Bfc z1`0{$`&v?%)=)#}Z8fe0cQqUsc8iv@-TC-~;5C}w3W61(yK{DZD0(i_n04AOa5=m& z?$ryXw#zPjdfe*%vTcRC+I|vphmjTHjM-vG2(FmjGdCj9-bjQc=aFTqdz_Z;#^=1EYDW98ay7VbbJdcP6v+dBeKVm4 z;?^KQkes*1keH0XoSp98Z(Co#p*p0He_nbXw8sB zn=U#uHV>)it4uT^6{TESXYdbXdAD^&vrAJC-uA0u0tbd-3H(SG6*h0&a44q*9tybOTLwDk51raKkB8=n*tLg?@)cVGL#eMbk4 z1y7oQhjg@WcL!8l9nL==lmN|wbp1WLS>^qE*n9C>C-c#=iIThsXEk=riQ(rZYULI( z)WvsD`$J%svj`9P0mo9`n7>}4>3`_2jT13c9GcqM@Q*>rN={|>)nP=@?+ra=dad~@9Xb6*VUKz{)Op*W%0Bo+|)|?4wm$u2U`!!e1HNzGxcVU0< zCb;v+1VFrl&1XX@>mNKZZp9Or=<6=gKvexSgjMLDS|pYnGIXV@k|xW|15sNCmhkv# z-9LQ}8S*h;Q@n*QR6vlQv~WoJz3;n9C6cv--s>RmFz5afC@^JCUZU|y0G1z%QDINbKLNost z>EoJ48vdZCVV~_b<#GU9qe_x3{kGlOj{26U-M4B+s`m%t+^I5M&g?6x6U#!*!Z^-u z45^rSQCowmA5hR>7s|$Yv=lg&129;O9Qr0smMW$n%wk1UvK|jh%(KZ3BXgQ?)Dj7E zAMO3GfFHBwo+@&=%g{oq6WA?Ih-E|LWIb7K_9IE+YBtvv*HzWsN2=_ipxnk)@L|II zayRv~Nhn>r*W~!m{S+~Sz&a{2IFqojB0lJHrkTKAbSI+gYVdWLnHlhRBzac0*QH2C zT*K-|!Sw%F_0^&q5p%XYir=i*;qqh<6@hF3ujfOTczX0h0!@)!1$vk2lsRWF)oFQI zC-93Qd$3oE9rK|n_bMx>Hc2^DTSmJUKVeo(v)HV<#jGzOch~6W8lLJ3qu1P1fT%** zpM`_f)%vh{@+DW*&|KlqhX}y2sHv;3bD}mlUQT0zB)82OJG`4~%Vw0BwDy<2&VYCw zfLO~C7!UV$Ja6LE;j-%Mpg9EkfX4Jp@r$3x_Bl2tRCjB0wOOaMdv1}utbSj`$rY3 zUK2bj{Qc?+{ER3rwB3P%l8wr&+g9t0wa3=V+pO@RDB?>`?oYIl;XH)H(??YL`qTPD zMuq^rGe|X#Y^lh>2deb3;c9l^$R2H{!%;?|-nEUVBVa3tNOlKJgg2N=UTay!N=(dP zcc|#D4k+N}_B1Kq=&|~GtG)izN`C8UTU?jzQQ$EgkFs2Eq1NsK5bDR^`sC!zS>bkCuEbuGfS|FIkZuz-G@ z`x(Hu==>Z~Bs;LYd!v5xVyu;f8=dj}3Rl2IDSnsmBzM5YWwj3_?eaE4-cZR?Rijq7 z{k9fdcEB$GHm4n`*0Kh-hF)Neubv7scGqi8>#^ju?j|V{2PeARLNn6A(Gk+OGfSt! zUOZ)Q-$&?X_J*ibSXL}0ZPL->L#d9q_6*sH5HxNBc3I1~7f>^1fL>)Dse10tts-tsj(5 zo!eO8STh zs(F)sZ?gRB!-$4inv5^O_>}-J7IY)DXnubFx7<0%Kvud@lIj8qSZHF=Bp6X&c{yE_ zY+LOo*g4i<VO8auX>AIY%~p6YZ5bjEinVT(iK{cJv(YP zaKca9k7g+!m=21Ebv~BCkV?B*SMxVN3kEGIb<3d^usU($@WO{!L#5&S?MIst;W|4b z;_0E!;b9E&=7UDFSrxxFP%+4Q}0e{iKs&m&>^B zDw<3HIK3wMPJ*T|9})b-CKWW-P-j_)GN*YOpe}&H6ml!rnJNL2i{QUsPBDn@5-#J( zPAKDq+*Q|mR;l`ZnGJy{EZ|$`j3F##mF1 zJsudE-@}fw^%LWO90BtT6WS6ZF*tm7nH)YcRC52=Jl=w} zP%@zro%1nD=akT74UHws!hY{1L^11ir4ua_&n)PZvzGunJD7SH&8{U9K-R(^BKybtrBW0`Fi@Wv|#KrYetIRBh2CfX0;n5nBhWL;5?}F>7<^j zb&sCpON&{UdXec#WD?Lo(MMLS`JSnm^->u<*zndyGp(KD+^2<~QJWB>k_C~tnr%Le z9(OSQ^mf?xnr=#-XJth9pG};ExNiP#!_|q3lfjg0+H!#wc1FO9f$ZuYmSktA<1|jd zfGX7i{cHm5wY6a0oHYycZ7|wi5JU3kw0&nbq_)7hu1-fwiiN1I=p1QgdkQ%p%X>$s z_4ToSU~!s5Eb0r`&LqPu50P<)@(N7+t8Q(JgIsgN*~gohjG+|$`IOyikU&Z!HxLap zhHRww7#dZ*HdF9IG1a(17ZKEb_XEsRU6>jSr5NQ=O8|?4S?-4D{;EP7u6UPQqqBnS0HR?C$6r0&l1)IX?TMMH~X?lXiG%~9!Ca8 z)SZYJBoGxT1hBOY)ZDNTQ+MguYYEVC-vlrw?t~mod%}r9rzk7lcmGI~<53zAxu~)r zUO1_((XnmDgPq&29zMELp*K$WxwTrnd^B9oeEqlzM+Ntp(b`_1D{bAgp`|buv_K&h zZ-TY(t})UTES{!N@Eils)|?0m$w@i~u8hD;p-3XAPT(fZggRhK%ASg#?Jd`7v6dA+ zK;q->yYmjw2Q5yZO8y@6n&EaQvvR}R7e3kB7c~kF3b#uL6LB|>D8wnBnCGeI0#{GT zl){eWI$He4g&<*T5B6>>BMZ4W^0^uG>rkOqww$U)k!4niD{ms_sn z+X>(dm+U7*92X45!WuOZqmBJ}5p z_Tk$fxMjSj$hPZ|kMDSdSCXK)4bt^N;hg@$JUJbt})4kVc69z zc9xV9Egn;lgTBxKH5~C%Z5E1&ZF9bWB*=0S#=?jPTugvUlADU!UM-xnzScMP%6Xry z`U3Q-><}|#RysudP*z_+V;SuH<{mZ1R!t6zm_5Xt`mfP>jdo$0RU4gWBXsdV5_=@{SqglCto{Jx7!e@DH($V zC%<4y03@V1bG~(#7C)5QQPd6yu#Fna1b#!&tmLX^W4Np)!Ma`ZVQ-oV+1NUhMa)H` z$g?1Jj2{xyj-!>fHH>qAK3CSsYjwk*>z#=oCJBs1($q+5g(3kXv^TJ~7fNZ`u2!o&VRdyh2XyFt z23|3h$73s%@CsEG{f|)FA+xw4Lyi}1P7V6YG*h$O=5X9k%k9l-)Z$)ajo${A_AERW z=}zi|sXkicplcMz!MEO>Ikin+Nkdrp*_zt-m*_PS%gIPO#id-f1#R~_>gu@$8YOJURva3=CYXv5Kl|i(P|=ae*>Y>9<;!7#bH#)CMaH031w3)Hihx--XvC5e9a z0F9U^DaX6v;InGV8dZi2Dybd1DU95nZ&9;5mKZP&Qd!4@FR9OjB7WZG?6;jTsR4l$ zpQvTYu*vjupanSfa#NTx6a6X(vlf&poo~YnU7(bEMxZldOknA1L)bQh z!rgi%C01i45iapf4mNFa4@3hmC&f_N(c1igLpDd)=0$G3=r>4Z20QH9Z&PH&<@v!WD$kNYVkb0Y%}inoL(QfnZPz z5t)+gDjhnK`KjT#=%>8M!ZCYNWKCs=KJ*heL-1wxCSJy*9D&BerwP|>FM#aQ)}DYG zh8jBoeHJP;KJAlIv<9?Ufn5M?CkiSD86bl+SGYdYaM_PkWlr&WwWPd7+`^g4LnJlEbMQ5}P<4wAXkB`&eN-4>zX zJt71Q9y2TGR(wOLFE~Dr$xhx?qSa8E28{r)B*q^Z7YE0wCU_w|R_w+m)ol0ac;9Xe zG%{}mc9vrKYEs-plZIGo7(*7;gb(jGS0dP-xO#*k9{N36dlt5{=tu+ZQ+%Oo$Ac_$ zexUDTI2=g8Xof5UM=zm_F3OsRI7YtWm&t2bQh-uMr|U$P$6OWEXgC<)fR`D|N$=gtrkYi@SwB{d$+GEdG1HZAO`W)9+BPU<; zL~Lq)d#vM9nrj*mK#3sbu{^6t)eGK+&i;XK$u8zgk@?VGX}#5UYikRxKu;zoOpfn+ zdGNLA^%l9K4fF8aBx9^!?Pe))Jx!(kn z?r)m=g@a!n7Az}qPa%%uzR3;4szcv4;b2>yNua?SI~YSyQUxLn_1!yj9TLzl$K;M~ z>3Gkk?$}@M&(BGH%Tee*F3Nrhu2Z!vJ6FrtP@vdss-;Zd=?s$9w@DN=tqD1QiBVd0 z0a{isl~3t_9)HYf|6rtxJ%91CEc1oCr+Rc9mppJ7#k^ElkUYoB3&9&w*cDw*7&$u#hW)?n5XsP73tdujRz``LH=qtb0q#Yy4E`ypxI`jkf)BY&Rzw1&hh)9Xc*h3vv+X!*&yuh&m^lecFc_jok`a30zM20=MEUT zdV>MB4xLYWct7%LMVqPB(@49i38aaDh{55kdJ)~9r_BeYZbLeoVDbBB?F*yEe9RYx z$Y%J?JzEJHGb0dZSzOVcWeA_*t)vUm(+|c>BtfC5SKJ3%mSA}8Ln&QmV`PG3J%*8u zaE8zh9=$hgg8(`@vSrY?;AXD46d=gCoC*F!DZ})78xAirdoBf}jdQ!^_11I0rFTz! z5xk?gGeUHuIZ8Lk7dw+J$b25B<>mP~imfQ==@n|fK%0tav{%dlLxdbeC>w-iIHL2l zwjD%cF6TQgzE(0m^!_}}3(7Z>atn61NITx3&!N^}R4T={?_P0V)FX;_&!yxKdLY)c zAyksSqZZy6;oF1tqT>aW3_mFYp1mD6zVnzV`Mg7j?J|pm&3|F2NLG0#qeB zP&^R@DOT#C5Y1hI&!Mc{(4SQ+5GDL_2RH?b>Yy^bu9@~i9lGCb{%?FhjZ!$ zu=?Y;_^H6_vmg>=*h(CG>24ey-)T)aVu=NRs{s)V85uMt5VIwmQ4P4X46bAFV^suO zlx29!`We^sqg+9zJH^+T7CX4%Vil%=*j&{cBfc=p~r02_*%q zBGkw<8X7-r+wyT9hy2zOu6naaP~?lib7eSV(JKgT3hmQsL0}JsF1;cjGtMbAnYiSM zyUS*;PrRhnLXw!6dp<|xPD^xaw^oe*%&KJ%t6AAY>GP-mi5{BPq9qyWX{GBVaH4(& z;S-XQyS5Qrb#D}8FNd&F@3?pB&iB*ME3|u^SNw~R)O&g+z~x6N=7jAff3F^jIE+za zBj0aD`n!=u7IXec0e#&ehr|bTfkQkiWVq7uwq2hDx~#~|5LBfp$(v?W$E@+<9gxxU z!D?i5K31%6s2%*Yf_Iv(V<%otvsvk#G-9EJgn#Ys`_BHE8~AxT=K0Kx9Tn@;338At zCajulo|O!T6$2-YM-Opu^PFD^ft2NDAsL47BZAz6a3#q>s1aDy`&W(Z5=}Mm7=fsL z)uMYgjs!E!>n*}XBg=IA2~4r}-Fa6x9%Vaam|^udPgCuMGblUKDW#lbBkN~g%cNrz zRaPB*j(G;>`SjkvmgY6B4aqEOy^lgiXx6rnLTo{>&EhlAKCODzZj=Fu}! z3^aj8gS697^WwO2pqr zNHg>^9Pu2h*Ajw_*zOb~6PX6aGI4r0@$+-8?IrxFlIUT+z9T3oI}}D_YKi*HCa+^e zJvwRIVg(pW^+~W(%05ju5-cq$8F+@g7zwlOb+Hyol4O01_B*P;;97kq)B2huS{(AF z7Q=2R`?cPTC=hs-yR0YB)aM$d+8@995jGAoE~u3`km(jUOfFLQtX!tP zGww*Z7ky!k+e{SE9hV9imaB%no&ET>xt22|)Ru3c=>qFU$}Eh>O|o-TBA0e&!}DIyG8PaASX4$C{q6ofNt_i3z_OFUm3h*HiUm2711B}!&hSkxSSK~eRcEjUs9HEC-I}U$SUd{J^oj6q{#2xPz@!|wf!u_D#?2T&kG8FG0 zeg*tgP!~7v3MFoJHxysL4Kxj$=z6#<20sW?fxLR@MjT_!g{UEGVV{z}FUr&!=}vid z|EYj2r_seK$0kAd%7K>H&BL?)-O{wp;tTltb=Id?mOc`_)yrUGq0NuYBG}N)8A-0l?m!VZQQ22v-&@{3B*MdOLfo<9L1QH} ze!`li{)S@<{PYkIb`(R6W*Hr<0jd!6m&wR$Z4ohFrP&GMOQE_O; z`_r<)T8vj`Q#dDIam%(4bT6_7~6Vpq#_SE%KYwfN5B)h z%2}9M1*2Q1&>C1r5cQ2e{JqqWAHWx$)FnlYpwH>{_gPq;~uKK-&KEE06muw5Jy|1z76Z*#CnC{_c^#Z2r%7`#Y^)FZXw?zq1^!#m52&YtQo<1E>VhbUQSg`?*)2c8(#rjm2Lr;1Io zg?9-)Pfgu-{O=cPC$ryZfoWN9` zY79&+Y^xWg9ZZb!JY)^g$vOtj(O7_{M0#vGx(*hW}z2m4ifaJ{e8aNe37@4sfopkSyV|2^dY z&BlL_-~Ip~C;4ZszsC0et|I-G{BM!|zoGp0a{ssj@N2RAckw~`)6(}}760h}`9-$B zOW<48`r~rJUp4>eB=}dW`nPHq-WzHEuea#0T7RVdUk-%dWuD-V?u5VU{gLnfoKG(5 zKX(zoY5w+4jNhLC0`iMxeiv7o|7_%cWXC_hsNePeic|GBIDcfz|BmyEFMpTAzrnHj z6MO!5q(7I8g!Vs6_D44TADrJR&#xT(Mv1@p^mqCCH#q-=UH{4KzewtLss0<#-?{a_ z7x5Rn{w@c9gYq9-``^L-oFy{4|FqZd-1~ov^7U^}e&^yp+x(A2@{5gsm*_W?zvX5* WNr*Q`EeHtG+sEdOe=g{M9sM79yJa*0 literal 0 HcmV?d00001 diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 0dfc5f36925..0f8bfb4591e 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -114,3 +114,11 @@ UPDATE llx_const set value='moono-lisa' where value = 'moono' AND name = 'FCKEDI ALTER TABLE llx_product_price ADD COLUMN default_vat_code varchar(10) after tva_tx; ALTER TABLE llx_product_fournisseur_price ADD COLUMN default_vat_code varchar(10) after tva_tx; +ALTER TABLE llx_user ADD COLUMN model_pdf varchar(255); +ALTER TABLE llx_usergroup ADD COLUMN model_pdf varchar(255); + +INSERT INTO `llx_const` (`name`, `entity`, `value`, `type`, `visible`, `note`, `tms`) VALUES +('PRODUCT_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/products', 'chaine', 0, '', '2017-03-13 16:54:30'), +('CONTRACT_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/contracts', 'chaine', 0, '', '2017-03-13 13:07:27'), +('USERGROUP_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/usergroups', 'chaine', 0, '', '2017-03-10 15:25:06'), +('USER_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/users', 'chaine', 0, '', '2017-03-10 15:14:14') diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index b323c970a9d..b1a9fabb20d 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -457,7 +457,17 @@ if (! $error && $db->connected && $action == "set") require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $srcroot=$main_dir.'/install/doctemplates'; $destroot=$main_data_dir.'/doctemplates'; - $docs=array('thirdparties' => 'thirdparty', 'proposals' => 'proposal', 'orders' => 'order', 'invoices' => 'invoice', 'projects' => 'project', 'tasks' => 'task_summary'); + $docs=array('contracts' => 'contract' + , 'thirdparties' => 'thirdparty' + , 'products' => 'product' + , 'proposals' => 'proposal' + , 'orders' => 'order' + , 'invoices' => 'invoice' + , 'projects' => 'project' + , 'tasks' => 'task_summary' + , 'users' => 'user' + , 'usergroups' => 'usergroups' + ); foreach($docs as $cursordir => $cursorfile) { $src=$srcroot.'/'.$cursordir.'/template_'.$cursorfile.'.odt'; diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index c42c3981494..c879ab54059 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -44,9 +44,9 @@ if (! $user->admin || (empty($conf->product->enabled) && empty($conf->service->e $action = GETPOST('action','alpha'); $value = GETPOST('value','alpha'); -$type = GETPOST('type','alpha'); $label = GETPOST('label','alpha'); $scandir = GETPOST('scandir','alpha'); +$type='product'; // Pricing Rules $select_pricing_rules=array( @@ -325,6 +325,7 @@ $form=new Form($db); * Module to manage product / services code */ $dirproduct=array('/core/modules/product/'); +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); print load_fiche_titre($langs->trans("ProductCodeChecker"), '', ''); @@ -402,146 +403,157 @@ foreach ($dirproduct as $dirroot) } print '
    '; - -// Load array def with activated templates +// Defini tableau def des modeles $def = array(); $sql = "SELECT nom"; $sql.= " FROM ".MAIN_DB_PREFIX."document_model"; -$sql.= " WHERE type = 'product'"; +$sql.= " WHERE type = '".$type."'"; $sql.= " AND entity = ".$conf->entity; $resql=$db->query($sql); if ($resql) { $i = 0; $num_rows=$db->num_rows($resql); - if ($num_rows > 0) + while ($i < $num_rows) { - print '
    '; - print load_fiche_titre($langs->trans("ModelModulesProduct"), '', ''); - - while ($i < $num_rows) - { - $array = $db->fetch_array($resql); - array_push($def, $array[0]); - $i++; - } - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - - $var=true; - foreach ($dirproduct as $dirroot) - { - $dir = dol_buildpath($dirroot.'core/modules/product/doc/',0); - $handle=@opendir($dir); - if (is_resource($handle)) - { - while (($file = readdir($handle))!==false) - { - if (preg_match('/\.modules\.php$/i',$file)) - { - $name = substr($file, 4, dol_strlen($file) -16); - $classname = substr($file, 0, dol_strlen($file) -12); - - try { - dol_include_once($dirroot.'core/modules/product/doc/'.$file); - } - catch(Exception $e) - { - dol_syslog($e->getMessage(), LOG_ERR); - } - - $module = new $classname($db); - - $modulequalified=1; - if (! empty($module->version)) { - if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; - else if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; - } - - if ($modulequalified) - { - $var = !$var; - print ''; - - // Activate / Disable - if (in_array($name, $def)) - { - print ""; - } - else - { - if (versioncompare($module->phpmin,versionphparray()) > 0) - { - print ""; - } - else - { - print ""; - } - } - - // Info - $htmltooltip = ''.$langs->trans("Name").': '.$module->name; - $htmltooltip.='
    '.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); - if ($module->type == 'pdf') - { - $htmltooltip.='
    '.$langs->trans("Height").'/'.$langs->trans("Width").': '.$module->page_hauteur.'/'.$module->page_largeur; - } - $htmltooltip.='

    '.$langs->trans("FeaturesSupported").':'; - $htmltooltip.='
    '.$langs->trans("WatermarkOnDraft").': '.yn((! empty($module->option_draft_watermark)?$module->option_draft_watermark:''), 1, 1); - - print ''; - - // Preview - print ''; - - print "\n"; - } - } - } - closedir($handle); - } - } - print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status").''.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
    '; - print $module->name; - print "\n"; - if (method_exists($module,'info')) print $module->info($langs); - else print $module->description; - print '\n"; - print 'scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("Enabled"),'switch_on'); - print ''; - print "\n"; - print img_picto(dol_escape_htmltag($langs->trans("ErrorModuleRequirePHPVersion",join('.',$module->phpmin))),'switch_off'); - print "\n"; - print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; - print "'; - print $form->textwithpicto('',$htmltooltip,1,0); - print ''; - if ($module->type == 'pdf') - { - $linkspec=''.img_object($langs->trans("Preview"),'bill').''; - } - else - { - $linkspec=img_object($langs->trans("PreviewNotAvailable"),'generic'); - } - print $linkspec; - print '
    '; + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; } } else { - dol_print_error($db); + dol_print_error($db); } - + +print ''; +print ''; +print ''; +print ''; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +$var=true; +foreach ($dirmodels as $reldir) +{ + foreach (array('','/doc') as $valdir) + { + $dir = dol_buildpath($reldir."core/modules/product".$valdir); + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var = !$var; + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } + else + { + print '"; + } + + // Defaut + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
    '.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip.='
    '.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip.='

    '.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
    '.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
    '.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
    '.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
    '.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + $htmltooltip.='
    '.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } +} + +print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
    '; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print "'; + if ($conf->global->PRODUCT_ADDON_PDF == $name) + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'contract').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
    '; +print "
    "; /* * Other conf diff --git a/htdocs/product/card.php b/htdocs/product/card.php index b27cef6d985..4df8b45041f 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -147,7 +147,6 @@ if (empty($reshook)) { // Save last template used to generate document if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); - // Define output language $outputlangs = $langs; $newlang=''; @@ -158,11 +157,12 @@ if (empty($reshook)) $outputlangs = new Translate("",$conf); $outputlangs->setDefaultLang($newlang); } - $result=product_create($db, $object, GETPOST('model','alpha'), $outputlangs); + $ret = $object->fetch($id); // Reload to get new records + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); if ($result <= 0) { - dol_print_error($db,$result); - exit; + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; } } @@ -197,6 +197,20 @@ if (empty($reshook)) setEventMessages($errors, null, 'errors'); } } + + // Remove file in doc form + if ($action == 'remove_file' && $user->rights->produit->creer) { + if ($object->id > 0) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->product->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); + else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); + } + } // Add a product or service if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service->creer)) @@ -2001,7 +2015,7 @@ if (! empty($conf->global->PRODUCT_ADD_FORM_ADD_TO) && $object->id && ($action = /* * Documents generes */ -if ($action == '' || $action == 'view') +if ($action != 'edit' && $action != 'delete') { print '
    '; print ''; // ancre diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 5cc173da6ad..192d681ca81 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -210,6 +210,11 @@ if ($action == 'update') setEventMessages($langs->trans('ErrorForbidden'), null, 'mesgs'); } } + +// Actions to build doc +$upload_dir = $conf->usergroup->dir_output; +$permissioncreate=$user->rights->user->user->creer; +include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; @@ -498,11 +503,6 @@ else } print "
    "; print "
    "; - - // Actions to build doc - $upload_dir = $conf->usergroup->dir_output; - $permissioncreate=$user->rights->user->user->creer; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; /* * Documents generes From 3ab7bac511ddf748356e27e058a79657ad5bb955 Mon Sep 17 00:00:00 2001 From: arnaud Date: Tue, 14 Mar 2017 09:37:51 +0100 Subject: [PATCH 095/410] FIX fresh install const --- htdocs/install/mysql/data/llx_const.sql | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/htdocs/install/mysql/data/llx_const.sql b/htdocs/install/mysql/data/llx_const.sql index 42ecad2b927..b34e0cac513 100644 --- a/htdocs/install/mysql/data/llx_const.sql +++ b/htdocs/install/mysql/data/llx_const.sql @@ -85,3 +85,12 @@ insert into llx_const (name, value, type, note, visible) values ('MAIN_DELAY_EXP -- insert into llx_const (name, value, type, note, visible) values ('MAIN_FIX_FOR_BUGGED_MTA','1','chaine','Set constant to fix email ending from PHP with some linux ike system',1); insert into llx_const (name, value, type, note, visible) values ('MAILING_EMAIL_FROM','dolibarr@domain.com','chaine','EMail emmetteur pour les envois d emailings',0); + + +-- +-- ODT Path +--- +insert into `llx_const` (`name`, `entity`, `value`, `type`, `visible`) VALUES ('PRODUCT_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/products', 'chaine', 0); +insert into `llx_const` (`name`, `entity`, `value`, `type`, `visible`) VALUES ('CONTRACT_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/contracts', 'chaine', 0); +insert into `llx_const` (`name`, `entity`, `value`, `type`, `visible`) VALUES ('USERGROUP_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/usergroups', 'chaine', 0); +insert into `llx_const` (`name`, `entity`, `value`, `type`, `visible`) VALUES ('USER_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/users', 'chaine', 0); From e0449cf17f4a1e9a096a6f7b9806f21834537ffa Mon Sep 17 00:00:00 2001 From: camlafit Date: Tue, 14 Mar 2017 09:56:30 +0100 Subject: [PATCH 096/410] Execute in background process It's better to split command call in two part. Set command to execute with binary path and execute after in background --- scripts/odt2pdf/odt2pdf.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/odt2pdf/odt2pdf.sh b/scripts/odt2pdf/odt2pdf.sh index b44ab3e6d78..1147ff3bbcc 100755 --- a/scripts/odt2pdf/odt2pdf.sh +++ b/scripts/odt2pdf/odt2pdf.sh @@ -17,13 +17,16 @@ then exit fi +soffice="/usr/bin/soffice" + if [ -f "$1.odt" ] then nbprocess=$(pgrep -c soffice) if [ $nbprocess -ne 1 ] # If there is some soffice process running then - soffice --invisible --accept="socket,host=127.0.0.1,port=8100;urp;" --nofirststartwizard --headless & + cmd="$soffice --invisible --accept=socket,host=127.0.0.1,port=8100;urp; --nofirststartwizard --headless" + $cmd & retcode=$? if [ $retcode -ne 0 ] then From 67189fa68399ff62b6691a218427b013123e9d51 Mon Sep 17 00:00:00 2001 From: "cam.lafit" Date: Tue, 14 Mar 2017 10:17:10 +0100 Subject: [PATCH 097/410] Provide a home directory to java/soffice By default www-data run as system user on /root directory, to prevent some error about right user we : * move first to /tmp directory * set /tmp as home www-data user If needed admin sys can update *$home_java* to a valide www-data directory --- scripts/odt2pdf/odt2pdf.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/odt2pdf/odt2pdf.sh b/scripts/odt2pdf/odt2pdf.sh index 1147ff3bbcc..75aa6cc15f0 100755 --- a/scripts/odt2pdf/odt2pdf.sh +++ b/scripts/odt2pdf/odt2pdf.sh @@ -18,15 +18,15 @@ then fi soffice="/usr/bin/soffice" - +home_java="/tmp" if [ -f "$1.odt" ] then nbprocess=$(pgrep -c soffice) if [ $nbprocess -ne 1 ] # If there is some soffice process running then - cmd="$soffice --invisible --accept=socket,host=127.0.0.1,port=8100;urp; --nofirststartwizard --headless" - $cmd & + cmd="$soffice --invisible --accept=socket,host=127.0.0.1,port=8100;urp; --nofirststartwizard --headless -env:UserInstallation=file:///$home_java/" + export HOME=$home_java && cd $home_java && $cmd& retcode=$? if [ $retcode -ne 0 ] then From fc5d96b84bc2900ddfedb5587f3ac15175b1996e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Mar 2017 10:51:28 +0100 Subject: [PATCH 098/410] Add comments --- scripts/odt2pdf/odt2pdf.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/odt2pdf/odt2pdf.sh b/scripts/odt2pdf/odt2pdf.sh index 75aa6cc15f0..4cf1ab54013 100755 --- a/scripts/odt2pdf/odt2pdf.sh +++ b/scripts/odt2pdf/odt2pdf.sh @@ -1,14 +1,14 @@ #!/bin/bash # @copyright GPL License 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com # @copyright GPL License 2013 - Florian HEnry - florian.henry@open-concept.pro -# @copyright GPL License 2015 - Laurent Destailleur - eldy@users.sourceforge.net +# @copyright GPL License 2017 - Laurent Destailleur - eldy@users.sourceforge.net # # Convert an ODT into a PDF using "jodconverter" or "pyodconverter" tool. # Dolibarr variable MAIN_ODT_AS_PDF must be defined to value "jodconverter" to call jodconverter wrapper after ODT generation -# or value "pyodconverter" to call DocumentConverter.py after ODT generation. -# or value "/pathto/jodconverter-cli-file.jar" to call jodconverter java tool without wrapper after ODT generation. +# or value "pyodconverter" to call DocumentConverter.py after ODT generation. +# or value "/pathto/jodconverter-cli-file.jar" to call jodconverter java tool without wrapper after ODT generation. # Dolibarr variable MAIN_DOL_SCRIPTS_ROOT must be defined to path of script directories (otherwise dolibarr will try to guess). - + if [ "x$1" == "x" ] then @@ -17,9 +17,14 @@ then exit fi +# Full patch where soffice is installed soffice="/usr/bin/soffice" + +# Temporary directory (web user must have permission to read/write). You can set here path to your DOL_DATA_ROOT/admin/temp directory for example. home_java="/tmp" + +# Main program if [ -f "$1.odt" ] then nbprocess=$(pgrep -c soffice) From ec7d48931e747c846c3f57ea0989184c9fafd353 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Mar 2017 13:49:04 +0100 Subject: [PATCH 099/410] Merge duplicate menus/page on projects --- htdocs/core/menus/standard/eldy.lib.php | 21 +++++++++------- htdocs/langs/en_US/projects.lang | 4 ++++ htdocs/projet/activity/index.php | 20 ++++++++++++++-- htdocs/projet/activity/perday.php | 2 +- htdocs/projet/activity/perweek.php | 2 +- htdocs/projet/index.php | 22 ++++++++++++++--- htdocs/projet/list.php | 26 ++++++++++---------- htdocs/projet/tasks/list.php | 32 ++++++++++++++++++++----- htdocs/projet/tasks/time.php | 4 +++- htdocs/theme/eldy/style.css.php | 11 ++++++--- htdocs/theme/md/style.css.php | 20 ++++++++++------ 11 files changed, 117 insertions(+), 47 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 440c96c1e49..9396363a0ab 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1226,29 +1226,32 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $langs->load("projects"); // Project affected to user - $newmenu->add("/projet/index.php?leftmenu=myprojects&mode=mine", $langs->trans("MyProjects"), 0, $user->rights->projet->lire, '', $mainmenu, 'myprojects'); - $newmenu->add("/projet/card.php?leftmenu=myprojects&action=create&mode=mine", $langs->trans("NewProject"), 1, $user->rights->projet->creer); - $newmenu->add("/projet/list.php?leftmenu=myprojects&mode=mine&search_status=99", $langs->trans("List"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/index.php?leftmenu=projects&search_project_user=".GETPOST('search_project_user'), $langs->trans("Projects"), 0, $user->rights->projet->lire, '', $mainmenu, 'projects'); + $newmenu->add("/projet/card.php?leftmenu=projects&action=create&search_project_user=".GETPOST('search_project_user'), $langs->trans("NewProject"), 1, $user->rights->projet->creer); + $newmenu->add("/projet/list.php?leftmenu=projects&search_project_user=".GETPOST('search_project_user')."&search_status=99", $langs->trans("List"), 1, $user->rights->projet->lire); // All project i have permission on + /* $newmenu->add("/projet/index.php?leftmenu=projects", $langs->trans("Projects"), 0, $user->rights->projet->lire && $user->rights->projet->lire, '', $mainmenu, 'projects'); $newmenu->add("/projet/card.php?leftmenu=projects&action=create", $langs->trans("NewProject"), 1, $user->rights->projet->creer && $user->rights->projet->creer); $newmenu->add("/projet/list.php?leftmenu=projects&search_status=99", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire); + */ $newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire && $user->rights->projet->lire); - + if (empty($conf->global->PROJECT_HIDE_TASKS)) { // Project affected to user - $newmenu->add("/projet/activity/index.php?leftmenu=mytasks&mode=mine", $langs->trans("MyActivities"), 0, $user->rights->projet->lire); - $newmenu->add("/projet/tasks.php?leftmenu=mytasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); - $newmenu->add("/projet/tasks/list.php?leftmenu=mytasks&mode=mine", $langs->trans("List"), 1, $user->rights->projet->lire); - $newmenu->add("/projet/activity/perweek.php?leftmenu=mytasks&mode=mine", $langs->trans("NewTimeSpent"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/activity/index.php?leftmenu=tasks&search_project_user=".GETPOST('search_project_user'), $langs->trans("Activities"), 0, $user->rights->projet->lire); + $newmenu->add("/projet/tasks.php?leftmenu=tasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); + $newmenu->add("/projet/tasks/list.php?leftmenu=tasks&search_project_user=".GETPOST('search_project_user'), $langs->trans("List"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks&search_project_user=".GETPOST('search_project_user'), $langs->trans("NewTimeSpent"), 1, $user->rights->projet->lire); // All project i have permission on - $newmenu->add("/projet/activity/index.php", $langs->trans("Activities"), 0, $user->rights->projet->lire && $user->rights->projet->lire); + /*$newmenu->add("/projet/activity/index.php", $langs->trans("Activities"), 0, $user->rights->projet->lire && $user->rights->projet->lire); $newmenu->add("/projet/tasks.php?action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer && $user->rights->projet->creer); $newmenu->add("/projet/tasks/list.php", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire); $newmenu->add("/projet/activity/perweek.php", $langs->trans("NewTimeSpent"), 1, $user->rights->projet->creer && $user->rights->projet->lire); + */ } // Categories diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index f9c603ce113..3d218611194 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -9,6 +9,9 @@ ProjectsArea=Projects Area ProjectStatus=Project status SharedProject=Everybody PrivateProject=Project contacts +ProjectsImContactFor=Projects I'm explicitely a contact of +AllAllowedProjects=All project I can read (mine + public) +AllProjects=All projects MyProjectsDesc=This view is limited to projects you are a contact for (whatever is the type). ProjectsPublicDesc=This view presents all projects you are allowed to read. TasksOnProjectsPublicDesc=This view presents all tasks on projects you are allowed to read. @@ -23,6 +26,7 @@ TasksDesc=This view presents all projects and tasks (your user permissions grant AllTaskVisibleButEditIfYouAreAssigned=All tasks for such project are visible, but you can enter time only for task assigned to you. Assign task to yourself if you need to enter time on it. OnlyYourTaskAreVisible=Only tasks assigned to you are visible. Assign task to yourself if it is not visible and you need to enter time on it. ImportDatasetTasks=Tasks of projects +ProjectCategories=Project tags/categories NewProject=New project AddProject=Create project DeleteAProject=Delete a project diff --git a/htdocs/projet/activity/index.php b/htdocs/projet/activity/index.php index 4586c8d52a6..495337b4a7b 100644 --- a/htdocs/projet/activity/index.php +++ b/htdocs/projet/activity/index.php @@ -58,11 +58,27 @@ $taskstatic=new Task($db); $tasktmp=new Task($db); $title=$langs->trans("Activities"); -if ($mine) $title=$langs->trans("MyActivities"); +//if ($mine) $title=$langs->trans("MyActivities"); llxHeader("",$title); -print load_fiche_titre($title, '', 'title_project'); + +// Title for combo list see all projects +$titleall=$langs->trans("AllAllowedProjects"); +if (! empty($user->rights->projet->all->lire) && ! $socid) $titleall=$langs->trans("AllProjects"); +else $titleall=$langs->trans("AllAllowedProjects").'

    '; + + +$morehtml=''; +$morehtml.='
    '; +$morehtml.=''; +$morehtml.=''; + +print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, -1, 'title_project.png', 0, $morehtml); +//print load_fiche_titre($title, '', 'title_project'); if ($mine) print $langs->trans("MyTasksDesc").'

    '; else diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 195ad3dbd89..692c5ecfad4 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -345,7 +345,7 @@ if ($mine) print $langs->trans("MyTasksDesc").($onlyopenedproject?' '.$langs->tr else { if ($user->rights->projet->all->lire && ! $socid) print $langs->trans("ProjectsDesc").($onlyopenedproject?' '.$langs->trans("OnlyOpenedProject"):'').'
    '; - else print $langs->trans("ProjectsPublicTaskDesc").($onlyopenedproject?' '.$langs->trans("AlsoOnlyOpenedProject"):'').'
    '; + else print $langs->trans("ProjectsPublicTaskDesc").($onlyopenedproject?' '.$langs->trans("OnlyOpenedProject"):'').'
    '; } if ($mine) { diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 9a34913b2f5..e1c71a98ba7 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -341,7 +341,7 @@ if ($mine) print $langs->trans("MyTasksDesc").($onlyopenedproject?' '.$langs->tr else { if ($user->rights->projet->all->lire && ! $socid) print $langs->trans("ProjectsDesc").($onlyopenedproject?' '.$langs->trans("OnlyOpenedProject"):'').'
    '; - else print $langs->trans("ProjectsPublicTaskDesc").($onlyopenedproject?' '.$langs->trans("AlsoOnlyOpenedProject"):'').'
    '; + else print $langs->trans("ProjectsPublicTaskDesc").($onlyopenedproject?' '.$langs->trans("OnlyOpenedProject"):'').'
    '; } if ($mine) { diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php index f3690eee61e..8292e4d31a8 100644 --- a/htdocs/projet/index.php +++ b/htdocs/projet/index.php @@ -34,6 +34,7 @@ $langs->load("projects"); $langs->load("companies"); $mine = GETPOST('mode')=='mine' ? 1 : 0; +$search_project_user = GETPOST('search_project_user','int'); // Security check $socid=0; @@ -59,10 +60,25 @@ $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,($mine?$min llxHeader("",$langs->trans("Projects"),"EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"); -$text=$langs->trans("ProjectsArea"); -if ($mine) $text=$langs->trans("MyProjectsArea"); +$title=$langs->trans("ProjectsArea"); +//if ($mine) $title=$langs->trans("MyProjectsArea"); -print load_fiche_titre($text,'','title_project.png'); + +// Title for combo list see all projects +$titleall=$langs->trans("AllAllowedProjects"); +if (! empty($user->rights->projet->all->lire) && ! $socid) $titleall=$langs->trans("AllProjects"); +else $titleall=$langs->trans("AllAllowedProjects").'

    '; + + +$morehtml=''; +$morehtml.=''; +$morehtml.=''; +$morehtml.=''; + +print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, -1, 'title_project.png', 0, $morehtml); // Show description of content if ($mine) print $langs->trans("MyProjectsDesc").'

    '; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 35f65b75c2a..f45148c84c7 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -75,12 +75,12 @@ $search_opp_percent=GETPOST("search_opp_percent",'alpha'); $search_opp_amount=GETPOST("search_opp_amount",'alpha'); $search_budget_amount=GETPOST("search_budget_amount",'alpha'); $search_public=GETPOST("search_public",'int'); -$search_user=GETPOST('search_user','int'); +$search_project_user=GETPOST('search_project_user','int'); $search_sale=GETPOST('search_sale','int'); $optioncss = GETPOST('optioncss','alpha'); $mine = $_REQUEST['mode']=='mine' ? 1 : 0; -if ($mine) { $search_user = $user->id; $mine=0; } +if ($mine) { $search_project_user = $user->id; $mine=0; } $sday = GETPOST('sday','int'); $smonth = GETPOST('smonth','int'); @@ -170,7 +170,7 @@ if (empty($reshook)) $search_budget_amount=''; $search_public=""; $search_sale=""; - $search_user=''; + $search_project_user=''; $sday=""; $smonth=""; $syear=""; @@ -193,7 +193,8 @@ $formother = new FormOther($db); $formproject = new FormProjets($db); $title=$langs->trans("Projects"); -if ($search_user == $user->id) $title=$langs->trans("MyProjects"); +//if ($search_project_user == $user->id) $title=$langs->trans("MyProjects"); + // Get list of project id allowed to user (in a string list separated by coma) if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1,$socid); @@ -238,7 +239,7 @@ if (! empty($search_categ)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_proje // For external user, no check is done on company permission because readability is managed by public status of project and assignement. //if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; if ($search_sale > 0) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; -if ($search_user > 0) +if ($search_project_user > 0) { $sql.=", ".MAIN_DB_PREFIX."element_contact as ecp"; } @@ -296,7 +297,7 @@ if ($search_public!='') $sql .= " AND p.public = ".$db->escape($search_public); if ($search_sale > 0) $sql.= " AND sc.fk_user = " .$search_sale; // 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.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; -if ($search_user > 0) $sql.= " AND ecp.fk_c_type_contact IN (".join(',',array_keys($listofprojectcontacttype)).") AND ecp.element_id = p.rowid AND ecp.fk_socpeople = ".$search_user; +if ($search_project_user > 0) $sql.= " AND ecp.fk_c_type_contact IN (".join(',',array_keys($listofprojectcontacttype)).") AND ecp.element_id = p.rowid AND ecp.fk_socpeople = ".$search_project_user; if ($search_opp_amount != '') $sql .= natural_search('p.opp_amount', $search_opp_amount, 1); if ($search_budget_amount != '') $sql .= natural_search('p.budget_amount', $search_budget_amount, 1); // Add where from extra fields @@ -368,7 +369,7 @@ if ($search_status >= 0) $param.='&search_status='.$search_status; if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all','openedopp','none'))) $param.='&search_opp_status='.urlencode($search_opp_status); if ((is_numeric($search_opp_percent) && $search_opp_percent >= 0) || in_array($search_opp_percent, array('all','openedopp','none'))) $param.='&search_opp_percent='.urlencode($search_opp_percent); if ($search_public != '') $param.='&search_public='.$search_public; -if ($search_user > 0) $param.='&search_user='.$search_user; +if ($search_project_user != '') $param.='&search_project_user='.$search_project_user; if ($search_sale > 0) $param.='&search_sale='.$search_sale; if ($search_opp_amount != '') $param.='&search_opp_amount='.$search_opp_amount; if ($search_budget_amount != '') $param.='&search_budget_amount='.$search_budget_amount; @@ -381,9 +382,6 @@ foreach ($search_array_options as $key => $val) if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); } -$text=$langs->trans("Projects"); -if ($search_user == $user->id) $text=$langs->trans('MyProjects'); - print ''; if ($optioncss != '') print ''; print ''; @@ -394,10 +392,10 @@ print ''; print ''; print ''; -print_barre_liste($text, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $nbtotalofrecords, 'title_project', 0, '', '', $limit); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $nbtotalofrecords, 'title_project', 0, '', '', $limit); // Show description of content -if ($search_user == $user->id) print $langs->trans("MyProjectsDesc").'

    '; +if ($search_project_user == $user->id) print $langs->trans("MyProjectsDesc").'

    '; else { if ($user->rights->projet->all->lire && ! $socid) print $langs->trans("ProjectsDesc").'

    '; @@ -417,7 +415,7 @@ if (! empty($conf->categorie->enabled)) { require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; $moreforfilter.='
    '; - $moreforfilter.=$langs->trans('Categories'). ': '; + $moreforfilter.=$langs->trans('ProjectCategories'). ': '; $moreforfilter.=$formother->select_categories('project',$search_categ,'search_categ',1); $moreforfilter.='
    '; } @@ -427,7 +425,7 @@ $moreforfilter.='
    '; $moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; $includeonly=''; if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); -$moreforfilter.=$form->select_dolusers($search_user, 'search_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth300'); +$moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:'', 'search_project_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth300'); $moreforfilter.='
    '; // If the user can view thirdparties other than his' diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 74f9b122f14..c9d9e82ea82 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -37,6 +37,7 @@ $langs->load('companies'); $id=GETPOST('id','int'); $search_all=GETPOST('search_all'); +$search_categ=GETPOST("search_categ",'alpha'); $search_project=GETPOST('search_project'); if (! isset($_GET['search_projectstatus']) && ! isset($_POST['search_projectstatus'])) { @@ -142,9 +143,10 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria - if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers + if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers { $search_all=""; + $search_categ=""; $search_project=""; $search_projectstatus=-1; $search_project_ref=""; @@ -184,7 +186,7 @@ if ($search_project_user > 0) $puser->fetch($search_project_user); if ($search_task_user > 0) $tuser->fetch($search_task_user); $title=$langs->trans("Activities"); -if ($search_task_user == $user->id) $title=$langs->trans("MyActivities"); +//if ($search_task_user == $user->id) $title=$langs->trans("MyActivities"); if ($id) { @@ -232,6 +234,8 @@ $sql = "SELECT ".$distinct." p.rowid as projectid, p.ref as projectref, p.title $sql.= ", s.nom as name, s.rowid as socid"; $sql.= ", t.datec as date_creation, t.dateo as date_start, t.datee as date_end, t.tms as date_update"; $sql.= ", t.rowid as id, t.ref, t.label, t.planned_workload, t.duration_effective, t.progress, t.fk_statut"; +// We'll need these fields in order to filter by categ +if ($search_categ) $sql .= ", cs.fk_categorie, cs.fk_project"; // Add fields from extrafields foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); // Add fields from hooks @@ -239,8 +243,10 @@ $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid,"; -$sql.= " ".MAIN_DB_PREFIX."projet_task as t"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; +// We'll need this table joined to the select in order to filter by categ +if (! empty($search_categ)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_project as cs ON p.rowid = cs.fk_project"; // We'll need this table joined to the select in order to filter by categ +$sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_extrafields as ef on (t.rowid = ef.fk_object)"; if ($search_project_user > 0) $sql.=", ".MAIN_DB_PREFIX."element_contact as ecp"; if ($search_task_user > 0) $sql.=", ".MAIN_DB_PREFIX."element_contact as ect"; @@ -249,6 +255,8 @@ $sql.= " AND p.entity IN (".getEntity('project',1).')'; if (! $user->rights->projet->all->lire) $sql.=" AND p.rowid IN (".($projectsListId?$projectsListId:'0').")"; // public and assigned to projects, or restricted to company for external users // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; +if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$db->escape($search_categ); +if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($search_project_ref) $sql .= natural_search('p.ref', $search_project_ref); if ($search_project_title) $sql .= natural_search('p.title', $search_project_title); if ($search_task_ref) $sql .= natural_search('t.ref', $search_task_ref); @@ -359,7 +367,7 @@ if ($search_societe != '') $param.='&search_societe='.$search_societe; if ($search_projectstatus != '') $param.='&search_projectstatus='.$search_projectstatus; if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all','none'))) $param.='&search_opp_status='.urlencode($search_opp_status); if ($search_public != '') $param.='&search_public='.$search_public; -if ($search_project_user > 0) $param.='&search_project_user='.$search_project_user; +if ($search_project_user != '') $param.='&search_project_user='.$search_project_user; if ($search_task_user > 0) $param.='&search_task_user='.$search_task_user; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields @@ -395,12 +403,24 @@ if ($search_all) print $langs->trans("FilterOnInto", $search_all) . join(', ',$fieldstosearchall); } +$morehtmlfilter = ''; + +// Filter on categories +if (! empty($conf->categorie->enabled)) +{ + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $moreforfilter.='
    '; + $moreforfilter.=$langs->trans('ProjectCategories'). ': '; + $moreforfilter.=$formother->select_categories('project',$search_categ,'search_categ',1); + $moreforfilter.='
    '; +} + // If the user can view users $moreforfilter.='
    '; $moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ' '; $includeonly=''; if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); -$moreforfilter.=$form->select_dolusers($search_project_user, 'search_project_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth300'); +$moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:'', 'search_project_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth300'); $moreforfilter.='
    '; // If the user can view users diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 6cb52588a89..22293039c86 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -425,6 +425,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id.'&lineid='.$_GET["lineid"].($withproject?'&withproject=1':''),$langs->trans("DeleteATimeSpent"),$langs->trans("ConfirmDeleteATimeSpent"),"confirm_delete",'','',1); } + print '
    '; print ''; $param=($withproject?'&withproject=1':''); @@ -492,7 +493,8 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) } print '
    '; - + print '
    '; + dol_fiche_end(); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 1f2f1a225e3..5ae8d76e456 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -268,7 +268,7 @@ input.select2-input { border-bottom: solid 1px rgba(0,0,0,.2) !important; /* required to avoid to lose bottom line when focus is lost on select2. */ } -.liste_titre input[name=month], .liste_titre input[name=month_lim] { +.liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select { @@ -282,9 +282,14 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla } input { line-height: 17px; + padding: 4px; + padding-left: 5px; +} +select { + padding: 4px; + padding-left: 2px; } input, select { - padding: 4px; margin-left:0px; margin-bottom:1px; margin-top:1px; @@ -4003,7 +4008,7 @@ a span.select2-chosen } .select2-container .select2-choice { background-image: none; - line-height: 24px; + /* line-height: 24px; */ } .select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-ajax-error, .select2-results .select2-selection-limit { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 425b4a4fb2f..b7da47d400c 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -292,18 +292,24 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla outline: none; margin: 0px 0px 0px 0px; } -input, select { - border-bottom: solid 1px rgba(0,0,0,.1); +input { + line-height: 17px; + padding: 4px; + padding-left: 5px; +} +select { + padding: 4px; + padding-left: 2px; +} +input, select { margin-left:0px; margin-bottom:1px; margin-top:1px; } -input { - padding:4px; -} -select { - padding:1px; + +input, select { + border-bottom: solid 1px rgba(0,0,0,.1); } textarea { From 6c392fad9f5f7e952c7ee9c174e22884f866450a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Mar 2017 14:06:55 +0100 Subject: [PATCH 100/410] Fix CSS --- htdocs/core/menus/init_menu_auguria.sql | 9 +-------- htdocs/core/menus/standard/eldy.lib.php | 2 +- htdocs/projet/tasks.php | 2 +- htdocs/projet/tasks/task.php | 2 +- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 59886b99f63..8ac601b4e27 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -281,20 +281,13 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3600__+MAX_llx_menu__, 'project', 'projects', 7__+MAX_llx_menu__, '/projet/index.php?leftmenu=projects', 'Projects', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3601__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/card.php?leftmenu=projects&action=create', 'NewProject', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3602__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/list.php?leftmenu=projects', 'List', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__); - -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3610__+MAX_llx_menu__, 'project', 'myprojects', 7__+MAX_llx_menu__, '/projet/index.php?leftmenu=projects&mode=mine', 'MyProjects', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3611__+MAX_llx_menu__, 'project', '', 3610__+MAX_llx_menu__, '/projet/card.php?leftmenu=projects&action=create&mode=mine', 'NewProject', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3612__+MAX_llx_menu__, 'project', '', 3610__+MAX_llx_menu__, '/projet/list.php?leftmenu=projects&mode=mine', 'List', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3603__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/stats/index.php?leftmenu=projects', 'Statistics', 1, 'projects', '$user->rights->projet->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3700__+MAX_llx_menu__, 'project', '', 7__+MAX_llx_menu__, '/projet/activity/index.php?leftmenu=projects', 'Activities', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3701__+MAX_llx_menu__, 'project', '', 3700__+MAX_llx_menu__, '/projet/tasks.php?leftmenu=projects&action=create', 'NewTask', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3702__+MAX_llx_menu__, 'project', '', 3700__+MAX_llx_menu__, '/projet/tasks/list.php?leftmenu=projects', 'List', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3703__+MAX_llx_menu__, 'project', '', 3700__+MAX_llx_menu__, '/projet/activity/perweek.php?leftmenu=projects', 'NewTimeSpent', 1, 'projects', '$user->rights->projet->lire', '', 2, 3, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3800__+MAX_llx_menu__, 'project', '', 7__+MAX_llx_menu__, '/projet/activity/index.php?leftmenu=projects&mode=mine', 'MyActivities', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3801__+MAX_llx_menu__, 'project', '', 3800__+MAX_llx_menu__, '/projet/tasks.php?leftmenu=projects&action=create', 'NewTask', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3802__+MAX_llx_menu__, 'project', '', 3800__+MAX_llx_menu__, '/projet/tasks/list.php?leftmenu=projects&mode=mine', 'List', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3803__+MAX_llx_menu__, 'project', '', 3800__+MAX_llx_menu__, '/projet/activity/perweek.php?leftmenu=projects&mode=mine', 'NewTimeSpent', 1, 'projects', '$user->rights->projet->lire', '', 2, 3, __ENTITY__); -- Project - Categories insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3804__+MAX_llx_menu__, 'project', 'cat', 3__+MAX_llx_menu__, '/categories/index.php?leftmenu=cat&type=6', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3805__+MAX_llx_menu__, 'project', '', 3200__+MAX_llx_menu__, '/categories/card.php?action=create&type=6', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 9396363a0ab..924a71020d8 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1236,7 +1236,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/projet/card.php?leftmenu=projects&action=create", $langs->trans("NewProject"), 1, $user->rights->projet->creer && $user->rights->projet->creer); $newmenu->add("/projet/list.php?leftmenu=projects&search_status=99", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire); */ - $newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire && $user->rights->projet->lire); + $newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); if (empty($conf->global->PROJECT_HIDE_TASKS)) { diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index cd8728b3013..b742b5a3acb 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -394,7 +394,7 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third // Description print '
    '.$langs->trans("Description").''; - print ''; + print ''; print '
    '.$langs->trans("Description").''; - print ''; + print ''; print '
    '; + $boxstat.='
    '; $boxstat.='multicurrency->enabled)) { $colspan++;?> @@ -283,7 +283,7 @@ else { "> - global->PRODUCT_USE_UNITS) @@ -293,11 +293,11 @@ else { print ''; } ?> - + situation_cycle_ref) { $coldisplay++; - print ''; + print ''; } if (! empty($usemargins)) { @@ -309,7 +309,7 @@ else { - "> + "> global->DISPLAY_MARGIN_RATES)) { - echo ''; + echo ''; $coldisplay++; } if (! empty($conf->global->DISPLAY_MARK_RATES)) { - echo ''; + echo ''; $coldisplay++; } } diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index d982516bd67..2f839e06281 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -46,6 +46,7 @@ $colspan = 3; // Col total ht + col edit + col delete if (! empty($inputalsopricewithtax)) $colspan++; // We add 1 if col total ttc if (in_array($object->element,array('propal','supplier_proposal','facture','invoice','commande','order','order_supplier','invoice_supplier'))) $colspan++; // With this, there is a column move button if (empty($user->rights->margins->creer)) $colspan++; +if (!empty($conf->multicurrency->enabled)) $colspan+=2; ?> @@ -114,23 +115,22 @@ $coldisplay=-1; // We remove first td if ($this->situation_counter == 1 || !$this->situation_cycle_ref) { print ''; } else { - print ''; + print ''; } $coldisplay++; - print ''; if (!empty($conf->multicurrency->enabled)) { - $colspan++; - print ''; + print ''; } if ($inputalsopricewithtax) { $coldisplay++; - print ''; } @@ -141,7 +141,7 @@ $coldisplay=-1; // We remove first td // for example always visible on invoice but must be visible only if stock module on and stock decrease option is on invoice validation and status is not validated // must also not be output for most entities (proposal, intervention, ...) //if($line->qty > $line->stock) print img_picto($langs->trans("StockTooLow"),"warning", 'style="vertical-align: bottom;"')." "; - print 'situation_counter > 1) print ' readonly'; print '>'; } else { ?> @@ -160,7 +160,7 @@ $coldisplay=-1; // We remove first td '; + print ''; } if (! empty($usemargins)) { @@ -179,10 +179,10 @@ $coldisplay=-1; // We remove first td rights->margins->creer) { @@ -193,7 +193,7 @@ $coldisplay=-1; // We remove first td if ($line->subprice < 0) echo ''; else - echo ''; + echo ''; $coldisplay++; } elseif (! empty($conf->global->DISPLAY_MARK_RATES)) @@ -203,7 +203,7 @@ $coldisplay=-1; // We remove first td if ($line->subprice < 0) echo ''; else - echo ''; + echo ''; $coldisplay++; } } @@ -227,7 +227,7 @@ $coldisplay=-1; // We remove first td service->enabled) && $line->product_type == 1 && $dateSelector) { ?> > - '; print ""; - if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates') - { - print ''; - } - $colspan=count($fieldlist)+3; - if ($id == 4) $colspan++; if (! empty($alabelisused)) // If there is one label among fields, we show legend of * { @@ -1175,7 +1148,7 @@ $db->close(); function fieldList($fieldlist, $obj='', $tabname='', $context='') { global $conf,$langs,$db; - global $form; + global $form, $mysoc; global $region_id; global $elementList,$sourceList,$localtax_typeList; global $bc; @@ -1197,7 +1170,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') } // For state page, we do not show the country input (we link to region, not country) print ''; } elseif ($fieldlist[$field] == 'country_id') From 688073dc18b49d836341c8b2f549a5990faae026 Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Wed, 15 Mar 2017 10:31:45 +0100 Subject: [PATCH 104/410] Create a trigger for company create RIB Since there no 'trigger' executed when we create a RIB for a company (COMPANY_CREATE, COMPANY_MODIFY, COMPANY_DELETE not executed), I purpose a new one COMPANY_RIB_CREATE. If this PR is qualified i will purpose COMPANY_RIB_MODIFY and COMPANY_RIB_DELETE too. tks --- .../class/companybankaccount.class.php | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 7d1afae725d..d59bedd03af 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -69,8 +69,8 @@ class CompanyBankAccount extends Account */ function create(User $user = null, $notrigger=0) { - $now=dol_now(); - + $now = dol_now(); + $error = 0; // Correct default_rib to be sure to have always one default $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib where fk_soc = ".$this->socid." AND default_rib = 1"; $result = $this->db->query($sql); @@ -89,7 +89,21 @@ class CompanyBankAccount extends Account if ($this->db->affected_rows($resql)) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."societe_rib"); - return 1; + + // Call trigger + $result=$this->call_trigger('COMPANY_RIB_CREATE',$user); + if ($result < 0) $error++; + // End call triggers + + if(! $error ) + { + return 1; + } + else + { + return 0; + } + } } else From 0721e6af42b757a2c19a4c1463e390acceac9d3a Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Wed, 15 Mar 2017 10:37:08 +0100 Subject: [PATCH 105/410] add condition add condition check for $notrigger --- .../class/companybankaccount.class.php | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index d59bedd03af..ec770d628a0 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -90,19 +90,27 @@ class CompanyBankAccount extends Account { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."societe_rib"); - // Call trigger - $result=$this->call_trigger('COMPANY_RIB_CREATE',$user); - if ($result < 0) $error++; - // End call triggers + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('COMPANY_RIB_CREATE',$user); + if ($result < 0) $error++; + // End call triggers + + if(! $error ) + { + return 1; + } + else + { + return 0; + } - if(! $error ) - { - return 1; - } - else - { - return 0; - } + } + else + { + return 1; + } } } From 888675016d458972fe5b18962726516d02ca8382 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 15 Mar 2017 11:13:30 +0100 Subject: [PATCH 106/410] NEW Can use dol_fiche_end without showing bottom border. --- htdocs/bookmarks/card.php | 10 +++++++--- htdocs/comm/propal/card.php | 1 - htdocs/contrat/note.php | 2 +- htdocs/core/lib/functions.lib.php | 12 ++++++------ htdocs/societe/soc.php | 4 ++-- htdocs/supplier_proposal/card.php | 1 - htdocs/theme/eldy/style.css.php | 23 ++++++++++++----------- htdocs/theme/md/style.css.php | 24 +++++++++++------------- 8 files changed, 39 insertions(+), 38 deletions(-) diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 818a38c28df..cf5a52cf9c6 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -159,7 +159,7 @@ if ($action == 'create') print ''; - print ''; + print ''; print '
    '; if ($conf->propal->enabled) diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index f731fac1684..390872bb836 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -284,7 +284,7 @@ if ($object->id > 0) // Lien recap $boxstat.='
    '; - $boxstat.=''; + $boxstat.='
    '; $boxstat.=''; /*$boxwork.=''; - $boxwork .= ''; - $boxwork .= ''; - $boxwork .=''; - /*print '';*/ - /* - if ($showweather) + foreach($valid_dashboardlines as $board) { - $boxwork.=''; - $showweather=0; - }*/ - $boxwork .=''; - $boxwork .="\n"; + if (empty($boad->nbtodo)) $nbworkboardempty++; + + $var=!$var; + $boxwork .= ''; + $boxwork .= ''; + $boxwork .= ''; + $boxwork .=''; + /*print '';*/ + /* + if ($showweather) + { + $boxwork.=''; + $showweather=0; + }*/ + $boxwork .=''; + $boxwork .="\n"; + } +} +else +{ + $boxwork.=''; + $boxwork.=''; + $boxwork.=''; } $boxwork.='
    '; if ($conf->supplier_proposal->enabled) diff --git a/htdocs/index.php b/htdocs/index.php index ee7d2ea7e04..b6189537546 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -516,7 +516,6 @@ foreach($dashboardlines as $tmp) { if ($tmp instanceof WorkboardResponse) $valid_dashboardlines[] = $tmp; } -$rowspan = count($valid_dashboardlines); // We calculate $totallate. Must be defined before start of next loop because it is show in first fetch on next loop foreach($valid_dashboardlines as $board) @@ -549,8 +548,6 @@ if ($showweather) $text=''; if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate).')'; $options='height="64px"'; - if ($rowspan <= 2) $options='height="24"'; // Weather logo is smaller if dashboard has few elements - else if ($rowspan <= 3) $options='height="48"'; // Weather logo is smaller if dashboard has few elements $boxwork.=showWeather($totallate,$text,$options); $boxwork.=''; @@ -564,43 +561,54 @@ if ($showweather) // Show dashboard $nbworkboardempty=0; -foreach($valid_dashboardlines as $board) +if (! empty($valid_dashboardlines)) { - if (empty($boad->nbtodo)) $nbworkboardempty++; - - $var=!$var; - $boxwork .= '
    '.$board->img.'   '.$board->label.''.$board->nbtodo.''; - $textlate = $langs->trans("NActionsLate",$board->nbtodolate); - $textlate.= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')'; - $boxwork .= ''; - $boxwork .= ''; - $boxwork .= $board->nbtodolate; - $boxwork .= ''; - $boxwork .= ''; - $boxwork .=''; - if ($board->nbtodolate > 0) $boxwork .=img_picto($textlate, "warning", 'class="valignmiddle"').' '; - $boxwork .=''; - print ' (>'.ceil($board->warning_delay).' '.$langs->trans("days").')'; - print ''; - $text=''; - if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate).')'; - $options='height="64px"'; - if ($rowspan <= 2) $options='height="24"'; // Weather logo is smaller if dashboard has few elements - else if ($rowspan <= 3) $options='height="48"'; // Weather logo is smaller if dashboard has few elements - $boxwork.=showWeather($totallate,$text,$options); - $boxwork.='
    '.$board->img.'   '.$board->label.''.$board->nbtodo.''; + $textlate = $langs->trans("NActionsLate",$board->nbtodolate); + $textlate.= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')'; + $boxwork .= ''; + $boxwork .= ''; + $boxwork .= $board->nbtodolate; + $boxwork .= ''; + $boxwork .= ''; + $boxwork .=''; + if ($board->nbtodolate > 0) $boxwork .=img_picto($textlate, "warning", 'class="valignmiddle"').' '; + $boxwork .=''; + print ' (>'.ceil($board->warning_delay).' '.$langs->trans("days").')'; + print ''; + $text=''; + if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate).')'; + $options='height="64px"'; + if ($rowspan <= 2) $options='height="24"'; // Weather logo is smaller if dashboard has few elements + else if ($rowspan <= 3) $options='height="48"'; // Weather logo is smaller if dashboard has few elements + $boxwork.=showWeather($totallate,$text,$options); + $boxwork.='
    '; + $boxwork.=$langs->trans("NoOpenedElementToProcess"); + $boxwork.='
    '; // End table array of working board diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index e29c8d8c8b9..9267fa16b2d 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -408,6 +408,7 @@ TotalDuration=Total duration Summary=Summary DolibarrStateBoard=Statistics DolibarrWorkBoard=Work tasks board +NoOpenedElementToProcess=No opened element to process Available=Available NotYetAvailable=Not yet available NotAvailable=Not available diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 5ae8d76e456..17e77025da8 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2858,6 +2858,9 @@ span.dashboardlineko { } .boxtable { margin-bottom: 8px !important; + border-bottom-width: 1px; +} +.boxtablenobottom { border-bottom-width: 0 !important; } .tdboxstats { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b7da47d400c..4470cbed751 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2785,6 +2785,9 @@ span.dashboardlineko { } .boxtable { margin-bottom: 8px !important; + border-bottom-width: 1px; +} +.boxtablenobottom { border-bottom-width: 0 !important; } .tdboxstats { From 76db6c9f18d2f5f56afb85bc9e293e16f16b680c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Mar 2017 21:02:26 +0100 Subject: [PATCH 102/410] Fix css and colspan --- htdocs/core/tpl/objectline_create.tpl.php | 16 +++++++------- htdocs/core/tpl/objectline_edit.tpl.php | 26 +++++++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index f85ca68c864..83725580db5 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -269,12 +269,12 @@ else { ?>
    - "> + "> - "> + "> "> + "> remise_percent); ?>">%remise_percent); ?>">% %% %%%%' . $form->load_tva('tva_tx', $line->tva_tx.($line->vat_src_code?(' ('.$line->vat_src_code.')'):''), $seller, $buyer, 0, $line->info_bits, $line->product_type, false, 1) . '%%situation_counter > 1) print ' readonly'; print '>situation_counter > 1) print ' readonly'; print '> info_bits & 2) != 2) { - print 'situation_counter > 1) print ' readonly'; print '>%'; } else { ?> @@ -170,7 +170,7 @@ $coldisplay=-1; // We remove first td situation_cycle_ref) { $coldisplay++; - print '%% product->enabled) || ! empty($conf->service->enabled)) { ?> - + - + '.$margin_rate.'%%%'.$mark_rate.'%%%
    trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; ?> + trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; ?> global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE:''); echo $form->select_date($line->date_start,'date_start',$hourmin,$hourmin,$line->date_start?0:1,"updateligne",1,0,1); From 39c8f9a15aa11ca7f2b5b998c1b98594e39a8afe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 15 Mar 2017 00:04:09 +0100 Subject: [PATCH 103/410] Fix country not preselected --- htdocs/accountancy/admin/categories_list.php | 35 +++----------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index 696475720ec..3a775149987 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -628,12 +628,6 @@ if ($id) if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); } if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); } - if ($id == 2) // Special cas for state page - { - if ($fieldlist[$field]=='region_id') { $valuetoshow=' '; $showfield=1; } - if ($fieldlist[$field]=='region') { $valuetoshow=$langs->trans("Country").'/'.$langs->trans("Region"); $showfield=1; } - } - if ($valuetoshow != '') { print ''; @@ -675,36 +669,15 @@ if ($id) if (empty($reshook)) { - if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates' && $action == 'edit') - { - fieldList($fieldlist,$obj,$tabname[$id],'hide'); - } - else - { - fieldList($fieldlist,$obj,$tabname[$id],'add'); - } + fieldList($fieldlist,$obj,$tabname[$id],'add'); } print ''; - if ($tabname[$id] != MAIN_DB_PREFIX.'c_email_templates' || $action != 'edit') - { - print ''; - } + print ''; print '
    * '.$langs->trans("AvailableVariables").": "; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail=new FormMail($db); - $tmp=$formmail->getAvailableSubstitKey('form'); - print implode(', ', $tmp); - print '
    '; $fieldname='country'; - print $form->select_country((! empty($obj->country_code)?$obj->country_code:(! empty($obj->country)?$obj->country:'')), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone'); + print $form->select_country((! empty($obj->country_code)?$obj->country_code:(! empty($obj->country)?$obj->country:$mysoc->country_code)), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone'); print '
    '.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("BehaviourOnClick").''; $liste=array(0=>$langs->trans("ReplaceWindow"),1=>$langs->trans("OpenANewWindow")); @@ -219,9 +219,11 @@ if ($id > 0 && ! preg_match('/^add/i',$action)) $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', '', '', 0, '', '', 0); + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', '', '', 0, '', '', 0); - print '
    '; + print '
    '; + + print '
    '; print ''; print '
    '; @@ -297,6 +299,8 @@ if ($id > 0 && ! preg_match('/^add/i',$action)) print '
    '; + print '
    '; + dol_fiche_end(); if ($action == 'edit') diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index b1a37c67b31..99e4a6c0871 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -2414,7 +2414,6 @@ if ($action == 'create') print ''; } - print "
    \n"; //Select mail models is same action as presend if (GETPOST('modelselected')) $action = 'presend'; diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php index c97124ed35b..212fa465266 100644 --- a/htdocs/contrat/note.php +++ b/htdocs/contrat/note.php @@ -164,7 +164,7 @@ if ($id > 0 || ! empty($ref)) print ''; - print '
    '; + //print '
    '; include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0c19d216164..62b2fb274c8 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -780,7 +780,7 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename=' * @param array $links Array of tabs. Currently initialized by calling a function xxx_admin_prepare_head * @param string $active Active tab name (document', 'info', 'ldap', ....) * @param string $title Title - * @param int $notab 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. + * @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. * @param string $picto Add a picto on tab title * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto. * @return void @@ -796,7 +796,7 @@ function dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto * @param array $links Array of tabs * @param string $active Active tab name * @param string $title Title - * @param int $notab 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. + * @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. * @param string $picto Add a picto on tab title * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto. * @return string @@ -926,7 +926,7 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi $out.="\n"; - if (! $notab) $out.="\n".'
    '."\n"; + if (! $notab || $notab == -1) $out.="\n".'
    '."\n"; $parameters=array('tabname' => $active, 'out' => $out); $reshook=$hookmanager->executeHooks('printTabsHead',$parameters); // This hook usage is called just before output the head of tabs. Take also a look at "completeTabsHead" @@ -941,7 +941,7 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi /** * Show tab footer of a card * - * @param int $notab 0=Add tab footer, 1=no tab footer + * @param int $notab -1 or 0=Add tab footer, 1=no tab footer * @return void */ function dol_fiche_end($notab=0) @@ -952,12 +952,12 @@ function dol_fiche_end($notab=0) /** * Return tab footer of a card * - * @param int $notab 0=Add tab footer, 1=no tab footer + * @param int $notab -1 or 0=Add tab footer, 1=no tab footer * @return string */ function dol_get_fiche_end($notab=0) { - if (! $notab) return "\n
    \n"; + if (! $notab || $notab == -1) return "\n
    \n"; else return ''; } diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 474a037d23f..74c02440a9f 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -1506,7 +1506,7 @@ else if ($modCodeClient->code_auto || $modCodeFournisseur->code_auto) print ''; - dol_fiche_head($head, 'card', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'card', $langs->trans("ThirdParty"), 0, 'company'); print ''; @@ -1921,7 +1921,7 @@ else $head = societe_prepare_head($object); - dol_fiche_head($head, 'card', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'card', $langs->trans("ThirdParty"), 0, 'company'); // Confirm delete third party if ($action == 'delete' || ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile))) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index e02a512f327..8ec24860e14 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1773,7 +1773,6 @@ if ($action == 'create') print ''; } - print "
    \n"; if ($action != 'presend') { diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 17e77025da8..a665002e30a 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1878,20 +1878,21 @@ div.tabBar { color: #; padding-top: 16px; padding-left: 0px; padding-right: 0px; - padding-bottom: 14px; - margin: 0px 0px 14px 0px; + padding-bottom: 2px; + margin: 0px 0px 16px 0px; border-top: 1px solid #BBB; - border-bottom: 1px solid #AAA; + /* border-bottom: 1px solid #AAA; */ width: auto; - background: rgb(); - - /* - -moz-box-shadow: 3px 3px 4px #DDD; - -webkit-box-shadow: 3px 3px 4px #DDD; - box-shadow: 3px 3px 4px #DDD; - */ } +div.tabBarWithBottom { + padding-bottom: 18px; + border-bottom: 1px solid #aaa; +} +div.tabBar table.tableforservicepart2:last-child { + border-bottom: 1px solid #aaa; +} + div.popuptabset { padding: 6px; background: #fff; @@ -1904,7 +1905,7 @@ div.popuptab { padding-right: 5px; } div.tabsAction { - margin: 20px 0em 10px 0em; + margin: 20px 0em 25px 0em; padding: 0em 0em; text-align: right; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 4470cbed751..913a269b0f2 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1883,30 +1883,28 @@ div.tabBar { padding-top: px; padding-left: px; padding-right: px; - padding-bottom: px; - margin: 0px 0px 14px 0px; + padding-bottom: px; + margin: 0px 0px 16px 0px; -moz-border-radius:3px; -webkit-border-radius: 3px; border-radius: 3px; border-right: 1px solid #BBB; - border-bottom: 1px solid #BBB; + /* border-bottom: 1px solid #BBB; */ border-left: 1px solid #BBB; border-top: 1px solid #CCC; width: auto; - background: rgb(); - - /* - - -moz-box-shadow: 3px 3px 4px #f4f4f4; - -webkit-box-shadow: 3px 3px 4px #f4f4f4; - box-shadow: 3px 3px 4px #f4f4f4; - - */ +} +div.tabBarWithBottom { + padding-bottom: 18px; + border-bottom: 1px solid #aaa; +} +div.tabBar table.tableforservicepart2:last-child { + border-bottom: 1px solid #aaa; } div.tabsAction { - margin: 20px 0em 10px 0em; + margin: 20px 0em 25px 0em; padding: 0em 0em; text-align: right; } From e6d8b3c4db761bc55a63d02f83c5e98e8b9d2cef Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 15 Mar 2017 11:41:15 +0100 Subject: [PATCH 107/410] Css enhancement --- htdocs/core/tpl/contacts.tpl.php | 20 ++++++++++---------- htdocs/theme/eldy/style.css.php | 10 ++++++++++ htdocs/theme/md/style.css.php | 3 +++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 3f8006c286b..0a17a8c07c2 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -90,7 +90,7 @@ if ($permission) { echo $formcompany->selectTypeContact($tmpobject, '', 'type','internal'); ?>
     
    -
    ">
    +
    ">
    '; ?> -
    trans("ThirdPartyContacts"); ?>
    -
    +
    trans("ThirdPartyContacts"); ?>
    +
    socid; ?> selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', '', 0); ?>
    -
    +
    select_contacts($selectedCompany, '', 'contactid', 0, '', '', 0, 'minwidth200'); ?>
    -
    +
    element == 'shipping' && is_object($objectsrc)) $tmpobject=$objectsrc; $formcompany->selectTypeContact($tmpobject, '', 'type','external'); ?>
    -
     
    -
    +
     
    +
    ">
    @@ -144,7 +144,7 @@ if ($permission) {
    trans("ThirdParty"); ?>
    trans("Users").'/'.$langs->trans("Contacts"); ?>
    trans("ContactType"); ?>
    -
    trans("Status"); ?>
    +
    trans("Status"); ?>
     
    @@ -208,7 +208,7 @@ if ($permission) { ?>
    -
    +
    statut >= 0) echo ''; ?> statut >= 0) echo ''; ?>
    -
    +
     "> diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a665002e30a..832b13dedf9 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2326,6 +2326,9 @@ td.border, div.tagtable div div.border { /* Main boxes */ +.noborderbottom { + border-bottom: none !important; +} .ficheaddleft table.noborder { margin: 0px 0px 0px 0px; } @@ -2345,6 +2348,13 @@ table.liste, table.noborder, table.formdoc, div.noborder { margin: 0px 0px 5px 0px; } +div.ficheaddleft table.noborder:last-child { + border-bottom: 1px solid #aaa; +} +div.ficheaddleft table.noborder { + border-bottom: none; +} + table.paddingtopbottomonly tr td { padding-top: 1px; padding-bottom: 2px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 913a269b0f2..6bca9f1751e 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2228,6 +2228,9 @@ td.border, div.tagtable div div.border { /* Main boxes */ +.noborderbottom { + border-bottom: none !important; +} .ficheaddleft table.noborder { margin: 0px 0px 0px 0px; } From 4c0ff38020f22ab337950702f98cf0e5ac89eec7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 15 Mar 2017 11:58:13 +0100 Subject: [PATCH 108/410] Fix closing boxes --- htdocs/core/class/html.formother.class.php | 6 +++--- htdocs/hrm/index.php | 2 +- htdocs/theme/eldy/style.css.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 5f8fe76e320..77d3e6cf271 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -1046,7 +1046,7 @@ class FormOther if (boxorder==\'A:A-B:B\' && closing == 1) // There is no more boxes on screen, and we are after a delete of a box so we must hide title { jQuery.ajax({ - url: \''.DOL_URL_ROOT.'/core/ajax/box.php?closing=\'+closing+\'&boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.', + url: \''.DOL_URL_ROOT.'/core/ajax/box.php?closing=0&boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.', async: false }); // We force reload to be sure to get all boxes into list @@ -1086,7 +1086,7 @@ class FormOther containment: \'.fiche\', connectWith: \'.connectedSortable\', stop: function(event, ui) { - updateBoxOrder(0); + updateBoxOrder(1); /* 1 to avoid message after a move */ } }); @@ -1096,7 +1096,7 @@ class FormOther var label=jQuery(\'#boxlabelentry\'+boxid).val(); jQuery(\'#boxto_\'+boxid).remove(); if (boxid > 0) jQuery(\'#boxcombo\').append(new Option(label, boxid)); - updateBoxOrder(1); + updateBoxOrder(1); /* 1 to avoid message after a remove */ }); });'."\n"; diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index b0e2bf58d79..63700629fd8 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -355,7 +355,7 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire { print '
    '; } - print '
    '.$langs->trans("None").'

    '; + print '
    '; } else dol_print_error($db); } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 832b13dedf9..90aebd7d908 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2348,10 +2348,10 @@ table.liste, table.noborder, table.formdoc, div.noborder { margin: 0px 0px 5px 0px; } -div.ficheaddleft table.noborder:last-child { +div.tabBar div.ficheaddleft table.noborder:last-of-type { border-bottom: 1px solid #aaa; } -div.ficheaddleft table.noborder { +div.tabBar div.ficheaddleft table.noborder { border-bottom: none; } From 6f25d6de2474f53bf511adcdc1537ba15f8b3c8d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 15 Mar 2017 12:33:06 +0100 Subject: [PATCH 109/410] Fix bad management of PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY --- htdocs/core/class/html.formprojet.class.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 47706d90d7f..b85c485e681 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -153,7 +153,14 @@ class FormProjets $sql.= " WHERE p.entity IN (".getEntity('project', 1).")"; if ($projectsListId !== false) $sql.= " AND p.rowid IN (".$projectsListId.")"; if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)"; - if ($socid > 0 && empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY)) $sql.= " AND (p.fk_soc=".$socid." OR p.fk_soc IS NULL)"; + if ($socid > 0) + { + if (empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY)) $sql.= " AND (p.fk_soc=".$socid." OR p.fk_soc IS NULL)"; + else if ($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY != 'all') // PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY is 'all' or a list of ids separated by coma. + { + $sql.= " AND (p.fk_soc IN (".$socid.", ".$conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY.") OR p.fk_soc IS NULL)"; + } + } if (!empty($filterkey)) { $sql .= ' AND ('; $sql .= ' p.title LIKE "%'.$this->db->escape($filterkey).'%"'; From deb91ad7c17490934c988b36823a21ba03354733 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 15 Mar 2017 13:30:30 +0100 Subject: [PATCH 110/410] FIX Data lost during merge of thirdparties --- htdocs/langs/en_US/companies.lang | 2 +- htdocs/societe/soc.php | 43 +++++++++++++++++-- .../class/supplier_proposal.class.php | 18 ++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 166633ef2ae..355f9f3f31c 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -397,7 +397,7 @@ LeopardNumRefModelDesc=The code is free. This code can be modified at any time. ManagingDirectors=Manager(s) name (CEO, director, president...) MergeOriginThirdparty=Duplicate third party (third party you want to delete) MergeThirdparties=Merge third parties -ConfirmMergeThirdparties=Are you sure you want to merge this third party into the current one? All linked objects (invoices, orders, ...) will be moved to current third party so you will be able to delete the duplicate one. +ConfirmMergeThirdparties=Are you sure you want to merge this third party into the current one? All linked objects (invoices, orders, ...) will be moved to current third party, then the thirdparty will be deleted. ThirdpartiesMergeSuccess=Thirdparties have been merged SaleRepresentativeLogin=Login of sales representative SaleRepresentativeFirstname=First name of sales representative diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 3da099390ac..b5bda51b4ba 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -123,15 +123,14 @@ if (empty($reshook)) $soc_origin_id = GETPOST('soc_origin', 'int'); $soc_origin = new Societe($db); - if ($soc_origin_id < 1) + if ($soc_origin_id <= 0) { $langs->load('errors'); $langs->load('companies'); - setEventMessages($langs->trans('ErrorProdIdIsMandatory', $langs->trans('MergeOriginThirdparty')), null, 'errors'); + setEventMessages($langs->trans('ErrorThirdPartyIdIsMandatory', $langs->trans('MergeOriginThirdparty')), null, 'errors'); } else { - if (!$errors && $soc_origin->fetch($soc_origin_id) < 1) { setEventMessages($langs->trans('ErrorRecordNotFound'), null, 'errors'); @@ -140,8 +139,44 @@ if (empty($reshook)) if (!$errors) { + // TODO Move the merge function into class of object. + $db->begin(); + // Recopy some data + $object->client = $object->client | $soc_origin->client; + $object->fournisseur = $object->fournisseur | $soc_origin->fournisseur; + $listofproperties=array( + 'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode', 'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6', + 'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis', + 'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency', + 'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur', + 'model_pdf', 'fk_projet' + ); + foreach ($listofproperties as $property) + { + if (empty($object->$property)) $object->$property = $soc_origin->$property; + } + + // Concat some data + $listofproperties=array( + 'note_public', 'note_private' + ); + foreach ($listofproperties as $property) + { + $object->$property = dol_concatdesc($object->$property, $soc_origin->$property); + } + + // Merge extrafields + foreach ($soc_origin->array_options as $key => $val) + { + if (empty($object->array_options[$key])) $object->array_options[$key] = $val; + } + + // TODO Merge categories + $object->update($object->id, $user); + + // Move links $objects = array( 'Adherent' => '/adherents/class/adherent.class.php', 'Societe' => '/societe/class/societe.class.php', @@ -159,6 +194,7 @@ if (empty($reshook)) 'Fichinter' => '/fichinter/class/fichinter.class.php', 'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php', 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', + 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php', 'Livraison' => '/livraison/class/livraison.class.php', 'Product' => '/product/class/product.class.php', @@ -451,6 +487,7 @@ if (empty($reshook)) if (empty($object->fournisseur)) $object->code_fournisseur=''; $result = $object->create($user); + if ($result >= 0) { if ($object->particulier) diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 53e7bf8ad34..d666f421cdb 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2532,6 +2532,24 @@ class SupplierProposal extends CommonObject return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); } + + /** + * Function used to replace a thirdparty id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old thirdparty id + * @param int $dest_id New thirdparty id + * @return bool + */ + public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'supplier_proposal' + ); + + return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); + } + } From 4e1799b2be6d9ca4c862f864c69a59a760e10b32 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Wed, 15 Mar 2017 21:31:44 +0100 Subject: [PATCH 111/410] Add fin_validite, date_cloture in fetch --- htdocs/contrat/class/contrat.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 1562cfcd942..10971a3b452 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -496,7 +496,7 @@ class Contrat extends CommonObject $sql.= " ref_supplier, ref_customer,"; $sql.= " ref_ext,"; $sql.= " fk_user_mise_en_service, date_contrat as datecontrat,"; - $sql.= " fk_user_author,"; + $sql.= " fk_user_author, fin_validite, date_cloture,"; $sql.= " fk_projet,"; $sql.= " fk_commercial_signature, fk_commercial_suivi,"; $sql.= " note_private, note_public, model_pdf, extraparams"; @@ -527,6 +527,10 @@ class Contrat extends CommonObject $this->date_contrat = $this->db->jdate($result["datecontrat"]); $this->date_creation = $this->db->jdate($result["datecontrat"]); + $this->fin_validite = $this->db->jdate($result["fin_validite"]); + $this->date_cloture = $this->db->jdate($result["date_cloture"]); + + $this->user_author_id = $result["fk_user_author"]; $this->commercial_signature_id = $result["fk_commercial_signature"]; From f9c2bb0410c50c483cf2d1b83398dc8530c2b744 Mon Sep 17 00:00:00 2001 From: fappels Date: Thu, 16 Mar 2017 10:05:50 +0100 Subject: [PATCH 112/410] Fix create supplier order line label Fix create line label Fix read line rang, special_code and fk_parent_line Remove create line rang, done by table default and $this->rang is invalid, supplier order has no rang property. --- htdocs/fourn/class/fournisseur.commande.class.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 15939384670..a4c18986fe4 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -350,10 +350,10 @@ class CommandeFournisseur extends CommonOrder $line->multicurrency_total_tva = $objp->multicurrency_total_tva; $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc; - $this->special_code = $objp->special_code; - $this->fk_parent_line = $objp->fk_parent_line; + $line->special_code = $objp->special_code; + $line->fk_parent_line = $objp->fk_parent_line; - $this->rang = $objp->rang; + $line->rang = $objp->rang; $this->lines[$i] = $line; @@ -1399,7 +1399,7 @@ class CommandeFournisseur extends CommonOrder if ($prod->fetch($fk_product) > 0) { $product_type = $prod->type; - $label = $prod->libelle; + $label = $prod->label; // 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. @@ -1501,7 +1501,6 @@ class CommandeFournisseur extends CommonOrder $this->line->product_type=$product_type; $this->line->remise_percent=$remise_percent; $this->line->subprice=$pu_ht; - $this->line->rang=$this->rang; $this->line->info_bits=$info_bits; $this->line->vat_src_code=$vat_src_code; @@ -3086,7 +3085,7 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql.= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_unit,"; $sql.= " fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc"; $sql.= ")"; - $sql.= " VALUES (".$this->fk_commande.", '" . $this->db->escape($this->product_label) . "','" . $this->db->escape($this->desc) . "',"; + $sql.= " VALUES (".$this->fk_commande.", '" . $this->db->escape($this->label) . "','" . $this->db->escape($this->desc) . "',"; $sql.= " ".($this->date_start?"'".$this->db->idate($this->date_start)."'":"null").","; $sql.= " ".($this->date_end?"'".$this->db->idate($this->date_end)."'":"null").","; if ($this->fk_product) { $sql.= $this->fk_product.","; } From 68e50d0c7931176d8966e203247de767c62239ad Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Mar 2017 10:36:17 +0100 Subject: [PATCH 113/410] FIX Filter on date lost after submit on time spent page --- htdocs/commande/card.php | 3 ++- htdocs/commande/info.php | 2 ++ htdocs/projet/activity/perweek.php | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index a98019eba89..fda37a88467 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -60,6 +60,7 @@ $langs->load('propal'); $langs->load('deliveries'); $langs->load('sendings'); $langs->load('products'); +$langs->load('other'); if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); if (! empty($conf->margin->enabled)) $langs->load('margins'); if (! empty($conf->productbatch->enabled)) $langs->load("productbatch"); @@ -2079,7 +2080,7 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; print ''; } else { - print $object->date ? dol_print_date($object->date, 'daytext') : ' '; + print $object->date ? dol_print_date($object->date, 'day') : ' '; if ($object->hasDelay() && empty($object->date_livraison)) { print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning"); } diff --git a/htdocs/commande/info.php b/htdocs/commande/info.php index 58b445c8ce7..9ee0e85e73e 100644 --- a/htdocs/commande/info.php +++ b/htdocs/commande/info.php @@ -53,6 +53,8 @@ if (! $object->fetch($id, $ref) > 0) * View */ +$form = new Form($db); + llxHeader('',$langs->trans('Order'),'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'); $object->fetch_thirdparty(); diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 9a34913b2f5..7bfa7728d4f 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -262,7 +262,7 @@ if ($action == 'addtime' && $user->rights->projet->lire) setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); // Redirect to avoid submit twice on back - header('Location: '.$_SERVER["PHP_SELF"].($projectid?'?id='.$projectid:'?').($mode?'&mode='.$mode:'')); + header('Location: '.$_SERVER["PHP_SELF"].($projectid?'?id='.$projectid:'?').($mode?'&mode='.$mode:'').($day?'&day='.$day:'').($month?'&month='.$month:'').($year?'&year='.$year:'')); exit; } } From 0d6a99b35ac15ba712799d67ce109f7afff13b3b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Mar 2017 11:01:35 +0100 Subject: [PATCH 114/410] Fix space --- htdocs/core/lib/project.lib.php | 6 +++--- htdocs/projet/activity/perday.php | 10 +++++----- htdocs/projet/activity/perweek.php | 26 +++++++++++++------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 173aee8ce26..4bfc8e4d97b 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -635,7 +635,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) { // Thirdparty - print '
    '; + print ''; $thirdpartystatic->id=$lines[$i]->socid; $thirdpartystatic->name=$lines[$i]->thirdparty_name; print $thirdpartystatic->getNomUrl(1, 'project', 10); @@ -839,10 +839,10 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) { // Thirdparty - print ''; + print ''; $thirdpartystatic->id=$lines[$i]->thirdparty_id; $thirdpartystatic->name=$lines[$i]->thirdparty_name; - print $thirdpartystatic->getNomUrl(1, 'project', 10); + print $thirdpartystatic->getNomUrl(1, 'project'); print ''.$langs->trans("ThirdParty").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").''.$langs->trans("TimeSpentByYou").''.$langs->trans("TimeSpentByUser").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").''.$langs->trans("TimeSpentByYou").''.$langs->trans("TimeSpentByUser").''.$langs->trans("HourStart").''.$langs->trans("Duration").''.$langs->trans("Note").''.$langs->trans("ThirdParty").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").''.$langs->trans("TimeSpentByYou").''.$langs->trans("TimeSpentByUser").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").''.$langs->trans("TimeSpentByYou").''.$langs->trans("TimeSpentByUser").''.dol_print_date($startday + ($i * 3600 * 24), '%a').'
    '.dol_print_date($startday + ($i * 3600 * 24), 'dayreduceformat').'
    '.dol_print_date($startday + ($i * 3600 * 24), '%a').'
    '.dol_print_date($startday + ($i * 3600 * 24), 'dayreduceformat').'
    '.$langs->trans("Total").'
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    '; if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("YouAreNotContactOfProject")); diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 692c5ecfad4..a65ffdd64e2 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -323,7 +323,7 @@ $nav.=" ".dol_print_date(dol_mktime(0,0,0,$month,$day,$y $nav.=''.img_next($langs->trans("Next"))."\n"; $nav.="   (".$langs->trans("Today").")"; $nav.='
    '.$form->select_date(-1,'',0,0,2,"addtime",1,0,1).' '; -$nav.=' '; +$nav.=' '; $picto='calendarweek'; @@ -338,9 +338,10 @@ print ''; print ''; $head=project_timesheet_prepare_head($mode); -dol_fiche_head($head, 'inputperday', '', 0, 'task'); +dol_fiche_head($head, 'inputperday', '', -1, 'task'); // Show description of content +print '
    '; if ($mine) print $langs->trans("MyTasksDesc").($onlyopenedproject?' '.$langs->trans("OnlyOpenedProject"):'').'
    '; else { @@ -355,6 +356,7 @@ else { print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
    '; } +print '
    '; dol_fiche_end(); @@ -389,7 +391,7 @@ dol_fiche_end(); //print ''; //print ''; -print '
    '.$nav.'
    '; // We move this before the assign to components so, the default submit button is not the assign to. +print '
    '.$nav.'
    '; // We move this before the assign to components so, the default submit button is not the assign to. print '
    '; print $langs->trans("AssignTaskToMe").'
    '; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index e1c71a98ba7..5847e91d46c 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -334,9 +334,10 @@ print ''; print ''; $head=project_timesheet_prepare_head($mode); -dol_fiche_head($head, 'inputperweek', '', 0, 'task'); +dol_fiche_head($head, 'inputperweek', '', -1, 'task'); // Show description of content +print '
    '; if ($mine) print $langs->trans("MyTasksDesc").($onlyopenedproject?' '.$langs->trans("OnlyOpenedProject"):'').'
    '; else { @@ -351,6 +352,7 @@ else { print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
    '; } +print '
    '; dol_fiche_end(); @@ -384,7 +386,7 @@ dol_fiche_end(); //print ''; //print ''; -print '
    '.$nav.'
    '; // We move this before the assign to components so, the default submit button is not the assign to. +print '
    '.$nav.'
    '; // We move this before the assign to components so, the default submit button is not the assign to. print '
    '; print $langs->trans("AssignTaskToMe").'
    '; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 90aebd7d908..3d6e8868bec 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -761,8 +761,8 @@ div.fiche>form>div.div-table-responsive { min-width: 20px; min-height: 1.4em; line-height: 1.4em; - padding: .4em .1em; - border: 1px solid #BBB; + /* padding: .4em .1em; */ + /* border-bottom: 1px solid #BBB; */ /* max-width: inherit; why this ? */ } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6bca9f1751e..aae0fd7f677 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -771,8 +771,8 @@ div.fiche>form>div.div-table-responsive { min-width: 20px; min-height: 1.4em; line-height: 1.4em; - padding: .4em .1em; - border: 1px solid #BBB; + /* padding: .4em .1em; */ + /* border-bottom: 1px solid #BBB; */ /* max-width: inherit; why this */ } From 35b79818b7699586c221c285e4282cd62e1f890c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Mar 2017 20:33:51 +0100 Subject: [PATCH 116/410] Uniformize css rules --- htdocs/core/class/html.formother.class.php | 2 +- htdocs/core/modules/modSociete.class.php | 2 +- htdocs/exports/export.php | 51 ++++++++++++++-------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 77d3e6cf271..95dee1424ef 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -72,7 +72,7 @@ class FormOther $result = $this->db->query($sql); if ($result) { - print ''; if ($useempty) { print ''; diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 6c1929d1dc9..a2239514898 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -270,7 +270,7 @@ class modSociete extends DolibarrModules include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; $this->export_fields_array[$r]+=array('u.login'=>'SaleRepresentativeLogin','u.firstname'=>'SaleRepresentativeFirstname', 'u.lastname'=>'SaleRepresentativeLastname'); //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>"Text",'s.status'=>"Text",'s.client'=>"Boolean",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note'=>"Text",'t.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code','s.fk_stcomm'=>'List:c_stcomm:libelle:code','d.nom'=>'List:c_departements:nom:rowid'); - $this->export_TypeFields_array[$r]=array('s.nom'=>"Text",'s.status'=>"Numeric",'s.client'=>"Numeric",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.code_compta'=>"Text",'s.code_compta_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_private'=>"Text",'s.note_public'=>"Text",'t.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code','st.code'=>'List:c_stcomm:libelle:code','d.nom'=>'Text','u.login'=>'Text','u.firstname'=>'Text','u.lastname'=>'Text','payterm.libelle'=>'Text','paymode.libelle'=>'Text','s.entity'=>'Numeric'); + $this->export_TypeFields_array[$r]=array('s.rowid'=>"Numeric", 's.nom'=>"Text",'s.status'=>"Numeric",'s.client'=>"Numeric",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.code_compta'=>"Text",'s.code_compta_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_private'=>"Text",'s.note_public'=>"Text",'t.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code','st.code'=>'List:c_stcomm:libelle:code','d.nom'=>'Text','u.login'=>'Text','u.firstname'=>'Text','u.lastname'=>'Text','payterm.libelle'=>'Text','paymode.libelle'=>'Text','s.entity'=>'Numeric'); $this->export_entities_array[$r]=array('u.login'=>'user','u.firstname'=>'user','u.lastname'=>'user'); // We define here only fields that use another picto $this->export_examplevalues_array[$r]=array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)','s.fournisseur'=>'0 (not a supplier) or 1 (supplier)'); diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 24b9ef3728e..152e095afa6 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -510,19 +510,21 @@ if ($step == 2 && $datatoexport) $hselected=$h; $h++; - dol_fiche_head($head, $hselected, $langs->trans("NewExport")); + dol_fiche_head($head, $hselected, $langs->trans("NewExport"), -1); + print '
    '; + print '
    '; print ''; // Module - print ''; + print ''; print ''; // Lot de donnees a exporter - print ''; + print ''; print ''; print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; //print img_object($objexport->array_export_module[0]->getName(),$objexport->array_export_module[0]->picto).' '; print $objexport->array_export_module[0]->getName(); print '
    '.$langs->trans("DatasetToExport").'
    '.$langs->trans("DatasetToExport").''; $icon=preg_replace('/:.*$/','',$objexport->array_export_icon[0]); $label=$objexport->array_export_label[0]; @@ -532,6 +534,10 @@ if ($step == 2 && $datatoexport) print '
    '; + print '
    '; + + dol_fiche_end(); + print '
    '; // Combo list of export models @@ -543,6 +549,7 @@ if ($step == 2 && $datatoexport) print '
    '; print $langs->trans("SelectExportFields").' '; $htmlother->select_export_model($exportmodelid,'exportmodelid',$datatoexport,1); + print ' '; print ''; print '
    '; print ''; @@ -635,8 +642,7 @@ if ($step == 2 && $datatoexport) print '
    '; - print ''; - + /* * Barre d'action * @@ -693,19 +699,21 @@ if ($step == 3 && $datatoexport) $hselected=$h; $h++; - dol_fiche_head($head, $hselected, $langs->trans("NewExport")); + dol_fiche_head($head, $hselected, $langs->trans("NewExport"), -1); + print '
    '; + print '
    '; print ''; // Module - print ''; + print ''; print ''; // Lot de donnees a exporter - print ''; + print ''; print ''; // Nbre champs exportes - print ''; + print ''; $list=''; foreach($array_selected as $code=>$value) { @@ -725,6 +733,8 @@ if ($step == 3 && $datatoexport) print ''; print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; //print img_object($objexport->array_export_module[0]->getName(),$objexport->array_export_module[0]->picto).' '; print $objexport->array_export_module[0]->getName(); print '
    '.$langs->trans("DatasetToExport").'
    '.$langs->trans("DatasetToExport").''; $icon=preg_replace('/:.*$/','',$objexport->array_export_icon[0]); $label=$objexport->array_export_label[0]; @@ -715,7 +723,7 @@ if ($step == 3 && $datatoexport) print '
    '.$langs->trans("ExportedFields").'
    '.$langs->trans("ExportedFields").''.$list.'
    '; + print '
    '; + print '
    '; // Combo list of export models @@ -866,8 +876,10 @@ if ($step == 4 && $datatoexport) $hselected=$h; $h++; - dol_fiche_head($head, $hselected, $langs->trans("NewExport")); + dol_fiche_head($head, $hselected, $langs->trans("NewExport"), -1); + print '
    '; + print '
    '; print ''; // Module @@ -918,6 +930,8 @@ if ($step == 4 && $datatoexport) } print '
    '; + print '
    '; + print '
    '; // Select request if all fields are selected @@ -1102,7 +1116,7 @@ if ($step == 5 && $datatoexport) $hselected=$h; $h++; - dol_fiche_head($head, $hselected, $langs->trans("NewExport")); + dol_fiche_head($head, $hselected, $langs->trans("NewExport"), -1); /* * Confirmation suppression fichier @@ -1113,17 +1127,20 @@ if ($step == 5 && $datatoexport) } + print '
    '; + print '
    '; + print ''; // Module - print ''; + print ''; print ''; // Lot de donnees a exporter - print ''; + print ''; print ''; // List of exported fields - print ''; + print ''; $list=''; foreach($array_selected as $code=>$label) { @@ -1143,7 +1160,7 @@ if ($step == 5 && $datatoexport) // List of filtered fiels if (isset($objexport->array_export_TypeFields[0]) && is_array($objexport->array_export_TypeFields[0])) { - print ''; + print ''; $list=''; if (! empty($array_filtervalue)) { @@ -1162,6 +1179,8 @@ if ($step == 5 && $datatoexport) } print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; //print img_object($objexport->array_export_module[0]->getName(),$objexport->array_export_module[0]->picto).' '; print $objexport->array_export_module[0]->getName(); print '
    '.$langs->trans("DatasetToExport").'
    '.$langs->trans("DatasetToExport").''; $icon=preg_replace('/:.*$/','',$objexport->array_export_icon[0]); print img_object($objexport->array_export_module[0]->getName(), $icon).' '; @@ -1131,7 +1148,7 @@ if ($step == 5 && $datatoexport) print '
    '.$langs->trans("ExportedFields").'
    '.$langs->trans("ExportedFields").'
    '.$langs->trans("FilteredFields").'
    '.$langs->trans("FilteredFields").'
    '; + print '
    '; + print '
    '; print $langs->trans("NowClickToGenerateToBuildExportFile").'
    '; @@ -1222,8 +1241,6 @@ if ($step == 5 && $datatoexport) print ''; } -print '
    '; - llxFooter(); $db->close(); From 68d3a930278d461dfc7288f4e56822e1637fd632 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Mar 2017 20:36:51 +0100 Subject: [PATCH 117/410] Fix link to reconcile --- htdocs/core/menus/standard/eldy.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index d9a09d748d1..cbd8b83da7c 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1422,7 +1422,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add('/compta/bank/card.php?id='.$objp->rowid,$objp->label,1,$user->rights->banque->lire); if ($objp->rappro && $objp->courant != Account::TYPE_CASH && empty($objp->clos)) // If not cash account and not closed and can be reconciliate { - $newmenu->add('/compta/bank/bankentries.php?id='.$objp->rowid,$langs->trans("Conciliate"),2,$user->rights->banque->consolidate); + $newmenu->add('/compta/bank/bankentries.php?action=reconcile&contextpage=banktransactionlist-'.$objp->rowid.'&account='.$objp->rowid.'&id='.$objp->rowid,$langs->trans("Conciliate"),2,$user->rights->banque->consolidate); } $i++; } From 7dd0f14563de3d2ceaf90da2ffb18cd469b2b188 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Mar 2017 21:03:35 +0100 Subject: [PATCH 118/410] Fix link to reconciliated function --- htdocs/compta/bank/bankentries.php | 30 ++++++++++++++++++++----- htdocs/core/menus/standard/eldy.lib.php | 2 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index ad3817f28cd..de0e6d70b4c 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -91,6 +91,7 @@ $search_dv_end = dol_mktime(0, 0, 0, GETPOST('search_end_dvmonth', 'int'), GETPO $search_thirdparty=GETPOST("thirdparty",'alpha'); $search_req_nb=GETPOST("req_nb",'alpha'); $search_num_releve=GETPOST("search_num_releve",'alpha'); +$search_conciliated=GETPOST("search_conciliated",'int'); $num_releve=GETPOST("num_releve"); $cat=GETPOST("cat"); @@ -150,6 +151,7 @@ $arrayfields=array( 'b.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1, 'position'=>605), 'balance'=>array('label'=>$langs->trans("Balance"), 'checked'=>1, 'position'=>1000), 'b.num_releve'=>array('label'=>$langs->trans("AccountStatement"), 'checked'=>1, 'position'=>1010), + 'b.conciliated'=>array('label'=>$langs->trans("Conciliated"), 'enabled'=> $object->rappro, 'checked'=>($action == 'reconcile'?1:0), 'position'=>1020), ); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -190,6 +192,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP $search_req_nb=''; $search_thirdparty=''; $search_num_releve=''; + $search_conciliated=''; $thirdparty=''; $account=""; @@ -444,7 +447,7 @@ else llxHeader('', $langs->trans("BankTransactions"), '', '', 0, 0, array(), array(), $param); } -$sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro, b.num_releve, b.num_chq,"; +$sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro as conciliated, b.num_releve, b.num_chq,"; $sql.= " b.fk_account, b.fk_type,"; $sql.= " ba.rowid as bankid, ba.ref as bankref,"; $sql.= " bu.url_id,"; @@ -474,6 +477,7 @@ if (dol_strlen($search_dv_end)>0) $sql .= " AND b.datev <= '" . $db->idate($sear if ($search_ref) $sql.=natural_search("b.rowid", $search_ref); if ($search_req_nb) $sql.= natural_search("b.num_chq", $search_req_nb); if ($search_num_releve) $sql.= natural_search("b.num_releve", $search_num_releve); +if ($search_conciliated != '' && $search_conciliated != '-1') $sql.= " AND b.rappro = ".$search_conciliated; if ($search_thirdparty) $sql.= natural_search("s.nom", $search_thirdparty); if ($description) $sql.= natural_search("b.label", $description); // Warning some text are just translation keys, not translated strings if ($bid) $sql.= " AND b.rowid=l.lineid AND l.fk_categ=".$bid; @@ -776,6 +780,7 @@ if ($resql) if (! empty($arrayfields['b.credit']['checked'])) print_liste_field_titre($arrayfields['b.credit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['b.num_releve']['checked'])) print_liste_field_titre($arrayfields['b.num_releve']['label'],$_SERVER['PHP_SELF'],'b.num_releve','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.conciliated']['checked'])) print_liste_field_titre($arrayfields['b.conciliated']['label'],$_SERVER['PHP_SELF'],'b.rappro','',$param,'align="center"',$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -857,11 +862,18 @@ if ($resql) print $form->textwithpicto('', $htmltext, 1); print '
    '; + print $form->selectyesno('search_conciliated', $search_conciliated, 1, False, 1); + print ''; print ''; @@ -1207,7 +1219,7 @@ if ($resql) // Transaction reconciliated or edit link if ($bankaccount->canBeConciliated() > 0) { - if ($objp->rappro) // If line not conciliated and account can be conciliated + if ($objp->conciliated) // If line not conciliated and account can be conciliated { print ''.$objp->num_releve.''; } @@ -1220,10 +1232,18 @@ if ($resql) if (! $i) $totalarray['nbfield']++; } + if (! empty($arrayfields['b.conciliated']['checked'])) + { + print ''; + print $objp->conciliated?$langs->trans("Yes"):$langs->trans("No"); + print ''; // Transaction reconciliated or edit link - if ($objp->rappro && $bankaccount->canBeConciliated() > 0) // If line not conciliated and account can be conciliated + if ($objp->conciliated && $bankaccount->canBeConciliated() > 0) // If line not conciliated and account can be conciliated { print ''; print img_edit(); @@ -1243,7 +1263,7 @@ if ($resql) print img_view(); print ''; } - if ($bankaccount->canBeConciliated() > 0 && empty($objp->rappro)) + if ($bankaccount->canBeConciliated() > 0 && empty($objp->conciliated)) { if ($db->jdate($objp->dv) < ($now - $conf->bank->rappro->warning_delay)) { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index cbd8b83da7c..b01286b3812 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1422,7 +1422,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add('/compta/bank/card.php?id='.$objp->rowid,$objp->label,1,$user->rights->banque->lire); if ($objp->rappro && $objp->courant != Account::TYPE_CASH && empty($objp->clos)) // If not cash account and not closed and can be reconciliate { - $newmenu->add('/compta/bank/bankentries.php?action=reconcile&contextpage=banktransactionlist-'.$objp->rowid.'&account='.$objp->rowid.'&id='.$objp->rowid,$langs->trans("Conciliate"),2,$user->rights->banque->consolidate); + $newmenu->add('/compta/bank/bankentries.php?action=reconcile&contextpage=banktransactionlist-'.$objp->rowid.'&account='.$objp->rowid.'&id='.$objp->rowid.'&search_conciliated=0',$langs->trans("Conciliate"),2,$user->rights->banque->consolidate); } $i++; } From dfc1ed7d7297fdb6e42de3d75f3e9f7bf6866217 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Mar 2017 22:36:44 +0100 Subject: [PATCH 119/410] FIX #6535 --- .../categories/class/api_categories.class.php | 45 +++++++++++++++++-- .../class/api_deprecated_category.class.php | 2 +- htdocs/product/class/api_products.class.php | 2 +- htdocs/societe/class/api_contacts.class.php | 2 +- .../societe/class/api_thirdparties.class.php | 2 +- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index 1f37623544b..a08abdfc545 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -248,6 +248,7 @@ class Categories extends DolibarrApi if( ! count($obj_ret)) { throw new RestException(404, 'No category found'); } + return $obj_ret; } @@ -351,9 +352,47 @@ class Categories extends DolibarrApi $object = parent::_cleanObjectDatas($object); - // Remove the subscriptions because they are handled as a subresource. - //unset($object->subscriptions); - + // Remove fields not relevent to categories + unset($object->country); + unset($object->country_id); + unset($object->country_code); + unset($object->total_ht); + unset($object->total_ht); + unset($object->total_localtax1); + unset($object->total_localtax2); + unset($object->total_ttc); + unset($object->total_tva); + unset($object->lines); + unset($object->fk_incoterms); + unset($object->libelle_incoterms); + unset($object->location_incoterms); + unset($object->civility_id); + unset($object->name); + unset($object->lastname); + unset($object->firstname); + unset($object->shipping_method_id); + unset($object->fk_delivery_address); + unset($object->cond_reglement); + unset($object->cond_reglement_id); + unset($object->mode_reglement_id); + unset($object->barcode_type_coder); + unset($object->barcode_type_label); + unset($object->barcode_type_code); + unset($object->barcode_type); + unset($object->canvas); + unset($object->cats); + unset($object->motherof); + unset($object->context); + unset($object->socid); + unset($object->thirdparty); + unset($object->contact); + unset($object->contact_id); + unset($object->user); + unset($object->fk_account); + unset($object->fk_project); + unset($object->note); + unset($object->statut); + return $object; } diff --git a/htdocs/categories/class/api_deprecated_category.class.php b/htdocs/categories/class/api_deprecated_category.class.php index 6f2f16bb222..271f2900502 100644 --- a/htdocs/categories/class/api_deprecated_category.class.php +++ b/htdocs/categories/class/api_deprecated_category.class.php @@ -291,7 +291,7 @@ class CategoryApi extends DolibarrApi * @url GET /customer/{cusid}/categories */ function getListCustomerCategories($cusid, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) { - return $this->getListForItem('customer', $sortfield, $sortorder, $limit, $page, $cusid); + return $this->getListForItem($sortfield, $sortorder, $limit, $page, 'customer', $cusid); } /** diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 90bc9d7296f..38b65ddfb4b 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -264,7 +264,7 @@ class Products extends DolibarrApi */ function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) { $categories = new Categories(); - return $categories->getListForItem('product', $sortfield, $sortorder, $limit, $page, $id); + return $categories->getListForItem($sortfield, $sortorder, $limit, $page, 'product', $id); } /** diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index d758d9ac3f4..de50799e430 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -318,7 +318,7 @@ class Contacts extends DolibarrApi */ function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) { $categories = new Categories(); - return $categories->getListForItem('contact', $sortfield, $sortorder, $limit, $page, $id); + return $categories->getListForItem($sortfield, $sortorder, $limit, $page, 'contact', $id); } /** diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index cedd30c5209..f8e96d82e47 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -267,7 +267,7 @@ class Thirdparties extends DolibarrApi */ function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) { $categories = new Categories(); - return $categories->getListForItem('customer', $sortfield, $sortorder, $limit, $page, $id); + return $categories->getListForItem($sortfield, $sortorder, $limit, $page, 'customer', $id); } /** From 9e944e45251a7d9c4bbe820c27fde6c165b83516 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 17 Mar 2017 12:41:56 +0100 Subject: [PATCH 120/410] Fix: wrong user fetch when same login in different entity --- htdocs/main.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 40d1326c45e..1a832990f38 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -576,9 +576,10 @@ if (! defined('NOLOGIN')) { // We are already into an authenticated session $login=$_SESSION["dol_login"]; - dol_syslog("This is an already logged session. _SESSION['dol_login']=".$login, LOG_DEBUG); + $entity=$_SESSION["dol_entity"]; + dol_syslog("This is an already logged session. _SESSION['dol_login']=".$login." _SESSION['dol_entity']=".$entity, LOG_DEBUG); - $resultFetchUser=$user->fetch('',$login); + $resultFetchUser=$user->fetch('',$login,'',1,($entity > 0 ? $entity : -1)); if ($resultFetchUser <= 0) { // Account has been removed after login From f255b94e9956899a682429a2aef5200d9669a386 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Fri, 17 Mar 2017 16:10:40 +0100 Subject: [PATCH 121/410] Fix #6537 Bug: SQL error: Missing , leads to wrong syntax --- htdocs/expedition/card.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index e4709facd9b..fd7c3e2633c 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2016 Laurent Destailleur * Copyright (C) 2005 Simon TOSSER * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2011-2012 Juanjo Menent + * Copyright (C) 2011-2017 Juanjo Menent * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Marcos García * Copyright (C) 2014 Cedric GROSS @@ -1744,10 +1744,10 @@ else if ($id || $ref) { $sql = "SELECT obj.rowid, obj.fk_product, obj.label, obj.description, obj.product_type as fk_product_type, obj.qty as qty_asked, obj.date_start, obj.date_end"; $sql.= ", ed.rowid as shipmentline_id, ed.qty as qty_shipped, ed.fk_expedition as expedition_id, ed.fk_origin_line, ed.fk_entrepot"; - $sql.= ", e.rowid as shipment_id, e.ref as shipment_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_expedition,"; - //if ($conf->livraison_bon->enabled) $sql .= " l.rowid as livraison_id, l.ref as livraison_ref, l.date_delivery, ld.qty as qty_received,"; - $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch'; - $sql.= ' p.description as product_desc'; + $sql.= ", e.rowid as shipment_id, e.ref as shipment_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_expedition"; + //if ($conf->livraison_bon->enabled) $sql .= ", l.rowid as livraison_id, l.ref as livraison_ref, l.date_delivery, ld.qty as qty_received"; + $sql.= ', p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch'; + $sql.= ', p.description as product_desc'; $sql.= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed"; $sql.= ", ".MAIN_DB_PREFIX."expedition as e"; $sql.= ", ".MAIN_DB_PREFIX.$origin."det as obj"; From 5c028b30d590bdcf4c558d2729d8715512ef9af7 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Fri, 17 Mar 2017 17:05:59 +0100 Subject: [PATCH 122/410] Fix #6512 Bug: Invalid argument in when submitting orderstoinvoice.php-form --- htdocs/commande/orderstoinvoice.php | 4 ++-- htdocs/fourn/commande/orderstoinvoice.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/commande/orderstoinvoice.php b/htdocs/commande/orderstoinvoice.php index d7c5682e0a9..009326f1f41 100644 --- a/htdocs/commande/orderstoinvoice.php +++ b/htdocs/commande/orderstoinvoice.php @@ -5,7 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Andreu Bisquerra Gaya * Copyright (C) 2012 David Rodriguez Martinez - * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2012-2017 Juanjo Menent * Copyright (C) 2015 Ferran Marcet * * This program is free software; you can redistribute it and/or modify @@ -122,7 +122,7 @@ if (($action == 'create' || $action == 'add') && !$error) } if (isset($_POST['orders_to_invoice'])) { - $orders_id = GETPOST('orders_to_invoice','',1); + $orders_id = GETPOST('orders_to_invoice','',2); $nn = count($orders_id); $ii = 0; diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index 1f87cdf5929..f804a1d9ab7 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -5,7 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Andreu Bisquerra Gaya * Copyright (C) 2012 David Rodriguez Martinez - * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2012-2017 Juanjo Menent * Copyright (C) 2014 Florian Henry * Copyright (C) 2015 Marcos García * @@ -116,7 +116,7 @@ if (($action == 'create' || $action == 'add') && ! $error) { $_GET['originid'] = $orders_id[0]; } if (isset($_POST['orders_to_invoice'])) { - $orders_id = GETPOST('orders_to_invoice','',1); + $orders_id = GETPOST('orders_to_invoice','',2); $nn = count($orders_id); $ii = 0; From 8c65c47b1f9185342406c10d88310cdddb9e0b76 Mon Sep 17 00:00:00 2001 From: De Coninck Laurent Date: Fri, 17 Mar 2017 17:55:25 +0100 Subject: [PATCH 123/410] fix the from e-mail on mass action In mass action e-mail (like on facture), the from e-mail was not taken into account. --- htdocs/core/actions_massactions.inc.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 3acb974deae..95c0c59a9cd 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -209,7 +209,26 @@ if (! $error && $massaction == 'confirm_presend') if (count($listofqualifiedinvoice) > 0) { $langs->load("commercial"); - $from = $user->getFullName($langs) . ' <' . $user->email .'>'; + + $fromtype = GETPOST('fromtype'); + if ($fromtype === 'user') { + $from = $user->getFullName($langs) .' <'.$user->email.'>'; + } + elseif ($fromtype === 'company') { + $from = $conf->global->MAIN_INFO_SOCIETE_NOM .' <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>'; + } + elseif (preg_match('/user_aliases_(\d+)/', $fromtype, $reg)) { + $tmp=explode(',', $user->email_aliases); + $from = trim($tmp[($reg[1] - 1)]); + } + elseif (preg_match('/global_aliases_(\d+)/', $fromtype, $reg)) { + $tmp=explode(',', $conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES); + $from = trim($tmp[($reg[1] - 1)]); + } + else { + $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; + } + $replyto = $from; $subject = GETPOST('subject'); $message = GETPOST('message'); From 16b12b33fc1b1e9bf4889e3bd0dd58a79c1f842a Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sat, 18 Mar 2017 07:24:55 +0100 Subject: [PATCH 124/410] First step : remove BANK_DISABLE_DIRECT_INPUT --- htdocs/accountancy/admin/index.php | 27 ------- htdocs/compta/bank/bankentries.php | 71 +++---------------- htdocs/core/modules/modAccounting.class.php | 10 +-- .../install/mysql/migration/5.0.0-6.0.0.sql | 2 + 4 files changed, 13 insertions(+), 97 deletions(-) diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 74479a9d39f..b92da48353f 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -141,19 +141,6 @@ if ($action == 'setmanagezero') { } } -if ($action == 'setdisabledirectinput') { - $setdisabledirectinput = GETPOST('value', 'int'); - $res = dolibarr_set_const($db, "BANK_DISABLE_DIRECT_INPUT", $setdisabledirectinput, 'yesno', 0, '', $conf->entity); - if (! $res > 0) - $error ++; - if (! $error) { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } else { - setEventMessages($langs->trans("Error"), null, 'mesgs'); - } -} - - /* * View */ @@ -243,20 +230,6 @@ if (! empty($user->admin)) } print '
    ' . $langs->trans("BANK_DISABLE_DIRECT_INPUT") . ''; - print img_picto($langs->trans("Activated"), 'switch_on'); - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - print '
    ' . $langs->trans("ACCOUNTING_MANAGE_ZERO") . '
    '; } - // Form to add a transaction with no invoice - if ($user->rights->banque->modifier && $action == 'addline') - { - print load_fiche_titre($langs->trans("AddBankRecordLong"),'',''); - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print '
    '.$langs->trans("Date").' '.$langs->trans("Type").''.$langs->trans("Numero").''.$langs->trans("Description").''.$langs->trans("Debit").''.$langs->trans("Credit").' 
    '; - $form->select_date(empty($dateop)?-1:$dateop,'op',0,0,0,'transaction'); - print ''; - $form->select_types_paiements((GETPOST('operation')?GETPOST('operation'):($object->courant == Account::TYPE_CASH ? 'LIQ' : '')),'operation','1,2',2,1); - print ''; - print ''; - print ''; - if ($options) { - print '
    '.$langs->trans("Rubrique").': '; - print Form::selectarray('cat1', $options, GETPOST('cat1'), 1); - } - print '
    '; - print '
    '; - print ''; - print '
    '; - print '
    '; - } - - /// ajax to adjust value date with plus and less picto print ' -

    trans("ShowInvoice"); ?>

    +

    trans("ShowInvoice"); ?>


    trans("PrintTicket"); ?>

    diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index b7cd28c446a..aa6c2729745 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -1094,7 +1094,7 @@ if ($id > 0) else print ''; } - if ($object->client != 0) print ''; + if ($object->client != 0) print ''; else print ''; } diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 99e4a6c0871..d5a492bf7d6 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -2383,7 +2383,7 @@ if ($action == 'create') { if (! empty($conf->facture->enabled) && $user->rights->facture->creer) { - print ''; + print ''; } $arrayofinvoiceforpropal = $object->getInvoiceArrayList(); diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 9e781139723..8c35c6c9e1f 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -564,7 +564,7 @@ if ($socid > 0) print $obj->description; print ''; } - print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''; + print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''; print ''.price($obj->amount_ht).''; print ''.price2num($obj->tva_tx,'MU').'%'; print ''.price($obj->amount_ttc).''; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 5d68619d2f9..7db6c28e89d 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2009,7 +2009,7 @@ if ($action == 'create' && $user->rights->commande->creer) $addrelativediscount = '' . $langs->trans("EditRelativeDiscounts") . ''; $addabsolutediscount = '' . $langs->trans("EditGlobalDiscounts") . ''; - $addcreditnote = '' . $langs->trans("AddCreditNote") . ''; + $addcreditnote = '' . $langs->trans("AddCreditNote") . ''; print '' . $langs->trans('Discounts') . ''; if ($soc->remise_percent) @@ -2541,7 +2541,7 @@ if ($action == 'create' && $user->rights->commande->creer) // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed" if ($object->statut > Commande::STATUS_DRAFT && ! $object->billed) { if (! empty($conf->facture->enabled) && $user->rights->facture->creer && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { - print ''; + print ''; } if ($user->rights->commande->creer && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { print ''; diff --git a/htdocs/commande/orderstoinvoice.php b/htdocs/commande/orderstoinvoice.php index 009326f1f41..17c73c82698 100644 --- a/htdocs/commande/orderstoinvoice.php +++ b/htdocs/commande/orderstoinvoice.php @@ -350,7 +350,7 @@ if (($action == 'create' || $action == 'add') && !$error) if ($id > 0 && ! $error) { $db->commit(); - header('Location: '.DOL_URL_ROOT.'/compta/facture.php?facid='.$id); + header('Location: '.DOL_URL_ROOT.'/compta/facture/card.php?facid='.$id); exit; } else diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 609a3f47bd1..8c1f2af7b1f 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -311,13 +311,9 @@ if ($result) print ''; } else if ($links[$key]['type']=='company') { - print ''; - //print img_object($langs->trans('ShowCompany'),'company').' '; $societe=new Societe($db); $societe->fetch($links[$key]['url_id']); - //print $links[$key]['label']; print $societe->getNomUrl(1); - print ''; } else if ($links[$key]['type']=='sc') { print ''; diff --git a/htdocs/compta/facture/apercu.php b/htdocs/compta/facture/apercu.php index 258b2434f60..b22571ad93f 100644 --- a/htdocs/compta/facture/apercu.php +++ b/htdocs/compta/facture/apercu.php @@ -151,7 +151,7 @@ if ($id > 0 || ! empty($ref)) // Relative and absolute discounts $addabsolutediscount=' '.$langs->trans("AddGlobalDiscount").''; - $addcreditnote=' '.$langs->trans("AddCreditNote").''; + $addcreditnote=' '.$langs->trans("AddCreditNote").''; print ''.$langs->trans('Discounts').''; print ''; diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture/card.php similarity index 99% rename from htdocs/compta/facture.php rename to htdocs/compta/facture/card.php index fad36115a26..4cbad38902f 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture/card.php @@ -30,12 +30,12 @@ */ /** - * \file htdocs/compta/facture.php + * \file htdocs/compta/facture/card.php * \ingroup facture * \brief Page to create/see an invoice */ -require '../main.inc.php'; +require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture-rec.class.php'; require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; @@ -2828,7 +2828,7 @@ else if ($id > 0 || ! empty($ref)) $head = facture_prepare_head($object); - dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); + dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), -1, 'bill'); $formconfirm = ''; @@ -3159,7 +3159,7 @@ else if ($id > 0 || ! empty($ref)) // Relative and absolute discounts $addrelativediscount = '' . $langs->trans("EditRelativeDiscounts") . ''; $addabsolutediscount = '' . $langs->trans("EditGlobalDiscounts") . ''; - $addcreditnote = '' . $langs->trans("AddCreditNote") . ''; + $addcreditnote = '' . $langs->trans("AddCreditNote") . ''; print '' . $langs->trans('Discounts'); print ''; @@ -3466,7 +3466,7 @@ else if ($id > 0 || ! empty($ref)) print '
    '; print $langs->trans('IncotermLabel'); print ''; - if ($user->rights->facture->creer) print ''.img_edit().''; + if ($user->rights->facture->creer) print ''.img_edit().''; else print ' '; print '
    '; print ''; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 305b8a7e1c0..721713fc279 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1048,7 +1048,7 @@ class Facture extends CommonInvoice $result=''; if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; - else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id; + else $url = DOL_URL_ROOT.'/compta/facture/card.php?facid='.$this->id; if ($short) return $url; diff --git a/htdocs/compta/facture/document.php b/htdocs/compta/facture/document.php index d6424309f87..45c6102ce1c 100644 --- a/htdocs/compta/facture/document.php +++ b/htdocs/compta/facture/document.php @@ -97,7 +97,7 @@ if ($id > 0 || ! empty($ref)) $upload_dir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($object->ref); $head = facture_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans('InvoiceCustomer'), 0, 'bill'); + dol_fiche_head($head, 'documents', $langs->trans('InvoiceCustomer'), -1, 'bill'); $totalpaye = $object->getSommePaiement(); diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index c858a2cda1f..9d4329a671b 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -1495,7 +1495,7 @@ else { if (empty($object->frequency) || $object->date_when <= $today) { - print ''; + print ''; } else { @@ -1786,7 +1786,7 @@ else { if (empty($objp->frequency) || $db->jdate($objp->date_when) <= $today) { - print ''; + print ''; print $langs->trans("CreateBill").''; } else diff --git a/htdocs/compta/facture/info.php b/htdocs/compta/facture/info.php index d52e7648418..56f89a83154 100644 --- a/htdocs/compta/facture/info.php +++ b/htdocs/compta/facture/info.php @@ -50,7 +50,7 @@ $object->fetch_thirdparty(); $object->info($object->id); $head = facture_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("InvoiceCustomer"), 0, 'bill'); +dol_fiche_head($head, 'info', $langs->trans("InvoiceCustomer"), -1, 'bill'); $totalpaye = $object->getSommePaiement(); diff --git a/htdocs/compta/facture/note.php b/htdocs/compta/facture/note.php index 9b939cf7c32..223480e4ba8 100644 --- a/htdocs/compta/facture/note.php +++ b/htdocs/compta/facture/note.php @@ -77,7 +77,7 @@ if ($id > 0 || ! empty($ref)) $totalpaye = $object->getSommePaiement(); - dol_fiche_head($head, 'note', $langs->trans("InvoiceCustomer"), 0, 'bill'); + dol_fiche_head($head, 'note', $langs->trans("InvoiceCustomer"), -1, 'bill'); // Invoice content diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index e81d0e38345..6a3e0e1a433 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -292,7 +292,7 @@ if (empty($reshook)) else $invoiceid=$facid; } } - if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid; + if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture/card.php?facid='.$invoiceid; else $loc = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$paiement_id; header('Location: '.$loc); exit; @@ -861,7 +861,7 @@ if (! GETPOST('action')) $objp = $db->fetch_object($resql); $var=!$var; print ''; - print ''.$objp->facnumber."\n"; + print ''.$objp->facnumber."\n"; print ''.dol_print_date($db->jdate($objp->dp))."\n"; print ''.$objp->paiement_type.' '.$objp->num_paiement."\n"; print ''.price($objp->amount).' '; diff --git a/htdocs/compta/prelevement/ligne.php b/htdocs/compta/prelevement/ligne.php index d43ba27ef26..64ddb12a7bc 100644 --- a/htdocs/compta/prelevement/ligne.php +++ b/htdocs/compta/prelevement/ligne.php @@ -309,11 +309,11 @@ if ($id) print ""; - print ''; + print ''; print img_object($langs->trans("ShowBill"),"bill"); print ' '; - print ''.$obj->ref."\n"; + print ''.$obj->ref."\n"; print ''; print img_object($langs->trans("ShowCompany"),"company"). ' '.$obj->name."\n"; diff --git a/htdocs/compta/prelevement/list.php b/htdocs/compta/prelevement/list.php index 7a7eeb7610a..d5ae2514034 100644 --- a/htdocs/compta/prelevement/list.php +++ b/htdocs/compta/prelevement/list.php @@ -183,9 +183,9 @@ if ($result) print ''.$obj->ref."\n"; - print ''; + print ''; print img_object($langs->trans("ShowBill"),"bill"); - print ' '.$obj->facnumber."\n"; + print ' '.$obj->facnumber."\n"; print ''; print ''.$obj->name."\n"; diff --git a/htdocs/compta/tva/quadri.php b/htdocs/compta/tva/quadri.php index 73cc0bc96ba..57ce32b72fe 100644 --- a/htdocs/compta/tva/quadri.php +++ b/htdocs/compta/tva/quadri.php @@ -237,7 +237,7 @@ if ($conf->global->ACCOUNTING_MODE == "CREANCES-DETTES") $x_both[$my_coll_rate]['paye']['vat'] = 0; $x_both[$my_coll_rate]['coll']['links'] = ''; foreach($x_coll[$my_coll_rate]['facid'] as $id=>$dummy){ - $x_both[$my_coll_rate]['coll']['links'] .= '..'.substr($x_coll[$my_coll_rate]['facnum'][$id],-2).' '; + $x_both[$my_coll_rate]['coll']['links'] .= '..'.substr($x_coll[$my_coll_rate]['facnum'][$id],-2).' '; } } foreach(array_keys($x_paye) as $my_paye_rate){ diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index f95a60ab130..400548b7076 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -2037,7 +2037,7 @@ else if (! empty($conf->facture->enabled) && $object->statut > 0 && $object->nbofservicesclosed < $nbofservices) { $langs->load("bills"); - if ($user->rights->facture->creer) print ''; + if ($user->rights->facture->creer) print ''; else print ''; } diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 387c662baad..41c5d67688c 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -483,7 +483,7 @@ class DiscountAbsolute if ($option == 'invoice') { $label=$langs->trans("ShowDiscount").': '.$this->ref_facture_source; - $link = ''; + $link = ''; $linkend=''; $ref=$this->ref_facture_source; $picto='bill'; diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 17e3b00b602..fd3b1e7187d 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -368,13 +368,13 @@ class Notify switch ($notifcode) { case 'BILL_VALIDATE': - $link='/compta/facture.php?facid='.$object->id; + $link='/compta/facture/card.php?facid='.$object->id; $dir_output = $conf->facture->dir_output; $object_type = 'facture'; $mesg = $langs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref); break; case 'BILL_PAYED': - $link='/compta/facture.php?facid='.$object->id; + $link='/compta/facture/card.php?facid='.$object->id; $dir_output = $conf->facture->dir_output; $object_type = 'facture'; $mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref); @@ -544,13 +544,13 @@ class Notify switch ($notifcode) { case 'BILL_VALIDATE': - $link='/compta/facture.php?facid='.$object->id; + $link='/compta/facture/card.php?facid='.$object->id; $dir_output = $conf->facture->dir_output; $object_type = 'facture'; $mesg = $langs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref); break; case 'BILL_PAYED': - $link='/compta/facture.php?facid='.$object->id; + $link='/compta/facture/card.php?facid='.$object->id; $dir_output = $conf->facture->dir_output; $object_type = 'facture'; $mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref); diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index caa469daa65..bfb893d92ee 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -43,7 +43,7 @@ function societe_prepare_head(Societe $object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/societe/soc.php?socid='.$object->id; + $head[$h][0] = DOL_URL_ROOT.'/societe/card.php?socid='.$object->id; $head[$h][1] = $langs->trans("Card"); $head[$h][2] = 'card'; $h++; @@ -259,7 +259,7 @@ function societe_prepare_head2($object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/societe/soc.php?socid='.$object->id; + $head[$h][0] = DOL_URL_ROOT.'/societe/card.php?socid='.$object->id; $head[$h][1] = $langs->trans("Card"); $head[$h][2] = 'company'; $h++; @@ -1470,7 +1470,7 @@ function show_subsidiaries($conf,$langs,$db,$object) print ''.$obj->code_client.''; print ''; - print ''; + print ''; print img_edit(); print ''; diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index f48a248ab14..fa8151563b1 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -38,7 +38,7 @@ function facture_prepare_head($object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/compta/facture.php?facid='.$object->id; + $head[$h][0] = DOL_URL_ROOT.'/compta/facture/card.php?facid='.$object->id; $head[$h][1] = $langs->trans('Card'); $head[$h][2] = 'compta'; $h++; diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 8ac601b4e27..54cddfcaa96 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -68,14 +68,14 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 404__+MAX_llx_menu__, 'home', '', 403__+MAX_llx_menu__, '/user/group/card.php?leftmenu=users&action=create', 'NewGroup', 2, 'users', '($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->write:$user->rights->user->user->creer) || $user->admin', '', 2, 0, __ENTITY__); -- Third parties insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 500__+MAX_llx_menu__, 'companies', 'thirdparties', 2__+MAX_llx_menu__, '/societe/index.php?leftmenu=thirdparties', 'ThirdParty', 0, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 501__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/soc.php?action=create', 'MenuNewThirdParty', 1, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 501__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/card.php?action=create', 'MenuNewThirdParty', 1, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 502__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/list.php?action=create', 'List', 1, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 503__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/list.php?type=f&leftmenu=suppliers', 'ListSuppliersShort', 1, 'suppliers', '$user->rights->societe->lire && $user->rights->fournisseur->lire', '', 2, 5, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 504__+MAX_llx_menu__, 'companies', '', 503__+MAX_llx_menu__, '/societe/soc.php?leftmenu=supplier&action=create&type=f', 'NewSupplier', 2, 'suppliers', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 504__+MAX_llx_menu__, 'companies', '', 503__+MAX_llx_menu__, '/societe/card.php?leftmenu=supplier&action=create&type=f', 'NewSupplier', 2, 'suppliers', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 506__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/list.php?type=p&leftmenu=prospects', 'ListProspectsShort', 1, 'companies', '$user->rights->societe->lire', '', 2, 3, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 507__+MAX_llx_menu__, 'companies', '', 506__+MAX_llx_menu__, '/societe/soc.php?leftmenu=prospects&action=create&type=p', 'MenuNewProspect', 2, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 507__+MAX_llx_menu__, 'companies', '', 506__+MAX_llx_menu__, '/societe/card.php?leftmenu=prospects&action=create&type=p', 'MenuNewProspect', 2, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 509__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/list.php?type=c&leftmenu=customers', 'ListCustomersShort', 1, 'companies', '$user->rights->societe->lire', '', 2, 4, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 510__+MAX_llx_menu__, 'companies', '', 509__+MAX_llx_menu__, '/societe/soc.php?leftmenu=customers&action=create&type=c', 'MenuNewCustomer', 2, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 510__+MAX_llx_menu__, 'companies', '', 509__+MAX_llx_menu__, '/societe/card.php?leftmenu=customers&action=create&type=c', 'MenuNewCustomer', 2, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); -- Third parties - Contacts insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 600__+MAX_llx_menu__, 'companies', 'contacts', 2__+MAX_llx_menu__, '/contact/list.php?leftmenu=contacts', 'ContactsAddresses', 0, 'companies', '$user->rights->societe->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 601__+MAX_llx_menu__, 'companies', '', 600__+MAX_llx_menu__, '/contact/card.php?leftmenu=contacts&action=create', 'NewContactAddress', 1, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); @@ -171,7 +171,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1604__+MAX_llx_menu__, 'accountancy', '', 1600__+MAX_llx_menu__, '/compta/facture/stats/index.php?leftmenu=customers_bills&mode=supplier', 'Statistics', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 8, __ENTITY__); -- Accountancy - Customer invoice insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1700__+MAX_llx_menu__, 'accountancy', 'customer_bills', 6__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills', 'BillsCustomers', 0, 'bills', '$user->rights->facture->lire', '', 2, 3, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1701__+MAX_llx_menu__, 'accountancy', '', 1700__+MAX_llx_menu__, '/compta/facture.php?action=create&leftmenu=customers_bills', 'NewBill', 1, 'bills', '$user->rights->facture->creer', '', 2, 3, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1701__+MAX_llx_menu__, 'accountancy', '', 1700__+MAX_llx_menu__, '/compta/facture/card.php?action=create&leftmenu=customers_bills', 'NewBill', 1, 'bills', '$user->rights->facture->creer', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1705__+MAX_llx_menu__, 'accountancy', '', 1700__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills', 'List', 1, 'bills', '$user->rights->facture->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1702__+MAX_llx_menu__, 'accountancy', '', 1700__+MAX_llx_menu__, '/compta/facture/fiche-rec.php?leftmenu=customers_bills', 'ListOfTemplates', 1, 'bills', '$user->rights->facture->lire', '', 2, 5, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index c7ac721a3d4..178f1ca9db7 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -611,8 +611,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($user->rights->societe->creer) { - $newmenu->add("/societe/soc.php?action=create", $langs->trans("MenuNewThirdParty"),1); - if (! $conf->use_javascript_ajax) $newmenu->add("/societe/soc.php?action=create&private=1",$langs->trans("MenuNewPrivateIndividual"),1); + $newmenu->add("/societe/card.php?action=create", $langs->trans("MenuNewThirdParty"),1); + if (! $conf->use_javascript_ajax) $newmenu->add("/societe/card.php?action=create&private=1",$langs->trans("MenuNewPrivateIndividual"),1); } } @@ -630,7 +630,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=2", $langs->trans("LastProspectContactInProcess"), 2, $user->rights->societe->lire); if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=3", $langs->trans("LastProspectContactDone"), 2, $user->rights->societe->lire); */ - $newmenu->add("/societe/soc.php?leftmenu=prospects&action=create&type=p", $langs->trans("MenuNewProspect"), 2, $user->rights->societe->creer); + $newmenu->add("/societe/card.php?leftmenu=prospects&action=create&type=p", $langs->trans("MenuNewProspect"), 2, $user->rights->societe->creer); //$newmenu->add("/contact/list.php?leftmenu=customers&type=p", $langs->trans("Contacts"), 2, $user->rights->societe->contact->lire); } @@ -640,7 +640,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $langs->load("commercial"); $newmenu->add("/societe/list.php?type=c&leftmenu=customers", $langs->trans("ListCustomersShort"), 1, $user->rights->societe->lire, '', $mainmenu, 'customers'); - $newmenu->add("/societe/soc.php?leftmenu=customers&action=create&type=c", $langs->trans("MenuNewCustomer"), 2, $user->rights->societe->creer); + $newmenu->add("/societe/card.php?leftmenu=customers&action=create&type=c", $langs->trans("MenuNewCustomer"), 2, $user->rights->societe->creer); //$newmenu->add("/contact/list.php?leftmenu=customers&type=c", $langs->trans("Contacts"), 2, $user->rights->societe->contact->lire); } @@ -649,7 +649,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu { $langs->load("suppliers"); $newmenu->add("/societe/list.php?type=f&leftmenu=suppliers", $langs->trans("ListSuppliersShort"), 1, $user->rights->fournisseur->lire, '', $mainmenu, 'suppliers'); - $newmenu->add("/societe/soc.php?leftmenu=suppliers&action=create&type=f",$langs->trans("MenuNewSupplier"), 2, $user->rights->societe->creer && $user->rights->fournisseur->lire); + $newmenu->add("/societe/card.php?leftmenu=suppliers&action=create&type=f",$langs->trans("MenuNewSupplier"), 2, $user->rights->societe->creer && $user->rights->fournisseur->lire); } // Contacts @@ -790,7 +790,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu { $langs->load("bills"); $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills",$langs->trans("BillsCustomers"),0,$user->rights->facture->lire); - $newmenu->add("/compta/facture.php?action=create",$langs->trans("NewBill"),1,$user->rights->facture->creer); + $newmenu->add("/compta/facture/card.php?action=create",$langs->trans("NewBill"),1,$user->rights->facture->creer); $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills",$langs->trans("List"),1,$user->rights->facture->lire); if ($usemenuhider || empty($leftmenu) || preg_match('/customers_bills/', $leftmenu)) diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php index 55cce13fbcf..148c21aa31d 100644 --- a/htdocs/core/modules/mailings/thirdparties.modules.php +++ b/htdocs/core/modules/mailings/thirdparties.modules.php @@ -241,7 +241,7 @@ class mailing_thirdparties extends MailingTargets */ function url($id) { - return ''.img_object('',"company").''; + return ''.img_object('',"company").''; } } diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php index de92354a964..21a37301e38 100644 --- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php +++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php @@ -234,7 +234,7 @@ class mailing_thirdparties_services_expired extends MailingTargets */ function url($id) { - return ''.img_object('',"company").''; + return ''.img_object('',"company").''; } } diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index fd7c3e2633c..e179142b19a 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2019,7 +2019,7 @@ else if ($id || $ref) { if ($user->rights->facture->creer) { - print ''.$langs->trans("CreateBill").''; + print ''.$langs->trans("CreateBill").''; } } diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 5e1b536cf40..31f72e18075 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1635,7 +1635,7 @@ else if ($id > 0 || ! empty($ref)) $langs->load("bills"); if ($object->statut < 2) { - if ($user->rights->facture->creer) print ''; + if ($user->rights->facture->creer) print ''; else print ''; } diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index 1048e41c18c..d93750ad4ee 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -756,7 +756,7 @@ if (empty($action)) // Thirdparty print ''; - if ($objp->socid) print ''.img_object($langs->trans('ShowCompany'),'company').' '.dol_trunc($objp->name,32).''; + if ($objp->socid) print ''.img_object($langs->trans('ShowCompany'),'company').' '.dol_trunc($objp->name,32).''; else print ' '; print ''; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 4df8b45041f..ac260fc99fb 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -804,7 +804,7 @@ if (empty($reshook)) ); if ($result > 0) { - header("Location: " . DOL_URL_ROOT . "/compta/facture.php?facid=" . $facture->id); + header("Location: " . DOL_URL_ROOT . "/compta/facture/card.php?facid=" . $facture->id); exit; } } diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 69a9344832b..ab74bc29485 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -394,7 +394,7 @@ if ($id > 0 || $ref) { if (empty($form->result)) { - print ' - '.$langs->trans("CreateDolibarrThirdPartySupplier").''; + print ' - '.$langs->trans("CreateDolibarrThirdPartySupplier").''; } } } diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 1b0ccb36ed0..9407fc716c1 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -528,7 +528,7 @@ if ($action == 'create' && $user->rights->projet->creer) print $form->textwithtooltip($text.' '.img_help(),$texthelp,1); } else print $text; - print ' '.$langs->trans("AddThirdParty").''; + print ' '.$langs->trans("AddThirdParty").''; print ''; } @@ -1088,7 +1088,7 @@ elseif ($object->id > 0) if (! empty($conf->facture->enabled) && $user->rights->facture->creer) { $langs->load("bills"); - print ''; + print ''; } if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->creer) { diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 89bab45896f..e10196b8784 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -263,7 +263,7 @@ $listofreferent=array( 'margin'=>'add', 'table'=>'facture', 'datefieldname'=>'datef', - 'urlnew'=>DOL_URL_ROOT.'/compta/facture.php?action=create&projectid='.$id.'&socid='.$socid, + 'urlnew'=>DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid, 'lang'=>'bills', 'buttonnew'=>'CreateBill', 'testnew'=>$user->rights->facture->creer, @@ -274,7 +274,7 @@ $listofreferent=array( 'class'=>'FactureRec', 'table'=>'facture_rec', 'datefieldname'=>'datec', - 'urlnew'=>DOL_URL_ROOT.'/compta/facture.php?action=create&projectid='.$id.'&socid='.$socid, + 'urlnew'=>DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid, 'lang'=>'bills', 'buttonnew'=>'CreateBill', 'testnew'=>$user->rights->facture->creer, diff --git a/htdocs/societe/soc.php b/htdocs/societe/card.php similarity index 99% rename from htdocs/societe/soc.php rename to htdocs/societe/card.php index 80aeb14a684..c9fb0de6edf 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/card.php @@ -26,7 +26,7 @@ */ /** - * \file htdocs/societe/soc.php + * \file htdocs/societe/card.php * \ingroup societe * \brief Third party card page */ @@ -2281,7 +2281,7 @@ else print '
    '; print $langs->trans('IncotermLabel'); print ''; - if ($user->rights->societe->creer) print ''.img_edit('',1).''; + if ($user->rights->societe->creer) print ''.img_edit('',1).''; else print ' '; print '
    '; print ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 5aac6fdec85..ed3fdad13c4 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1891,7 +1891,7 @@ class Societe extends CommonObject if (empty($linkstart)) { $label.= '' . $langs->trans("ShowCompany") . ''; - $linkstart = ''; print fieldLabel('Label','label',1).''; - print 'trans("VariousPayment")).'">'; + print ''; print ''; // Sens From d9abe553cfb0723aba098c5901326dce4082952e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 10:54:47 +0100 Subject: [PATCH 148/410] Useless bottom-border --- htdocs/admin/modules.php | 6 +++--- htdocs/supplier_proposal/card.php | 2 +- htdocs/supplier_proposal/document.php | 2 +- htdocs/supplier_proposal/info.php | 2 +- htdocs/supplier_proposal/note.php | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 107cffd8500..52b250e8cf0 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -440,7 +440,7 @@ if ($mode == 'common') print ''; print ''; - dol_fiche_head($head, $mode, ''); + dol_fiche_head($head, $mode, '', -1); $moreforfilter = ''; $moreforfilter.='
    '; @@ -773,7 +773,7 @@ if ($mode == 'common') if ($mode == 'marketplace') { - dol_fiche_head($head, $mode, ''); + dol_fiche_head($head, $mode, '', -1); // Marketplace print "\n"; @@ -809,7 +809,7 @@ if ($mode == 'marketplace') if ($mode == 'deploy') { - dol_fiche_head($head, $mode, ''); + dol_fiche_head($head, $mode, '', -1); $allowonlineinstall=true; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 8ec24860e14..d05d3490776 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1283,7 +1283,7 @@ if ($action == 'create') $soc->fetch($object->socid); $head = supplier_proposal_prepare_head($object); - dol_fiche_head($head, 'comm', $langs->trans('CommRequest'), 0, 'supplier_proposal'); + dol_fiche_head($head, 'comm', $langs->trans('CommRequest'), -1, 'supplier_proposal'); $formconfirm = ''; diff --git a/htdocs/supplier_proposal/document.php b/htdocs/supplier_proposal/document.php index 2f49951c844..1f21693246b 100644 --- a/htdocs/supplier_proposal/document.php +++ b/htdocs/supplier_proposal/document.php @@ -83,7 +83,7 @@ if ($object->id > 0) $upload_dir = $conf->supplier_proposal->dir_output.'/'.dol_sanitizeFileName($object->ref); $head = supplier_proposal_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans('CommRequest'), 0, 'supplier_proposal'); + dol_fiche_head($head, 'document', $langs->trans('CommRequest'), -1, 'supplier_proposal'); // Construit liste des fichiers $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); diff --git a/htdocs/supplier_proposal/info.php b/htdocs/supplier_proposal/info.php index de98ed5be65..718b79ce4ae 100644 --- a/htdocs/supplier_proposal/info.php +++ b/htdocs/supplier_proposal/info.php @@ -53,7 +53,7 @@ $object->info($object->id); $head = supplier_proposal_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans('CommRequest'), 0, 'supplier_proposal'); +dol_fiche_head($head, 'info', $langs->trans('CommRequest'), -1, 'supplier_proposal'); // Supplier proposal card $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/supplier_proposal/note.php b/htdocs/supplier_proposal/note.php index b764372848d..10a9668382c 100644 --- a/htdocs/supplier_proposal/note.php +++ b/htdocs/supplier_proposal/note.php @@ -76,7 +76,7 @@ if ($id > 0 || ! empty($ref)) if ( $societe->fetch($object->socid) ) { $head = supplier_proposal_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans('CommRequest'), 0, 'supplier_proposal'); + dol_fiche_head($head, 'note', $langs->trans('CommRequest'), -1, 'supplier_proposal'); // Supplier proposal card From 5231fbf1e3519c3cb1d7caf704b25b20a67a6a1f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 11:37:03 +0100 Subject: [PATCH 149/410] Option to hide version --- htdocs/main.inc.php | 60 +++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 5cb73be28e7..6b9d4f08531 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1390,7 +1390,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $logouttext=''; if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $logouthtmltext=$appli.'
    '; + //$logouthtmltext=$appli.'
    '; if ($_SESSION["dol_authmode"] != 'forceuser' && $_SESSION["dol_authmode"] != 'http') { $logouthtmltext.=$langs->trans("Logout").'
    '; @@ -1467,8 +1467,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a if ($helpbaseurl && $helppage) { $text=''; - $title=''; - //$text.='
    '; + $title=$appli.'
    '; $title.=$langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'); if ($mode == 'wiki') $title.=' - '.$langs->trans("PageWiki").' "'.dol_escape_htmltag(strtr($helppage,'_',' ')).'"'; $text.=''."\n"; // Version - $doliurl='http://www.dolibarr.org'; - //local communities - if (preg_match('/fr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.fr'; - if (preg_match('/es/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.es'; - if (preg_match('/de/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.de'; - if (preg_match('/it/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.it'; - if (preg_match('/gr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.gr'; - - $appli=constant('DOL_APPLICATION_TITLE'); - if (! empty($conf->global->MAIN_APPLICATION_TITLE)) - { - $appli=$conf->global->MAIN_APPLICATION_TITLE; $doliurl=''; - if (preg_match('/\d\.\d/', $appli)) - { - if (! preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli.=" (".DOL_VERSION.")"; // If new title contains a version that is different than core - } - else $appli.=" ".DOL_VERSION; - } - else $appli.=" ".DOL_VERSION; - print ''."\n"; + if (empty($conf->global->MAIN_HIDE_VERSION)) // Version is already on help picto and on login page. + { + $doliurl='https://www.dolibarr.org'; + //local communities + if (preg_match('/fr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.fr'; + if (preg_match('/es/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.es'; + if (preg_match('/de/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.de'; + if (preg_match('/it/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.it'; + if (preg_match('/gr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.gr'; + + $appli=constant('DOL_APPLICATION_TITLE'); + if (! empty($conf->global->MAIN_APPLICATION_TITLE)) + { + $appli=$conf->global->MAIN_APPLICATION_TITLE; $doliurl=''; + if (preg_match('/\d\.\d/', $appli)) + { + if (! preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli.=" (".DOL_VERSION.")"; // If new title contains a version that is different than core + } + else $appli.=" ".DOL_VERSION; + } + else $appli.=" ".DOL_VERSION; + print '
    '; + if ($doliurl) print ''; + else print ''; + print $appli; + if ($doliurl) print ''; + else print ''; + print '
    '."\n"; + } // Link to bugtrack if (! empty($conf->global->MAIN_BUGTRACK_ENABLELINK)) From 9abe0940e7ec3234302388956a63fae7e5e6bc35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 11:42:02 +0100 Subject: [PATCH 150/410] Fix bad use of showLinkedObjectBlock --- htdocs/user/card.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 4627d7c472a..839d09ee9c7 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -2360,13 +2360,9 @@ else $somethingshown = $formfile->show_documents('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - // Linked object block - $somethingshown = $form->showLinkedObjectBlock($object); - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object); - if ($linktoelem) print '
    '.$linktoelem; - + $linktoelem = $form->showLinkToObjectBlock($object, null, null); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); print '
    '; From 5b4bb560122450add46324a9233d9016a95455fb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 12:13:02 +0100 Subject: [PATCH 151/410] No more need of $bc[$var] --- htdocs/admin/ihm.php | 195 +++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 107 deletions(-) diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index eefa6a1fc24..95917a79ab5 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -157,8 +157,7 @@ if ($action == 'edit') // Edit print ''; clearstatcache(); - $var=true; - + print '
    '; print '
    '; print ''; @@ -166,16 +165,14 @@ if ($action == 'edit') // Edit print ''; // Default language - $var=!$var; - print ''; print ''; print ''; // Multilingual GUI - $var=!$var; - print ''; print ''; @@ -192,11 +189,9 @@ if ($action == 'edit') // Edit { print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("DefaultLanguage").''; + print '
    '.$langs->trans("DefaultLanguage").''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'main_lang_default', 1, 0, 0, 0, 0, 'minwidth300'); print ' 
    '.$langs->trans("EnableMultilangInterface").''; + print '
    '.$langs->trans("EnableMultilangInterface").''; print $form->selectyesno('main_multilangs',$conf->global->MAIN_MULTILANGS,1); print ' 
    '; print ''; - $var=True; foreach ($searchform as $key => $value) { - $var=!$var; - print ''; } @@ -210,29 +205,18 @@ if ($action == 'edit') // Edit print ''; print ''; - // Show logo - $var=!$var; - print ''; - print ''; - print ''; - // Max size of lists - $var=!$var; - print ''; + print ''; print ''; print ''; // Max size of short lists on customer card - $var=!$var; - print ''; + print ''; print ''; print ''; // Disable javascript and ajax - $var=!$var; - print ''; print ''; @@ -241,8 +225,7 @@ if ($action == 'edit') // Edit // Activate preview tab on element card if (class_exists("Imagick")) { - $var=!$var; - print ''; print ''; @@ -250,32 +233,28 @@ if ($action == 'edit') // Edit } // First day for weeks - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingDays - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingHours - $var=!$var; - print ''; print ''; print ''; // Firstname/Name - $var=!$var; - print ''; @@ -283,40 +262,52 @@ if ($action == 'edit') // Edit print ''; // Hide unauthorized button - $var=!$var; - print ''; print ''; print ''; - // Hide helpcenter link on login page - $var=!$var; - print ''; + // Show logo + print ''; print ''; print ''; - - // Hide wiki link on login page - $var=!$var; - print ''; + + // Hide version link + /* + + print ''; print ''; print ''; - + */ + // Show bugtrack link - $var=!$var; - print ''; print ''; print ''; - // Message on login page - $var=!$var; - print ''; + print ''; + print ''; + + // Hide helpcenter link on login page + print ''; + print ''; + print ''; + + // Message on login page + print ''."\n"; // Message of the day on home page - $var=!$var; - print ''; - print ''; - print ''; + print ''; - print ''; - print ''; + print ''; @@ -1485,7 +1485,7 @@ else } else { - dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), -1, 'trip'); // Clone confirmation if ($action == 'clone') { diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php index 470e2ec3346..eb622867f54 100644 --- a/htdocs/expensereport/document.php +++ b/htdocs/expensereport/document.php @@ -91,7 +91,7 @@ if ($object->id) $head=expensereport_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php index 21ee44df97a..0c3f687519c 100644 --- a/htdocs/expensereport/info.php +++ b/htdocs/expensereport/info.php @@ -39,6 +39,9 @@ $result = restrictedArea($user, 'expensereport', $id, 'expensereport'); /* * View */ + +$form = new Form($db); + $title=$langs->trans("ExpenseReport") . " - " . $langs->trans("Info"); $helpurl="EN:Module_Expense_Reports"; llxHeader("",$title,$helpurl); @@ -51,7 +54,7 @@ if ($id > 0 || ! empty($ref)) $head = expensereport_prepare_head($object); - dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; From e6637422d510caefbe4e8761557e698b9f64ce00 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:58:41 +0100 Subject: [PATCH 166/410] Fix with on smartphone --- htdocs/expensereport/info.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php index 21ee44df97a..0ea405e08c3 100644 --- a/htdocs/expensereport/info.php +++ b/htdocs/expensereport/info.php @@ -39,6 +39,9 @@ $result = restrictedArea($user, 'expensereport', $id, 'expensereport'); /* * View */ + +$form = new Form($db); + $title=$langs->trans("ExpenseReport") . " - " . $langs->trans("Info"); $helpurl="EN:Module_Expense_Reports"; llxHeader("",$title,$helpurl); From 9a13dc92ab4ed01916a3410d4bf96f6caae50f2a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:56:11 +0100 Subject: [PATCH 167/410] bottom-border useless --- htdocs/expensereport/card.php | 6 +++--- htdocs/expensereport/document.php | 2 +- htdocs/expensereport/info.php | 5 ++++- htdocs/expensereport/note.php | 17 +---------------- 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 4c28fe0281c..8ec9d9140cb 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1272,8 +1272,8 @@ if ($action == 'create') print ''; @@ -1485,7 +1485,7 @@ else } else { - dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), -1, 'trip'); // Clone confirmation if ($action == 'clone') { diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php index 470e2ec3346..eb622867f54 100644 --- a/htdocs/expensereport/document.php +++ b/htdocs/expensereport/document.php @@ -91,7 +91,7 @@ if ($object->id) $head=expensereport_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php index 21ee44df97a..0c3f687519c 100644 --- a/htdocs/expensereport/info.php +++ b/htdocs/expensereport/info.php @@ -39,6 +39,9 @@ $result = restrictedArea($user, 'expensereport', $id, 'expensereport'); /* * View */ + +$form = new Form($db); + $title=$langs->trans("ExpenseReport") . " - " . $langs->trans("Info"); $helpurl="EN:Module_Expense_Reports"; llxHeader("",$title,$helpurl); @@ -51,7 +54,7 @@ if ($id > 0 || ! empty($ref)) $head = expensereport_prepare_head($object); - dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/expensereport/note.php b/htdocs/expensereport/note.php index 636e54c654e..8c059b8b284 100644 --- a/htdocs/expensereport/note.php +++ b/htdocs/expensereport/note.php @@ -78,7 +78,7 @@ if ($id > 0 || ! empty($ref)) $head = expensereport_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'note', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; @@ -87,20 +87,6 @@ if ($id > 0 || ! empty($ref)) dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - - /* - print '
    '.$langs->trans("PermanentLeftSearchForm").''.$langs->trans("Activated").'
    '.$searchformtitle[$key].''; + print '
    '.$searchformtitle[$key].''; print $form->selectyesno($searchform[$key],$searchformconst[$key],1); print '
     
    '.$langs->trans("EnableShowLogo").''; - print $form->selectyesno('MAIN_SHOW_LOGO',$conf->global->MAIN_SHOW_LOGO,1); - print ' 
    '.$langs->trans("DefaultMaxSizeList").'
    '.$langs->trans("DefaultMaxSizeList").' 
    '.$langs->trans("DefaultMaxSizeShortList").'
    '.$langs->trans("DefaultMaxSizeShortList").' 
    '.$langs->trans("DisableJavascript").''; + print '
    '.$langs->trans("DisableJavascript").''; print $form->selectyesno('main_disable_javascript',isset($conf->global->MAIN_DISABLE_JAVASCRIPT)?$conf->global->MAIN_DISABLE_JAVASCRIPT:0,1); print ' 
    '.$langs->trans("UsePreviewTabs").''; + print '
    '.$langs->trans("UsePreviewTabs").''; print $form->selectyesno('MAIN_USE_PREVIEW_TABS',isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0,1); print ' 
    '.$langs->trans("WeekStartOnDay").''; + print '
    '.$langs->trans("WeekStartOnDay").''; print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1'),'MAIN_START_WEEK',0); print ' 
    '.$langs->trans("DefaultWorkingDays").''; + print '
    '.$langs->trans("DefaultWorkingDays").''; print ''; print ' 
    '.$langs->trans("DefaultWorkingHours").''; + print '
    '.$langs->trans("DefaultWorkingHours").''; print ''; print ' 
    '.$langs->trans("FirstnameNamePosition").''; + print '
    '.$langs->trans("FirstnameNamePosition").''; $array=array(0=>$langs->trans("Firstname").' '.$langs->trans("Lastname"),1=>$langs->trans("Lastname").' '.$langs->trans("Firstname")); print $form->selectarray('MAIN_FIRSTNAME_NAME_POSITION',$array,(isset($conf->global->MAIN_FIRSTNAME_NAME_POSITION)?$conf->global->MAIN_FIRSTNAME_NAME_POSITION:0)); print '
    '.$langs->trans("ButtonHideUnauthorized").''; + print '
    '.$langs->trans("ButtonHideUnauthorized").''; print $form->selectyesno('MAIN_BUTTON_HIDE_UNAUTHORIZED',isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0,1); print ' 
    '.$langs->trans("DisableLinkToHelpCenter").''; - print $form->selectyesno('MAIN_HELPCENTER_DISABLELINK',isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0,1); - print '
    '.$langs->trans("EnableShowLogo").''; + print $form->selectyesno('MAIN_SHOW_LOGO',$conf->global->MAIN_SHOW_LOGO,1); + print ' 
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; - print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0,1); - print '
    '.$langs->trans("HideVersionLink").''; + print $form->selectyesno('MAIN_HIDE_VERSION',$conf->global->MAIN_HIDE_VERSION,1); + print ' 
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; + print '
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; print $form->selectyesno('MAIN_BUGTRACK_ENABLELINK',$conf->global->MAIN_BUGTRACK_ENABLELINK,1); print ' 
    '.$langs->trans("MessageLogin").''; + // Hide wiki link on login page + print '
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0,1); + print ' 
    '.$langs->trans("DisableLinkToHelpCenter").''; + print $form->selectyesno('MAIN_HELPCENTER_DISABLELINK',isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0,1); + print ' 
    '.$langs->trans("MessageLogin").''; $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); @@ -324,8 +315,7 @@ if ($action == 'edit') // Edit print '
    '.$langs->trans("MessageOfDay").''; + print '
    '.$langs->trans("MessageOfDay").''; $doleditor = new DolEditor('main_motd', (isset($conf->global->MAIN_MOTD)?$conf->global->MAIN_MOTD:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); @@ -345,14 +335,11 @@ if ($action == 'edit') // Edit } else // Show { - $var=true; - // Language print ''; print ''; - $var=!$var; - print ''; print ""; - - $var=!$var; - print ''; + + print ''; print ''; print ""; @@ -380,11 +366,10 @@ else // Show { print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").' 
    '.$langs->trans("DefaultLanguage").''; + print '
    '.$langs->trans("DefaultLanguage").''; $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); print ($s?$s.' ':''); print ($conf->global->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); @@ -361,9 +348,8 @@ else // Show if ($user->admin && $conf->global->MAIN_LANG_DEFAULT!='auto') print info_admin($langs->trans("SubmitTranslation".($conf->global->MAIN_LANG_DEFAULT=='en_US'?'ENUS':''),$conf->global->MAIN_LANG_DEFAULT),1); print '
    '.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . '
    '.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . ' 
    '; print ''; - $var=true; foreach ($searchform as $key => $value) { - $var=!$var; - print ''; + + print ''; print ''; @@ -394,28 +379,20 @@ else // Show } // Other - $var=true; print '
    '.$langs->trans("PermanentLeftSearchForm").''.$langs->trans("Activated").' 
    '.$searchformtitle[$key].''.yn($searchformconst[$key]).'
    '.$searchformtitle[$key].''.yn($searchformconst[$key]).''; if (! empty($searchformmodule[$key])) print $langs->trans("IfModuleEnabled",$langs->transnoentitiesnoconv($searchformmodule[$key])); print '
    '; print ''; - $var=!$var; - print ''; - print ''; - print ""; - - $var=!$var; - print ''; + print ''; print ''; print ""; - $var=!$var; - print ''; + print ''; print ''; print ""; // Disable javascript/ajax - $var=!$var; - print '"; print ''; print ""; @@ -423,40 +400,36 @@ else // Show // Activate preview tab on element card if (class_exists("Imagick")) { - $var=!$var; - print '"; print ''; print ""; } // First day for weeks - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingDays - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingHours - $var=!$var; - print ''; print ''; print ''; // Firstname / Name position - $var=!$var; - print ''; @@ -464,40 +437,48 @@ else // Show print ''; // Hide unauthorized button - $var=!$var; - print ''; - // Link to help center - $var=!$var; - print ''; + // Show logo + print ''; + print ''; + print ""; - // Link to wiki help - $var=!$var; - print ''; - - // Show bugtrack link - $var=!$var; - print ''; + print ''; + print ''; + */ + + // Show bugtrack link + print '"; print ''; print ""; - // Message login - $var=!$var; - print ''; + + // Link to help center + print ''; + + // Message login + print ''."\n"; // Message of the day - $var=!$var; - print ''."\n"; From 0e997c973f05cff4d8bafcf363081d8274a34df0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:01:32 +0100 Subject: [PATCH 152/410] FIX Picto of project on dol_banner and box --- htdocs/core/boxes/box_project.php | 8 ++++---- htdocs/core/lib/functions.lib.php | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index c2cc1cb041b..b4a020cf500 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -78,7 +78,7 @@ class box_project extends ModeleBoxes // list the summary of the orders if ($user->rights->projet->lire) { - $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut "; + $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; if($user->socid) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=p.fk_soc"; $sql.= " WHERE p.entity = ".$conf->entity; @@ -98,7 +98,7 @@ class box_project extends ModeleBoxes $tooltip = $langs->trans('Project') . ': ' . $objp->ref; $this->info_box_contents[$i][0] = array( 'td' => 'align="left" width="16"', - 'logo' => 'object_project', + 'logo' => 'object_project'.($objp->public?'pub':''), 'tooltip' => $tooltip, 'url' => DOL_URL_ROOT."/projet/card.php?id=".$objp->rowid, ); @@ -124,12 +124,12 @@ class box_project extends ModeleBoxes $objTask = $db->fetch_object($resultTask); $this->info_box_contents[$i][3] = array( 'td' => 'class="right"', - 'text' => number_format($objTask->nb, 0, ',', ' ')." ".$langs->trans("Tasks"), + 'text' => $objTask->nb." ".$langs->trans("Tasks"), ); if ($objTask->nb > 0 ) $this->info_box_contents[$i][4] = array( 'td' => 'class="right"', - 'text' => number_format(($objTask->totprogress/$objTask->nb), 0, ',', ' ')."%", + 'text' => round($objTask->totprogress/$objTask->nb, 0)."%", ); else $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 3851a173c24..c987b9dd954 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1045,7 +1045,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r $morehtmlleft.=''; } } - elseif ($conf->browser->layout != 'phone') // Show no photo link + elseif ($conf->browser->layout != 'phone') // Show No photo link (picto of pbject) { $morehtmlleft.='
    '; if ($object->element == 'action') @@ -1057,7 +1057,9 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r else { $width=14; $cssclass='photorefcenter'; - $nophoto=img_picto('', 'object_'.$object->picto, '', false, 1); + $picto = $object->picto; + if ($object->element == 'project' && ! $object->public) $picto = 'project'; // instead of projectpub + $nophoto=img_picto('', 'object_'.$picto, '', false, 1); $morehtmlleft.='
    No photo
    '; } $morehtmlleft.='
    '; From aa71710a746794f42e71c0708b83461e51e03fc4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:38:00 +0100 Subject: [PATCH 153/410] FIX list of projects --- htdocs/core/boxes/box_project.php | 44 ++++++++++++++++++++++--------- htdocs/projet/list.php | 3 ++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index b4a020cf500..4277481499f 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -72,27 +72,40 @@ class box_project extends ModeleBoxes $totalnb = 0; $totalnbTask=0; - $textHead = $langs->trans("Projects"); + $textHead = $langs->trans("OpenedProjects"); $this->info_box_head = array('text' => $textHead, 'limit'=> dol_strlen($textHead)); // list the summary of the orders if ($user->rights->projet->lire) { - - $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; + + include_once(DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'); + $projectstatic = new Project($this->db); + + $socid=$user->societe_id; + + // Get list of project id allowed to user (in a string list separated by coma) + $projectsListId=''; + if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1,$socid); + + $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; if($user->socid) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=p.fk_soc"; - $sql.= " WHERE p.entity = ".$conf->entity; - if($user->socid) $sql.= " AND s.rowid = ".$user->socid; + $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; + if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users + if ($user->socid) $sql.= " AND s.rowid = ".$user->socid; $sql.= " AND p.fk_statut = 1"; // Seulement les projets ouverts - $sql.= " ORDER BY p.datec DESC"; - $sql.= $db->plimit($max, 0); + if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; + + $sql.= " ORDER BY p.datec DESC"; + //$sql.= $db->plimit($max, 0); $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); $i = 0; - while ($i < $num) { + while ($i < min($num, $max)) { $objp = $db->fetch_object($result); $tooltip = $langs->trans('Project') . ': ' . $objp->ref; @@ -117,8 +130,8 @@ class box_project extends ModeleBoxes $sql ="SELECT count(*) as nb, sum(progress) as totprogress"; $sql.=" FROM ".MAIN_DB_PREFIX."projet as p LEFT JOIN ".MAIN_DB_PREFIX."projet_task as pt on pt.fk_projet = p.rowid"; - $sql.=" WHERE p.entity = ".$conf->entity; - $sql.=" AND p.rowid = ".$objp->rowid; + $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; + $sql.=" AND p.rowid = ".$objp->rowid; $resultTask = $db->query($sql); if ($resultTask) { $objTask = $db->fetch_object($resultTask); @@ -135,12 +148,17 @@ class box_project extends ModeleBoxes $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); $totalnbTask += $objTask->nb; } else { - $this->info_box_contents[$i][3] = array('td' => 'class="right"', 'text' => number_format(0, 0, ',', ' ')); + $this->info_box_contents[$i][3] = array('td' => 'class="right"', 'text' => round(0)); $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); } $i++; } + if ($max < $num) + { + $this->info_box_contents[$i][0] = array('td' => 'colspan="5"', 'text' => '...'); + $i++; + } } } @@ -158,11 +176,11 @@ class box_project extends ModeleBoxes ); $this->info_box_contents[$i][2] = array( 'td' => 'align="right" ', - 'text' => number_format($num, 0, ',', ' ')." ".$langs->trans("Projects"), + 'text' => round($num, 0)." ".$langs->trans("Projects"), ); $this->info_box_contents[$i][3] = array( 'td' => 'align="right" ', - 'text' => number_format($totalnbTask, 0, ',', ' ')." ".$langs->trans("Tasks"), + 'text' => (($max < $num) ? '' : (round($totalnbTask, 0)." ".$langs->trans("Tasks"))), ); $this->info_box_contents[$i][4] = array( 'td' => '', diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index f45148c84c7..c7d213b19ce 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -197,6 +197,7 @@ $title=$langs->trans("Projects"); // Get list of project id allowed to user (in a string list separated by coma) +$projectsListId=''; if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1,$socid); // Get id of types of contacts for projects (This list never contains a lot of elements) @@ -246,7 +247,7 @@ if ($search_project_user > 0) $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser -if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; +if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$db->escape($search_categ); if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($search_ref) $sql .= natural_search('p.ref', $search_ref); From 95da2f5d545aa9083ea47ba3ebe5776eac142373 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:38:21 +0100 Subject: [PATCH 154/410] NEW Add font-awesome css. --- htdocs/main.inc.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 6b9d4f08531..45787d5054b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1080,7 +1080,13 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; } } - + + if (! defined('DISABLE_FONT_AWSOME')) + { + print ''."\n"; + print ''."\n"; + } + print ''."\n"; // Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php' //$themepath=dol_buildpath((empty($conf->global->MAIN_FORCETHEMEDIR)?'':$conf->global->MAIN_FORCETHEMEDIR).$conf->css,1); @@ -1100,7 +1106,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs } //print 'themepath='.$themepath.' themeparam='.$themeparam;exit; print ''."\n"; - if (! empty($conf->global->MAIN_FIX_FLASH_ON_CHROME)) print ''."\n".''."\n"; + if (! empty($conf->global->MAIN_FIX_FLASH_ON_CHROME)) print ''."\n".''."\n"; // CSS forced by modules (relative url starting with /) if (! empty($conf->modules_parts['css'])) From 68257283e444cab0e16d4559d8f083a5bb557102 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:39:42 +0100 Subject: [PATCH 155/410] Enhance select list --- htdocs/core/class/html.form.class.php | 41 ++++++++++------------ htdocs/core/class/html.formother.class.php | 3 +- htdocs/core/lib/ajax.lib.php | 2 +- htdocs/index.php | 5 ++- htdocs/projet/class/project.class.php | 4 +-- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 1366435f144..0ec07e1c3fa 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1070,11 +1070,10 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } // Construct $out and $outarray - $out.= ''."\n"; $textifempty=''; // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. @@ -1286,10 +1285,9 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - if ($htmlname != 'none' || $options_only) $out.= ''; if ($showempty == 1) $out.= ''; if ($showempty == 2) $out.= ''; $num = $this->db->num_rows($resql); @@ -1481,17 +1479,15 @@ class Form if ($num) { // Enhance with select2 - $nodatarole=''; if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined - $out.= ''; if ($show_empty) $out.= ''."\n"; if ($show_every) $out.= ''."\n"; @@ -1964,10 +1960,9 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - $out.=''; $textifempty=''; // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. @@ -4966,24 +4961,25 @@ class Form * Note: Do not apply langs->trans function on returned content, content may be entity encoded twice. * * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect - * @param array $array Array with key+value + * @param array $array Array (key => value) * @param string|string[] $id Preselected key or preselected keys for multiselect * @param int $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (value is '' or ' ' if 1), <0 to add an empty value with key that is this value. - * @param int $key_in_label 1 pour afficher la key dans la valeur "[key] value" + * @param int $key_in_label 1 to show key into label with format "[key] value" * @param int $value_as_key 1 to use value as key * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container - * @param int $translate Translate and encode value + * @param int $translate 1=Translate and encode value * @param int $maxlen Length maximum for labels * @param int $disabled Html select box is disabled * @param string $sort 'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order * @param string $morecss Add more class to css styles * @param int $addjscombo Add js combo - * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set. - * @param int $disablebademail Check if an email is found into value and if not disable and colorize entry. - * @return string HTML select string. + * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set + * @param int $disablebademail Check if an email is found into value and if not disable and colorize entry + * @param int $nohtmlescape No html escaping. + * @return string HTML select string * @see multiselectarray */ - static function selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='', $addjscombo=0, $moreparamonempty='',$disablebademail=0) + static function selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='', $addjscombo=0, $moreparamonempty='',$disablebademail=0, $nohtmlescape=0) { global $conf, $langs; @@ -5003,13 +4999,11 @@ class Form $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?(constant('REQUIRE_JQUERY_MULTISELECT')?constant('REQUIRE_JQUERY_MULTISELECT'):'select2'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; // Enhance with select2 - $nodatarole=''; if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } } @@ -5057,11 +5051,13 @@ class Form if ($key_in_label) { - $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value)); + if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value)); + else $selectOptionValue = $key.' - '.($maxlen?dol_trunc($value,$maxlen):$value); } else { - $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value); + if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value); + else $selectOptionValue = $maxlen?dol_trunc($value,$maxlen):$value; if ($value == '' || $value == '-') $selectOptionValue=' '; } //var_dump($selectOptionValue); @@ -5976,6 +5972,7 @@ class Form } else { + // Generic case to show photos $dir=$conf->$modulepart->dir_output; if (! empty($object->photo)) { @@ -6045,7 +6042,6 @@ class Form if ($object->photo) $ret.="
    \n"; $ret.='
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . ' 
    '.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '
    '.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . ' 
    '.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '
    '.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . ' 
    '.$langs->trans("DisableJavascript").''; + + print '
    '.$langs->trans("DisableJavascript").''; print yn($conf->global->MAIN_DISABLE_JAVASCRIPT)." 
    '.$langs->trans("UsePreviewTabs").''; + + print '
    '.$langs->trans("UsePreviewTabs").''; print yn(isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0)." 
    '.$langs->trans("WeekStartOnDay").''; + print '
    '.$langs->trans("WeekStartOnDay").''; print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); print ' 
    '.$langs->trans("DefaultWorkingDays").''; + print '
    '.$langs->trans("DefaultWorkingDays").''; print isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5'; print ' 
    '.$langs->trans("DefaultWorkingHours").''; + print '
    '.$langs->trans("DefaultWorkingHours").''; print isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18'; print ' 
    '.$langs->trans("FirstnameNamePosition").''; + print '
    '.$langs->trans("FirstnameNamePosition").''; if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print $langs->trans("Firstname").' '.$langs->trans("Lastname"); } else { print $langs->trans("Lastname").' '.$langs->trans("Firstname"); } print '
    '.$langs->trans("ButtonHideUnauthorized").''; + print '
    '.$langs->trans("ButtonHideUnauthorized").''; print yn((isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0),1); print '
    '.$langs->trans("DisableLinkToHelpCenter").''; - print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); - print '
    '.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . ' 
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; - print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); - print '
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; + // Hide version link + /* + print '
    '.$langs->trans("HideVersionLink").''; + print yn($conf->global->MAIN_HIDE_VERSION); + print ' 
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; print yn($conf->global->MAIN_BUGTRACK_ENABLELINK)." 
    '.$langs->trans("MessageLogin").''; + // Link to wiki help + print '
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); + print '
    '.$langs->trans("DisableLinkToHelpCenter").''; + print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); + print '
    '.$langs->trans("MessageLogin").''; if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); else print ' '; print '
    '.$langs->trans("MessageOfDay").''; + print '
    '.$langs->trans("MessageOfDay").''; if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); else print ' '; print '
    '; if ($object->photo) $ret.=''; - //$ret.=''; $ret.=''; $ret.='
    '.$langs->trans("Delete").'

    '.$langs->trans("PhotoFile").'
    '; } @@ -6112,10 +6108,9 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - $out.= ''; $num = $this->db->num_rows($resql); $i = 0; diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 95dee1424ef..4ae2d81539d 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -1011,6 +1011,7 @@ class FormOther if (! empty($boxidactivatedforuser[$box->id])) continue; // Already visible for user $label=$langs->transnoentitiesnoconv($box->boxlabel); if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')'; + //$label = ''.$label; KO with select2. No html rendering. $arrayboxtoactivatelabel[$box->id]=$label; // We keep only boxes not shown for user, to show into combo list } foreach($boxidactivatedforuser as $boxid) @@ -1027,7 +1028,7 @@ class FormOther $selectboxlist.=''; $selectboxlist.=''; $selectboxlist.=''; - $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected'); + $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected', 0, 1); if (empty($conf->use_javascript_ajax)) $selectboxlist.=' '; $selectboxlist.=''; $selectboxlist.=ajax_combobox("boxcombo"); diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 68e3f079361..214704f06a2 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -377,7 +377,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ $(\''.(preg_match('/^\./',$htmlname)?$htmlname:'#'.$htmlname).'\').'.$tmpplugin.'({ dir: \'ltr\', width: \''.$widthTypeOfAutocomplete.'\', /* off or resolve */ - minimumInputLength: '.$minLengthToAutocomplete.' + minimumInputLength: '.$minLengthToAutocomplete.' })'; if ($forcefocus) $msg.= '.select2(\'focus\')'; $msg.= ';'."\n"; diff --git a/htdocs/index.php b/htdocs/index.php index b6189537546..75ee74144f2 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -77,7 +77,7 @@ if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $title=$langs->trans("HomeAr llxHeader('',$title); - + $resultboxes=FormOther::getBoxesArea($user,"0"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb) @@ -242,7 +242,7 @@ if (empty($user->societe_id)) 'order', 'bill', 'propal', - 'project', + 'projectpub', 'trip', 'generic' ); @@ -388,7 +388,6 @@ if (! empty($conf->projet->enabled) && $user->rights->projet->lire) { include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $board=new Project($db); - $dashboardlines[] = $board->load_board($user); } diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 755998f7238..94c49d6d0ef 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1692,8 +1692,8 @@ class Project extends CommonObject $response->warning_delay = $conf->projet->warning_delay/60/60/24; $response->label = $langs->trans("OpenedProjects"); if ($user->rights->projet->all->lire) $response->url = DOL_URL_ROOT.'/projet/list.php?search_status=1&mainmenu=project'; - else $response->url = DOL_URL_ROOT.'/projet/list.php?mode=mine&search_status=1&mainmenu=project'; - $response->img = img_object($langs->trans("Projects"),"project"); + else $response->url = DOL_URL_ROOT.'/projet/list.php?search_project_user=-1&search_status=1&mainmenu=project'; + $response->img = img_object($langs->trans("Projects"),"projectpub"); // This assignment in condition is not a bug. It allows walking the results. while ($obj=$this->db->fetch_object($resql)) From 36630b94046af3f7b35c961632ab0d62bf8ef145 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:01:32 +0100 Subject: [PATCH 156/410] FIX Picto of project on dol_banner and box Conflicts: htdocs/core/boxes/box_project.php --- htdocs/core/boxes/box_project.php | 14 +++++++------- htdocs/core/lib/functions.lib.php | 6 ++++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index 4c0689cd282..8b5cbc342e6 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -78,7 +78,7 @@ class box_project extends ModeleBoxes // list the summary of the orders if ($user->rights->projet->lire) { - $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut "; + $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; if($user->socid) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=p.fk_soc"; $sql.= " WHERE p.entity = ".$conf->entity; @@ -98,7 +98,7 @@ class box_project extends ModeleBoxes $tooltip = $langs->trans('Project') . ': ' . $objp->ref; $this->info_box_contents[$i][0] = array( 'td' => 'align="left" width="16"', - 'logo' => 'object_project', + 'logo' => 'object_project'.($objp->public?'pub':''), 'tooltip' => $tooltip, 'url' => DOL_URL_ROOT."/projet/card.php?id=".$objp->rowid, ); @@ -123,13 +123,13 @@ class box_project extends ModeleBoxes if ($resultTask) { $objTask = $db->fetch_object($resultTask); $this->info_box_contents[$i][3] = array( - 'td' => 'align="right"', - 'text' => number_format($objTask->nb, 0, ',', ' ')." ".$langs->trans("Tasks"), + 'td' => 'class="right"', + 'text' => $objTask->nb." ".$langs->trans("Tasks"), ); - if ($objTask->nb > 0 ) + if ($objTask->nb > 0) $this->info_box_contents[$i][4] = array( - 'td' => 'align="right"', - 'text' => number_format(($objTask->totprogress/$objTask->nb), 0, ',', ' ')."%", + 'td' => 'class="right"', + 'text' => round($objTask->totprogress/$objTask->nb, 0)."%", ); else $this->info_box_contents[$i][4] = array('td' => 'align="right"', 'text' => "N/A "); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 709dc58d769..b2de5ff9d54 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1024,7 +1024,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r $morehtmlleft.=''; } } - elseif ($conf->browser->layout != 'phone') // Show no photo link + elseif ($conf->browser->layout != 'phone') // Show No photo link (picto of pbject) { $morehtmlleft.='
    '; if ($object->element == 'action') @@ -1036,7 +1036,9 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r else { $width=14; $cssclass='photorefcenter'; - $nophoto=img_picto('', 'object_'.$object->picto, '', false, 1); + $picto = $object->picto; + if ($object->element == 'project' && ! $object->public) $picto = 'project'; // instead of projectpub + $nophoto=img_picto('', 'object_'.$picto, '', false, 1); $morehtmlleft.='
    No photo
    '; } $morehtmlleft.='
    '; From e2e76b40dacaca429caeabc3f648de8b56282678 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:38:00 +0100 Subject: [PATCH 157/410] FIX list of projects Conflicts: htdocs/core/boxes/box_project.php --- htdocs/core/boxes/box_project.php | 46 +++++++++++++++++++++---------- htdocs/projet/list.php | 3 +- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index 8b5cbc342e6..a47ae3d0cb5 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -72,27 +72,40 @@ class box_project extends ModeleBoxes $totalnb = 0; $totalnbTask=0; - $textHead = $langs->trans("Projects"); + $textHead = $langs->trans("OpenedProjects"); $this->info_box_head = array('text' => $textHead, 'limit'=> dol_strlen($textHead)); // list the summary of the orders if ($user->rights->projet->lire) { - - $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; + + include_once(DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'); + $projectstatic = new Project($this->db); + + $socid=$user->societe_id; + + // Get list of project id allowed to user (in a string list separated by coma) + $projectsListId=''; + if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1,$socid); + + $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; if($user->socid) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=p.fk_soc"; - $sql.= " WHERE p.entity = ".$conf->entity; - if($user->socid) $sql.= " AND s.rowid = ".$user->socid; + $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; + if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users + if ($user->socid) $sql.= " AND s.rowid = ".$user->socid; $sql.= " AND p.fk_statut = 1"; // Seulement les projets ouverts - $sql.= " ORDER BY p.datec DESC"; - $sql.= $db->plimit($max, 0); + if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; + + $sql.= " ORDER BY p.datec DESC"; + //$sql.= $db->plimit($max, 0); $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); $i = 0; - while ($i < $num) { + while ($i < min($num, $max)) { $objp = $db->fetch_object($result); $tooltip = $langs->trans('Project') . ': ' . $objp->ref; @@ -117,8 +130,8 @@ class box_project extends ModeleBoxes $sql ="SELECT count(*) as nb, sum(progress) as totprogress"; $sql.=" FROM ".MAIN_DB_PREFIX."projet as p LEFT JOIN ".MAIN_DB_PREFIX."projet_task as pt on pt.fk_projet = p.rowid"; - $sql.=" WHERE p.entity = ".$conf->entity; - $sql.=" AND p.rowid = ".$objp->rowid; + $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; + $sql.=" AND p.rowid = ".$objp->rowid; $resultTask = $db->query($sql); if ($resultTask) { $objTask = $db->fetch_object($resultTask); @@ -135,12 +148,17 @@ class box_project extends ModeleBoxes $this->info_box_contents[$i][4] = array('td' => 'align="right"', 'text' => "N/A "); $totalnbTask += $objTask->nb; } else { - $this->info_box_contents[$i][3] = array('td' => 'align="right"', 'text' => number_format(0, 0, ',', ' ')); - $this->info_box_contents[$i][4] = array('td' => 'align="right"', 'text' => "N/A "); + $this->info_box_contents[$i][3] = array('td' => 'class="right"', 'text' => round(0)); + $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); } $i++; } + if ($max < $num) + { + $this->info_box_contents[$i][0] = array('td' => 'colspan="5"', 'text' => '...'); + $i++; + } } } @@ -158,11 +176,11 @@ class box_project extends ModeleBoxes ); $this->info_box_contents[$i][2] = array( 'td' => 'align="right" ', - 'text' => number_format($num, 0, ',', ' ')." ".$langs->trans("Projects"), + 'text' => round($num, 0)." ".$langs->trans("Projects"), ); $this->info_box_contents[$i][3] = array( 'td' => 'align="right" ', - 'text' => number_format($totalnbTask, 0, ',', ' ')." ".$langs->trans("Tasks"), + 'text' => (($max < $num) ? '' : (round($totalnbTask, 0)." ".$langs->trans("Tasks"))), ); $this->info_box_contents[$i][4] = array( 'td' => '', diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 68077621771..dadc199d146 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -196,6 +196,7 @@ $title=$langs->trans("Projects"); if ($search_user == $user->id) $title=$langs->trans("MyProjects"); // Get list of project id allowed to user (in a string list separated by coma) +$projectsListId=''; if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1,$socid); // Get id of types of contacts for projects (This list never contains a lot of elements) @@ -245,7 +246,7 @@ if ($search_user > 0) $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser -if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; +if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$db->escape($search_categ); if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($search_ref) $sql .= natural_search('p.ref', $search_ref); From 4457bc33cd8b2acb56ae5f344c0782720b251337 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 14:23:55 +0100 Subject: [PATCH 158/410] Fix english translation --- htdocs/langs/en_US/admin.lang | 2 +- htdocs/langs/en_US/bills.lang | 24 ++++++++++++------------ htdocs/langs/en_US/companies.lang | 2 +- htdocs/langs/en_US/compta.lang | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 213c8d4767e..2df0ffcc9d4 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -82,7 +82,7 @@ Mask=Mask NextValue=Next value NextValueForInvoices=Next value (invoices) NextValueForCreditNotes=Next value (credit notes) -NextValueForDeposit=Next value (deposit) +NextValueForDeposit=Next value (down payment) NextValueForReplacements=Next value (replacements) MustBeLowerThanPHPLimit=Note: your PHP limits each file upload's size to %s %s, whatever this parameter's value is NoMaxSizeByPHPLimit=Note: No limit is set in your PHP configuration diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 7d9fcf3aa63..9ea58263dfd 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -15,9 +15,9 @@ DisabledBecauseNotErasable=Disabled because cannot be erased InvoiceStandard=Standard invoice InvoiceStandardAsk=Standard invoice InvoiceStandardDesc=This kind of invoice is the common invoice. -InvoiceDeposit=Deposit invoice -InvoiceDepositAsk=Deposit invoice -InvoiceDepositDesc=This kind of invoice is done when a deposit has been received. +InvoiceDeposit=Down payment invoice +InvoiceDepositAsk=Down payment invoice +InvoiceDepositDesc=This kind of invoice is done when a down payment has been received. InvoiceProForma=Proforma invoice InvoiceProFormaAsk=Proforma invoice InvoiceProFormaDesc=Proforma invoice is an image of a true invoice but has no accountancy value. @@ -63,7 +63,7 @@ paymentInInvoiceCurrency=in invoices currency PaidBack=Paid back DeletePayment=Delete payment ConfirmDeletePayment=Are you sure you want to delete this payment? -ConfirmConvertToReduc=Do you want to convert this credit note or deposit into an absolute discount?
    The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this customer. +ConfirmConvertToReduc=Do you want to convert this credit note or down payment into an absolute discount?
    The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this customer. SupplierPayments=Suppliers payments ReceivedPayments=Received payments ReceivedCustomersPayments=Payments received from customers @@ -196,12 +196,12 @@ ShowBill=Show invoice ShowInvoice=Show invoice ShowInvoiceReplace=Show replacing invoice ShowInvoiceAvoir=Show credit note -ShowInvoiceDeposit=Show deposit invoice +ShowInvoiceDeposit=Show down payment invoice ShowInvoiceSituation=Show situation invoice ShowPayment=Show payment AlreadyPaid=Already paid AlreadyPaidBack=Already paid back -AlreadyPaidNoCreditNotesNoDeposits=Already paid (without credit notes and deposits) +AlreadyPaidNoCreditNotesNoDeposits=Already paid (without credit notes and down payments) Abandoned=Abandoned RemainderToPay=Remaining unpaid RemainderToTake=Remaining amount to take @@ -268,10 +268,10 @@ RelativeDiscount=Relative discount GlobalDiscount=Global discount CreditNote=Credit note CreditNotes=Credit notes -Deposit=Deposit -Deposits=Deposits +Deposit=Down payment +Deposits=Down payments DiscountFromCreditNote=Discount from credit note %s -DiscountFromDeposit=Payments from deposit invoice %s +DiscountFromDeposit=Down payments from invoice %s AbsoluteDiscountUse=This kind of credit can be used on invoice before its validation CreditNoteDepositUse=Invoice must be validated to use this kind of credits NewGlobalDiscount=New absolute discount @@ -422,7 +422,7 @@ ChequeDeposits=Checks deposits Cheques=Checks DepositId=Id deposit NbCheque=Number of checks -CreditNoteConvertedIntoDiscount=This credit note or deposit invoice has been converted into %s +CreditNoteConvertedIntoDiscount=This credit note or down payment invoice has been converted into %s UsBillingContactAsIncoiveRecipientIfExist=Use customer billing contact address instead of third party address as recipient for invoices ShowUnpaidAll=Show all unpaid invoices ShowUnpaidLateOnly=Show late unpaid invoices only @@ -451,9 +451,9 @@ YouMustCreateStandardInvoiceFirstDesc=You have to create a standard invoice firs PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (recommended Template) PDFCrevetteDescription=Invoice PDF template Crevette. A complete invoice template for situation invoices TerreNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 -MarsNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for replacement invoices, %syymm-nnnn for deposit invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 +MarsNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for replacement invoices, %syymm-nnnn for down payment invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 TerreNumRefModelError=A bill starting with $syymm already exists and is not compatible with this model of sequence. Remove it or rename it to activate this module. -CactusNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for credit notes and %syymm-nnnn for deposit invoices where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 +CactusNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for credit notes and %syymm-nnnn for down payment invoices where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 ##### Types de contacts ##### TypeContact_facture_internal_SALESREPFOLL=Representative following-up customer invoice TypeContact_facture_external_BILLING=Customer invoice contact diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 355f9f3f31c..45e7864e0d4 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -254,7 +254,7 @@ CustomerRelativeDiscountShort=Relative discount CustomerAbsoluteDiscountShort=Absolute discount CompanyHasRelativeDiscount=This customer has a default discount of %s%% CompanyHasNoRelativeDiscount=This customer has no relative discount by default -CompanyHasAbsoluteDiscount=This customer still has discount credits or deposits for %s %s +CompanyHasAbsoluteDiscount=This customer has discount available (credits notes or down payments) for %s %s CompanyHasCreditNote=This customer still has credit notes for %s %s CompanyHasNoAbsoluteDiscount=This customer has no discount credit available CustomerAbsoluteDiscountAllUsers=Absolute discounts (granted by all users) diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 08f17ed995e..a4080b76b07 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -133,8 +133,8 @@ RulesResultDue=- It includes outstanding invoices, expenses, VAT, donations whet RulesResultInOut=- It includes the real payments made on invoices, expenses, VAT and salaries.
    - It is based on the payment dates of the invoices, expenses, VAT and salaries. The donation date for donation. RulesCADue=- It includes the client's due invoices whether they are paid or not.
    - It is based on the validation date of these invoices.
    RulesCAIn=- It includes all the effective payments of invoices received from clients.
    - It is based on the payment date of these invoices
    -DepositsAreNotIncluded=- Deposit invoices are nor included -DepositsAreIncluded=- Deposit invoices are included +DepositsAreNotIncluded=- Down payment invoices are nor included +DepositsAreIncluded=- Down payment invoices are included LT2ReportByCustomersInInputOutputModeES=Report by third party IRPF LT1ReportByCustomersInInputOutputModeES=Report by third party RE VATReport=VAT report @@ -168,7 +168,7 @@ DescSellsJournal=Sales Journal DescPurchasesJournal=Purchases Journal InvoiceRef=Invoice ref. CodeNotDef=Not defined -WarningDepositsNotIncluded=Deposits invoices are not included in this version with this accountancy module. +WarningDepositsNotIncluded=Down payment invoices are not included in this version with this accountancy module. DatePaymentTermCantBeLowerThanObjectDate=Payment term date can't be lower than object date. Pcg_version=Chart of accounts models Pcg_type=Pcg type From a5c11dc8408884ce022e648ac7f3d4409eabdf12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 16:02:54 +0100 Subject: [PATCH 159/410] NEW Add function dolMd2Html --- COPYRIGHT | 1 + htdocs/admin/modulehelp.php | 68 +- htdocs/core/lib/parsemd.lib.php | 46 + htdocs/core/modules/modFacture.class.php | 2 +- htdocs/includes/parsedown/.travis.yml | 16 + htdocs/includes/parsedown/LICENSE.txt | 20 + htdocs/includes/parsedown/Parsedown.php | 1548 ++++++++++++++++++++ htdocs/includes/parsedown/README.md | 56 + htdocs/includes/parsedown/composer.json | 21 + htdocs/includes/parsedown/phpunit.xml.dist | 8 + htdocs/langs/en_US/admin.lang | 1 + 11 files changed, 1762 insertions(+), 25 deletions(-) create mode 100644 htdocs/core/lib/parsemd.lib.php create mode 100644 htdocs/includes/parsedown/.travis.yml create mode 100644 htdocs/includes/parsedown/LICENSE.txt create mode 100644 htdocs/includes/parsedown/Parsedown.php create mode 100644 htdocs/includes/parsedown/README.md create mode 100644 htdocs/includes/parsedown/composer.json create mode 100644 htdocs/includes/parsedown/phpunit.xml.dist diff --git a/COPYRIGHT b/COPYRIGHT index f55772c0d9f..6f8a595897d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -22,6 +22,7 @@ Mobiledetect 2.8.17 MIT License Yes NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency odtPHP 1.0.1 GPL-2+ b Yes Library to build/edit ODT files +ParseDown 1.6 MIT License Yes Markdown parser PHPExcel 1.8.1 LGPL-2.1+ Yes Read/Write XLS files, read ODS files php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 9ff7a4478ff..e76627c2965 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -239,7 +239,7 @@ $head[$h][2] = 'desc'; $h++; $head[$h][0] = DOL_URL_ROOT."/admin/modulehelp.php?id=".$id.'&mode=feature'; -$head[$h][1] = $langs->trans("Features"); +$head[$h][1] = $langs->trans("TechnicalServicesProvided"); $head[$h][2] = 'feature'; $h++; @@ -251,45 +251,38 @@ foreach($orders as $tmpkey => $tmpvalue) if ($objMod->numero == $id) { $key = $i; + $modName = $filename[$tmpkey]; + $dirofmodule = $dirmod[$tmpkey]; break; } $i++; } $value = $orders[$key]; +$special = $objMod->special; +$tab=explode('_',$value); +$familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3]; + +// Check filters +$modulename=$objMod->getName(); +$moduledesc=$objMod->getDesc(); +$moduleauthor=$objMod->getPublisher(); + print '
    '; - -print load_fiche_titre($objMod->getDesc(),$moreinfo,'object_'.$objMod->picto); +print load_fiche_titre(($modulename?$modulename:$moduledesc), $moreinfo, 'object_'.$objMod->picto); print '
    '; -dol_fiche_head($head, $mode, $title); +dol_fiche_head($head, $mode, $title, -1); - - -$tab=explode('_',$value); -$familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3]; - -$modName = $filename[$key]; -$objMod = $modules[$key]; -$dirofmodule = $dirmod[$key]; - -$special = $objMod->special; - -if (! $objMod->getName()) +if (! $modulename) { dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING); } $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod))); -// Check filters -$modulename=$objMod->getName(); -$moduledesc=$objMod->getDesc(); -$moduledesclong=$objMod->getDescLong(); -$moduleauthor=$objMod->getPublisher(); - // Load all lang files of module if (isset($objMod->langfiles) && is_array($objMod->langfiles)) { @@ -322,6 +315,8 @@ $text=''; if ($mode == 'desc') { + if ($moduledesc) $text.=$moduledesc.'

    '; + $text.=''.$langs->trans("Version").': '.$version; $textexternal=''; @@ -329,7 +324,7 @@ if ($mode == 'desc') { $textexternal.='
    '.$langs->trans("Origin").': '.$langs->trans("ExternalModule",$dirofmodule); if ($objMod->editor_name != 'dolibarr') $textexternal.='
    '.$langs->trans("Publisher").': '.(empty($objMod->editor_name)?$langs->trans("Unknown"):$objMod->editor_name); - if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='
    '.$langs->trans("Url").': '.$objMod->editor_url; + if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='
    '.$langs->trans("Url").': '.$objMod->editor_url.''; $text.=$textexternal; $text.='
    '; } @@ -342,7 +337,8 @@ if ($mode == 'desc') else $text.=$langs->trans("Disabled"); $text.='
    '; - if ($objMod->getDescLong()) $text.=$objMod->getDesc().'
    '; + $moduledesclong=$objMod->getDescLong(); + if ($moduledesclong) $text.='


    '.$moduledesclong.'
    '; } if ($mode == 'feature') @@ -360,6 +356,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddDictionaries").': '; if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib'])) { @@ -372,6 +370,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddBoxes").': '; if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes)) { @@ -384,6 +384,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddModels").': '; if (isset($objMod->module_parts) && isset($objMod->module_parts['models']) && $objMod->module_parts['models']) { @@ -391,6 +393,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddSubstitutions").': '; if (isset($objMod->module_parts) && isset($objMod->module_parts['substitutions']) && $objMod->module_parts['substitutions']) { @@ -398,6 +402,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddSheduledJobs").': '; if (isset($objMod->cronjobs) && is_array($objMod->cronjobs) && count($objMod->cronjobs)) { @@ -410,6 +416,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddTriggers").': '; if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers']) { @@ -417,6 +425,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddHooks").': '; if (isset($objMod->module_parts) && is_array($objMod->module_parts['hooks']) && count($objMod->module_parts['hooks'])) { @@ -429,6 +439,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddPermissions").': '; if (isset($objMod->rights) && is_array($objMod->rights) && count($objMod->rights)) { @@ -441,6 +453,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddMenus").': '; if (isset($objMod->menu) && ! empty($objMod->menu)) // objMod can be an array or just an int 1 { @@ -448,6 +462,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddExportProfiles").': '; if (isset($objMod->export_label) && is_array($objMod->export_label) && count($objMod->export_label)) { @@ -460,6 +476,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddImportProfiles").': '; if (isset($objMod->import_label) && is_array($objMod->import_label) && count($objMod->import_label)) { @@ -472,6 +490,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
    '; + $text.='
    '.$langs->trans("AddOtherPagesOrServices").': '; $text.=$langs->trans("DetectionNotPossible"); } diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php new file mode 100644 index 00000000000..17e64f6543e --- /dev/null +++ b/htdocs/core/lib/parsemd.lib.php @@ -0,0 +1,46 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/lib/parsemd.lib.php + * \brief This file contains functions dedicated to MD parsind. + */ + +/** + * Function to parse MD content into HTML + * + * @param string $content MD content + * @param string $parser 'parsedown' or 'nl2br' + * @return string Parsed content + */ +function dolMd2Html($content, $parser='parsedown') +{ + if ($parser == 'parsedown') + { + include DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; + $Parsedown = new Parsedown(); + $content = $Parsedown->text($content); + } + else + { + $content = nl2br($content); + } + + return $content; +} + diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index a88082ba6fc..d6e6bfd2575 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -69,7 +69,7 @@ class modFacture extends DolibarrModules $this->conflictwith = array(); $this->langfiles = array("bills","companies","compta","products"); $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='text') - $this->warnings_activation_ext = array('CA'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') + $this->warnings_activation_ext = array('FR'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') // Config pages $this->config_page_url = array("facture.php"); diff --git a/htdocs/includes/parsedown/.travis.yml b/htdocs/includes/parsedown/.travis.yml new file mode 100644 index 00000000000..fa5ca981cc9 --- /dev/null +++ b/htdocs/includes/parsedown/.travis.yml @@ -0,0 +1,16 @@ +language: php + +php: + - 7.1 + - 7.0 + - 5.6 + - 5.5 + - 5.4 + - 5.3 + - hhvm + - hhvm-nightly + +matrix: + fast_finish: true + allow_failures: + - php: hhvm-nightly diff --git a/htdocs/includes/parsedown/LICENSE.txt b/htdocs/includes/parsedown/LICENSE.txt new file mode 100644 index 00000000000..baca86f5b8e --- /dev/null +++ b/htdocs/includes/parsedown/LICENSE.txt @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Emanuil Rusev, erusev.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/htdocs/includes/parsedown/Parsedown.php b/htdocs/includes/parsedown/Parsedown.php new file mode 100644 index 00000000000..20863a7537a --- /dev/null +++ b/htdocs/includes/parsedown/Parsedown.php @@ -0,0 +1,1548 @@ +DefinitionData = array(); + + # standardize line breaks + $text = str_replace(array("\r\n", "\r"), "\n", $text); + + # remove surrounding line breaks + $text = trim($text, "\n"); + + # split text into lines + $lines = explode("\n", $text); + + # iterate through lines to identify blocks + $markup = $this->lines($lines); + + # trim line breaks + $markup = trim($markup, "\n"); + + return $markup; + } + + # + # Setters + # + + function setBreaksEnabled($breaksEnabled) + { + $this->breaksEnabled = $breaksEnabled; + + return $this; + } + + protected $breaksEnabled; + + function setMarkupEscaped($markupEscaped) + { + $this->markupEscaped = $markupEscaped; + + return $this; + } + + protected $markupEscaped; + + function setUrlsLinked($urlsLinked) + { + $this->urlsLinked = $urlsLinked; + + return $this; + } + + protected $urlsLinked = true; + + # + # Lines + # + + protected $BlockTypes = array( + '#' => array('Header'), + '*' => array('Rule', 'List'), + '+' => array('List'), + '-' => array('SetextHeader', 'Table', 'Rule', 'List'), + '0' => array('List'), + '1' => array('List'), + '2' => array('List'), + '3' => array('List'), + '4' => array('List'), + '5' => array('List'), + '6' => array('List'), + '7' => array('List'), + '8' => array('List'), + '9' => array('List'), + ':' => array('Table'), + '<' => array('Comment', 'Markup'), + '=' => array('SetextHeader'), + '>' => array('Quote'), + '[' => array('Reference'), + '_' => array('Rule'), + '`' => array('FencedCode'), + '|' => array('Table'), + '~' => array('FencedCode'), + ); + + # ~ + + protected $unmarkedBlockTypes = array( + 'Code', + ); + + # + # Blocks + # + + protected function lines(array $lines) + { + $CurrentBlock = null; + + foreach ($lines as $line) + { + if (chop($line) === '') + { + if (isset($CurrentBlock)) + { + $CurrentBlock['interrupted'] = true; + } + + continue; + } + + if (strpos($line, "\t") !== false) + { + $parts = explode("\t", $line); + + $line = $parts[0]; + + unset($parts[0]); + + foreach ($parts as $part) + { + $shortage = 4 - mb_strlen($line, 'utf-8') % 4; + + $line .= str_repeat(' ', $shortage); + $line .= $part; + } + } + + $indent = 0; + + while (isset($line[$indent]) and $line[$indent] === ' ') + { + $indent ++; + } + + $text = $indent > 0 ? substr($line, $indent) : $line; + + # ~ + + $Line = array('body' => $line, 'indent' => $indent, 'text' => $text); + + # ~ + + if (isset($CurrentBlock['continuable'])) + { + $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock); + + if (isset($Block)) + { + $CurrentBlock = $Block; + + continue; + } + else + { + if ($this->isBlockCompletable($CurrentBlock['type'])) + { + $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); + } + } + } + + # ~ + + $marker = $text[0]; + + # ~ + + $blockTypes = $this->unmarkedBlockTypes; + + if (isset($this->BlockTypes[$marker])) + { + foreach ($this->BlockTypes[$marker] as $blockType) + { + $blockTypes []= $blockType; + } + } + + # + # ~ + + foreach ($blockTypes as $blockType) + { + $Block = $this->{'block'.$blockType}($Line, $CurrentBlock); + + if (isset($Block)) + { + $Block['type'] = $blockType; + + if ( ! isset($Block['identified'])) + { + $Blocks []= $CurrentBlock; + + $Block['identified'] = true; + } + + if ($this->isBlockContinuable($blockType)) + { + $Block['continuable'] = true; + } + + $CurrentBlock = $Block; + + continue 2; + } + } + + # ~ + + if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted'])) + { + $CurrentBlock['element']['text'] .= "\n".$text; + } + else + { + $Blocks []= $CurrentBlock; + + $CurrentBlock = $this->paragraph($Line); + + $CurrentBlock['identified'] = true; + } + } + + # ~ + + if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type'])) + { + $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); + } + + # ~ + + $Blocks []= $CurrentBlock; + + unset($Blocks[0]); + + # ~ + + $markup = ''; + + foreach ($Blocks as $Block) + { + if (isset($Block['hidden'])) + { + continue; + } + + $markup .= "\n"; + $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']); + } + + $markup .= "\n"; + + # ~ + + return $markup; + } + + protected function isBlockContinuable($Type) + { + return method_exists($this, 'block'.$Type.'Continue'); + } + + protected function isBlockCompletable($Type) + { + return method_exists($this, 'block'.$Type.'Complete'); + } + + # + # Code + + protected function blockCode($Line, $Block = null) + { + if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted'])) + { + return; + } + + if ($Line['indent'] >= 4) + { + $text = substr($Line['body'], 4); + + $Block = array( + 'element' => array( + 'name' => 'pre', + 'handler' => 'element', + 'text' => array( + 'name' => 'code', + 'text' => $text, + ), + ), + ); + + return $Block; + } + } + + protected function blockCodeContinue($Line, $Block) + { + if ($Line['indent'] >= 4) + { + if (isset($Block['interrupted'])) + { + $Block['element']['text']['text'] .= "\n"; + + unset($Block['interrupted']); + } + + $Block['element']['text']['text'] .= "\n"; + + $text = substr($Line['body'], 4); + + $Block['element']['text']['text'] .= $text; + + return $Block; + } + } + + protected function blockCodeComplete($Block) + { + $text = $Block['element']['text']['text']; + + $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); + + $Block['element']['text']['text'] = $text; + + return $Block; + } + + # + # Comment + + protected function blockComment($Line) + { + if ($this->markupEscaped) + { + return; + } + + if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!') + { + $Block = array( + 'markup' => $Line['body'], + ); + + if (preg_match('/-->$/', $Line['text'])) + { + $Block['closed'] = true; + } + + return $Block; + } + } + + protected function blockCommentContinue($Line, array $Block) + { + if (isset($Block['closed'])) + { + return; + } + + $Block['markup'] .= "\n" . $Line['body']; + + if (preg_match('/-->$/', $Line['text'])) + { + $Block['closed'] = true; + } + + return $Block; + } + + # + # Fenced Code + + protected function blockFencedCode($Line) + { + if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches)) + { + $Element = array( + 'name' => 'code', + 'text' => '', + ); + + if (isset($matches[1])) + { + $class = 'language-'.$matches[1]; + + $Element['attributes'] = array( + 'class' => $class, + ); + } + + $Block = array( + 'char' => $Line['text'][0], + 'element' => array( + 'name' => 'pre', + 'handler' => 'element', + 'text' => $Element, + ), + ); + + return $Block; + } + } + + protected function blockFencedCodeContinue($Line, $Block) + { + if (isset($Block['complete'])) + { + return; + } + + if (isset($Block['interrupted'])) + { + $Block['element']['text']['text'] .= "\n"; + + unset($Block['interrupted']); + } + + if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text'])) + { + $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1); + + $Block['complete'] = true; + + return $Block; + } + + $Block['element']['text']['text'] .= "\n".$Line['body']; + + return $Block; + } + + protected function blockFencedCodeComplete($Block) + { + $text = $Block['element']['text']['text']; + + $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); + + $Block['element']['text']['text'] = $text; + + return $Block; + } + + # + # Header + + protected function blockHeader($Line) + { + if (isset($Line['text'][1])) + { + $level = 1; + + while (isset($Line['text'][$level]) and $Line['text'][$level] === '#') + { + $level ++; + } + + if ($level > 6) + { + return; + } + + $text = trim($Line['text'], '# '); + + $Block = array( + 'element' => array( + 'name' => 'h' . min(6, $level), + 'text' => $text, + 'handler' => 'line', + ), + ); + + return $Block; + } + } + + # + # List + + protected function blockList($Line) + { + list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]'); + + if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches)) + { + $Block = array( + 'indent' => $Line['indent'], + 'pattern' => $pattern, + 'element' => array( + 'name' => $name, + 'handler' => 'elements', + ), + ); + + if($name === 'ol') + { + $listStart = stristr($matches[0], '.', true); + + if($listStart !== '1') + { + $Block['element']['attributes'] = array('start' => $listStart); + } + } + + $Block['li'] = array( + 'name' => 'li', + 'handler' => 'li', + 'text' => array( + $matches[2], + ), + ); + + $Block['element']['text'] []= & $Block['li']; + + return $Block; + } + } + + protected function blockListContinue($Line, array $Block) + { + if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches)) + { + if (isset($Block['interrupted'])) + { + $Block['li']['text'] []= ''; + + unset($Block['interrupted']); + } + + unset($Block['li']); + + $text = isset($matches[1]) ? $matches[1] : ''; + + $Block['li'] = array( + 'name' => 'li', + 'handler' => 'li', + 'text' => array( + $text, + ), + ); + + $Block['element']['text'] []= & $Block['li']; + + return $Block; + } + + if ($Line['text'][0] === '[' and $this->blockReference($Line)) + { + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); + + $Block['li']['text'] []= $text; + + return $Block; + } + + if ($Line['indent'] > 0) + { + $Block['li']['text'] []= ''; + + $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); + + $Block['li']['text'] []= $text; + + unset($Block['interrupted']); + + return $Block; + } + } + + # + # Quote + + protected function blockQuote($Line) + { + if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) + { + $Block = array( + 'element' => array( + 'name' => 'blockquote', + 'handler' => 'lines', + 'text' => (array) $matches[1], + ), + ); + + return $Block; + } + } + + protected function blockQuoteContinue($Line, array $Block) + { + if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) + { + if (isset($Block['interrupted'])) + { + $Block['element']['text'] []= ''; + + unset($Block['interrupted']); + } + + $Block['element']['text'] []= $matches[1]; + + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $Block['element']['text'] []= $Line['text']; + + return $Block; + } + } + + # + # Rule + + protected function blockRule($Line) + { + if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text'])) + { + $Block = array( + 'element' => array( + 'name' => 'hr' + ), + ); + + return $Block; + } + } + + # + # Setext + + protected function blockSetextHeader($Line, array $Block = null) + { + if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) + { + return; + } + + if (chop($Line['text'], $Line['text'][0]) === '') + { + $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2'; + + return $Block; + } + } + + # + # Markup + + protected function blockMarkup($Line) + { + if ($this->markupEscaped) + { + return; + } + + if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches)) + { + $element = strtolower($matches[1]); + + if (in_array($element, $this->textLevelElements)) + { + return; + } + + $Block = array( + 'name' => $matches[1], + 'depth' => 0, + 'markup' => $Line['text'], + ); + + $length = strlen($matches[0]); + + $remainder = substr($Line['text'], $length); + + if (trim($remainder) === '') + { + if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) + { + $Block['closed'] = true; + + $Block['void'] = true; + } + } + else + { + if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) + { + return; + } + + if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder)) + { + $Block['closed'] = true; + } + } + + return $Block; + } + } + + protected function blockMarkupContinue($Line, array $Block) + { + if (isset($Block['closed'])) + { + return; + } + + if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open + { + $Block['depth'] ++; + } + + if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close + { + if ($Block['depth'] > 0) + { + $Block['depth'] --; + } + else + { + $Block['closed'] = true; + } + } + + if (isset($Block['interrupted'])) + { + $Block['markup'] .= "\n"; + + unset($Block['interrupted']); + } + + $Block['markup'] .= "\n".$Line['body']; + + return $Block; + } + + # + # Reference + + protected function blockReference($Line) + { + if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches)) + { + $id = strtolower($matches[1]); + + $Data = array( + 'url' => $matches[2], + 'title' => null, + ); + + if (isset($matches[3])) + { + $Data['title'] = $matches[3]; + } + + $this->DefinitionData['Reference'][$id] = $Data; + + $Block = array( + 'hidden' => true, + ); + + return $Block; + } + } + + # + # Table + + protected function blockTable($Line, array $Block = null) + { + if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) + { + return; + } + + if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '') + { + $alignments = array(); + + $divider = $Line['text']; + + $divider = trim($divider); + $divider = trim($divider, '|'); + + $dividerCells = explode('|', $divider); + + foreach ($dividerCells as $dividerCell) + { + $dividerCell = trim($dividerCell); + + if ($dividerCell === '') + { + continue; + } + + $alignment = null; + + if ($dividerCell[0] === ':') + { + $alignment = 'left'; + } + + if (substr($dividerCell, - 1) === ':') + { + $alignment = $alignment === 'left' ? 'center' : 'right'; + } + + $alignments []= $alignment; + } + + # ~ + + $HeaderElements = array(); + + $header = $Block['element']['text']; + + $header = trim($header); + $header = trim($header, '|'); + + $headerCells = explode('|', $header); + + foreach ($headerCells as $index => $headerCell) + { + $headerCell = trim($headerCell); + + $HeaderElement = array( + 'name' => 'th', + 'text' => $headerCell, + 'handler' => 'line', + ); + + if (isset($alignments[$index])) + { + $alignment = $alignments[$index]; + + $HeaderElement['attributes'] = array( + 'style' => 'text-align: '.$alignment.';', + ); + } + + $HeaderElements []= $HeaderElement; + } + + # ~ + + $Block = array( + 'alignments' => $alignments, + 'identified' => true, + 'element' => array( + 'name' => 'table', + 'handler' => 'elements', + ), + ); + + $Block['element']['text'] []= array( + 'name' => 'thead', + 'handler' => 'elements', + ); + + $Block['element']['text'] []= array( + 'name' => 'tbody', + 'handler' => 'elements', + 'text' => array(), + ); + + $Block['element']['text'][0]['text'] []= array( + 'name' => 'tr', + 'handler' => 'elements', + 'text' => $HeaderElements, + ); + + return $Block; + } + } + + protected function blockTableContinue($Line, array $Block) + { + if (isset($Block['interrupted'])) + { + return; + } + + if ($Line['text'][0] === '|' or strpos($Line['text'], '|')) + { + $Elements = array(); + + $row = $Line['text']; + + $row = trim($row); + $row = trim($row, '|'); + + preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches); + + foreach ($matches[0] as $index => $cell) + { + $cell = trim($cell); + + $Element = array( + 'name' => 'td', + 'handler' => 'line', + 'text' => $cell, + ); + + if (isset($Block['alignments'][$index])) + { + $Element['attributes'] = array( + 'style' => 'text-align: '.$Block['alignments'][$index].';', + ); + } + + $Elements []= $Element; + } + + $Element = array( + 'name' => 'tr', + 'handler' => 'elements', + 'text' => $Elements, + ); + + $Block['element']['text'][1]['text'] []= $Element; + + return $Block; + } + } + + # + # ~ + # + + protected function paragraph($Line) + { + $Block = array( + 'element' => array( + 'name' => 'p', + 'text' => $Line['text'], + 'handler' => 'line', + ), + ); + + return $Block; + } + + # + # Inline Elements + # + + protected $InlineTypes = array( + '"' => array('SpecialCharacter'), + '!' => array('Image'), + '&' => array('SpecialCharacter'), + '*' => array('Emphasis'), + ':' => array('Url'), + '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'), + '>' => array('SpecialCharacter'), + '[' => array('Link'), + '_' => array('Emphasis'), + '`' => array('Code'), + '~' => array('Strikethrough'), + '\\' => array('EscapeSequence'), + ); + + # ~ + + protected $inlineMarkerList = '!"*_&[:<>`~\\'; + + # + # ~ + # + + public function line($text) + { + $markup = ''; + + # $excerpt is based on the first occurrence of a marker + + while ($excerpt = strpbrk($text, $this->inlineMarkerList)) + { + $marker = $excerpt[0]; + + $markerPosition = strpos($text, $marker); + + $Excerpt = array('text' => $excerpt, 'context' => $text); + + foreach ($this->InlineTypes[$marker] as $inlineType) + { + $Inline = $this->{'inline'.$inlineType}($Excerpt); + + if ( ! isset($Inline)) + { + continue; + } + + # makes sure that the inline belongs to "our" marker + + if (isset($Inline['position']) and $Inline['position'] > $markerPosition) + { + continue; + } + + # sets a default inline position + + if ( ! isset($Inline['position'])) + { + $Inline['position'] = $markerPosition; + } + + # the text that comes before the inline + $unmarkedText = substr($text, 0, $Inline['position']); + + # compile the unmarked text + $markup .= $this->unmarkedText($unmarkedText); + + # compile the inline + $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']); + + # remove the examined text + $text = substr($text, $Inline['position'] + $Inline['extent']); + + continue 2; + } + + # the marker does not belong to an inline + + $unmarkedText = substr($text, 0, $markerPosition + 1); + + $markup .= $this->unmarkedText($unmarkedText); + + $text = substr($text, $markerPosition + 1); + } + + $markup .= $this->unmarkedText($text); + + return $markup; + } + + # + # ~ + # + + protected function inlineCode($Excerpt) + { + $marker = $Excerpt['text'][0]; + + if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]), + 'element' => array( + 'name' => 'code', + 'text' => $text, + ), + ); + } + } + + protected function inlineEmailTag($Excerpt) + { + if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches)) + { + $url = $matches[1]; + + if ( ! isset($matches[2])) + { + $url = 'mailto:' . $url; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $matches[1], + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + protected function inlineEmphasis($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + $marker = $Excerpt['text'][0]; + + if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'strong'; + } + elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'em'; + } + else + { + return; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => $emphasis, + 'handler' => 'line', + 'text' => $matches[1], + ), + ); + } + + protected function inlineEscapeSequence($Excerpt) + { + if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters)) + { + return array( + 'markup' => $Excerpt['text'][1], + 'extent' => 2, + ); + } + } + + protected function inlineImage($Excerpt) + { + if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[') + { + return; + } + + $Excerpt['text']= substr($Excerpt['text'], 1); + + $Link = $this->inlineLink($Excerpt); + + if ($Link === null) + { + return; + } + + $Inline = array( + 'extent' => $Link['extent'] + 1, + 'element' => array( + 'name' => 'img', + 'attributes' => array( + 'src' => $Link['element']['attributes']['href'], + 'alt' => $Link['element']['text'], + ), + ), + ); + + $Inline['element']['attributes'] += $Link['element']['attributes']; + + unset($Inline['element']['attributes']['href']); + + return $Inline; + } + + protected function inlineLink($Excerpt) + { + $Element = array( + 'name' => 'a', + 'handler' => 'line', + 'text' => null, + 'attributes' => array( + 'href' => null, + 'title' => null, + ), + ); + + $extent = 0; + + $remainder = $Excerpt['text']; + + if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) + { + $Element['text'] = $matches[1]; + + $extent += strlen($matches[0]); + + $remainder = substr($remainder, $extent); + } + else + { + return; + } + + if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) + { + $Element['attributes']['href'] = $matches[1]; + + if (isset($matches[2])) + { + $Element['attributes']['title'] = substr($matches[2], 1, - 1); + } + + $extent += strlen($matches[0]); + } + else + { + if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) + { + $definition = strlen($matches[1]) ? $matches[1] : $Element['text']; + $definition = strtolower($definition); + + $extent += strlen($matches[0]); + } + else + { + $definition = strtolower($Element['text']); + } + + if ( ! isset($this->DefinitionData['Reference'][$definition])) + { + return; + } + + $Definition = $this->DefinitionData['Reference'][$definition]; + + $Element['attributes']['href'] = $Definition['url']; + $Element['attributes']['title'] = $Definition['title']; + } + + $Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']); + + return array( + 'extent' => $extent, + 'element' => $Element, + ); + } + + protected function inlineMarkup($Excerpt) + { + if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false) + { + return; + } + + if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + } + + protected function inlineSpecialCharacter($Excerpt) + { + if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text'])) + { + return array( + 'markup' => '&', + 'extent' => 1, + ); + } + + $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot'); + + if (isset($SpecialCharacter[$Excerpt['text'][0]])) + { + return array( + 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';', + 'extent' => 1, + ); + } + } + + protected function inlineStrikethrough($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) + { + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'del', + 'text' => $matches[1], + 'handler' => 'line', + ), + ); + } + } + + protected function inlineUrl($Excerpt) + { + if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/') + { + return; + } + + if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) + { + $Inline = array( + 'extent' => strlen($matches[0][0]), + 'position' => $matches[0][1], + 'element' => array( + 'name' => 'a', + 'text' => $matches[0][0], + 'attributes' => array( + 'href' => $matches[0][0], + ), + ), + ); + + return $Inline; + } + } + + protected function inlineUrlTag($Excerpt) + { + if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) + { + $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]); + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $url, + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + # ~ + + protected function unmarkedText($text) + { + if ($this->breaksEnabled) + { + $text = preg_replace('/[ ]*\n/', "
    \n", $text); + } + else + { + $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
    \n", $text); + $text = str_replace(" \n", "\n", $text); + } + + return $text; + } + + # + # Handlers + # + + protected function element(array $Element) + { + $markup = '<'.$Element['name']; + + if (isset($Element['attributes'])) + { + foreach ($Element['attributes'] as $name => $value) + { + if ($value === null) + { + continue; + } + + $markup .= ' '.$name.'="'.$value.'"'; + } + } + + if (isset($Element['text'])) + { + $markup .= '>'; + + if (isset($Element['handler'])) + { + $markup .= $this->{$Element['handler']}($Element['text']); + } + else + { + $markup .= $Element['text']; + } + + $markup .= ''; + } + else + { + $markup .= ' />'; + } + + return $markup; + } + + protected function elements(array $Elements) + { + $markup = ''; + + foreach ($Elements as $Element) + { + $markup .= "\n" . $this->element($Element); + } + + $markup .= "\n"; + + return $markup; + } + + # ~ + + protected function li($lines) + { + $markup = $this->lines($lines); + + $trimmedMarkup = trim($markup); + + if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '

    ') + { + $markup = $trimmedMarkup; + $markup = substr($markup, 3); + + $position = strpos($markup, "

    "); + + $markup = substr_replace($markup, '', $position, 4); + } + + return $markup; + } + + # + # Deprecated Methods + # + + function parse($text) + { + $markup = $this->text($text); + + return $markup; + } + + # + # Static Methods + # + + static function instance($name = 'default') + { + if (isset(self::$instances[$name])) + { + return self::$instances[$name]; + } + + $instance = new static(); + + self::$instances[$name] = $instance; + + return $instance; + } + + private static $instances = array(); + + # + # Fields + # + + protected $DefinitionData; + + # + # Read-Only + + protected $specialCharacters = array( + '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|', + ); + + protected $StrongRegex = array( + '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', + '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us', + ); + + protected $EmRegex = array( + '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', + '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', + ); + + protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?'; + + protected $voidElements = array( + 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', + ); + + protected $textLevelElements = array( + 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', + 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', + 'i', 'rp', 'del', 'code', 'strike', 'marquee', + 'q', 'rt', 'ins', 'font', 'strong', + 's', 'tt', 'sub', 'mark', + 'u', 'xm', 'sup', 'nobr', + 'var', 'ruby', + 'wbr', 'span', + 'time', + ); +} diff --git a/htdocs/includes/parsedown/README.md b/htdocs/includes/parsedown/README.md new file mode 100644 index 00000000000..4e5659a4804 --- /dev/null +++ b/htdocs/includes/parsedown/README.md @@ -0,0 +1,56 @@ +> You might also like [Caret](http://caret.io?ref=parsedown) - our Markdown editor for Mac / Windows / Linux. + +## Parsedown + +[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown) + + +Better Markdown Parser in PHP + +[Demo](http://parsedown.org/demo) | +[Benchmarks](http://parsedown.org/speed) | +[Tests](http://parsedown.org/tests/) | +[Documentation](https://github.com/erusev/parsedown/wiki/) + +### Features + +* One File +* Super Fast +* Extensible +* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown) +* Tested in 5.3 to 7.1 and in HHVM +* [Markdown Extra extension](https://github.com/erusev/parsedown-extra) + +### Installation + +Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown). + +### Example + +``` php +$Parsedown = new Parsedown(); + +echo $Parsedown->text('Hello _Parsedown_!'); # prints:

    Hello Parsedown!

    +``` + +More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI). + +### Questions + +**How does Parsedown work?** + +It tries to read Markdown like a human. First, it looks at the lines. It’s interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line starts with a `-` then perhaps it belongs to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines). + +We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages. + +**Is it compliant with CommonMark?** + +It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve. + +**Who uses it?** + +[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [Herbie CMS](http://www.getherbie.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony demo](https://github.com/symfony/symfony-demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents). + +**How can I help?** + +Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2). diff --git a/htdocs/includes/parsedown/composer.json b/htdocs/includes/parsedown/composer.json new file mode 100644 index 00000000000..28145af68ca --- /dev/null +++ b/htdocs/includes/parsedown/composer.json @@ -0,0 +1,21 @@ +{ + "name": "erusev/parsedown", + "description": "Parser for Markdown.", + "keywords": ["markdown", "parser"], + "homepage": "http://parsedown.org", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-0": {"Parsedown": ""} + } +} diff --git a/htdocs/includes/parsedown/phpunit.xml.dist b/htdocs/includes/parsedown/phpunit.xml.dist new file mode 100644 index 00000000000..b2d5e9d4fe1 --- /dev/null +++ b/htdocs/includes/parsedown/phpunit.xml.dist @@ -0,0 +1,8 @@ + + + + + test/ParsedownTest.php + + + \ No newline at end of file diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index f5aa35f0c35..69881d693c6 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1131,6 +1131,7 @@ CompanyIdProfChecker=Rules on Professional Ids MustBeUnique=Must be unique? MustBeMandatory=Mandatory to create third parties? MustBeInvoiceMandatory=Mandatory to validate invoices? +TechnicalServicesProvided=Technical services provided ##### Webcal setup ##### WebCalUrlForVCalExport=An export link to %s format is available at following link: %s ##### Invoices ##### From b5e646daa0620ec92f0953730acdd2f4369dbd54 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 16:29:31 +0100 Subject: [PATCH 160/410] NEW Show by default README.md file found into root dir of ext module. --- htdocs/admin/modulehelp.php | 2 +- htdocs/core/lib/parsemd.lib.php | 18 ++++-- htdocs/core/modules/DolibarrModules.class.php | 58 ++++++++++++++++--- htdocs/theme/eldy/style.css.php | 7 +++ htdocs/theme/md/style.css.php | 7 +++ 5 files changed, 79 insertions(+), 13 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index e76627c2965..5b428443248 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -338,7 +338,7 @@ if ($mode == 'desc') $text.='
    '; $moduledesclong=$objMod->getDescLong(); - if ($moduledesclong) $text.='


    '.$moduledesclong.'
    '; + if ($moduledesclong) $text.='

    '.$moduledesclong.'
    '; } if ($mode == 'feature') diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php index 17e64f6543e..1eb962463c0 100644 --- a/htdocs/core/lib/parsemd.lib.php +++ b/htdocs/core/lib/parsemd.lib.php @@ -24,12 +24,22 @@ /** * Function to parse MD content into HTML * - * @param string $content MD content - * @param string $parser 'parsedown' or 'nl2br' - * @return string Parsed content + * @param string $content MD content + * @param string $parser 'parsedown' or 'nl2br' + * @param string $replaceimagepath Replace path to image with another path. Exemple: ('doc/'=>'xxx/aaa/') + * @return string Parsed content */ -function dolMd2Html($content, $parser='parsedown') +function dolMd2Html($content, $parser='parsedown',$replaceimagepath=null) { + if (is_array($replaceimagepath)) + { + foreach($replaceimagepath as $key => $val) + { + $keytoreplace = ']('.$key; + $valafter = ']('.$val; + $content = preg_replace('/'.preg_quote($keytoreplace,'/').'/m', $valafter, $content); + } + } if ($parser == 'parsedown') { include DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 84538801add..48ce35f1532 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -582,26 +582,68 @@ class DolibarrModules // Can not be abstract, because we need to insta } /** - * Gives the translated module description if translation exists in admin.lang or the default module description + * Gives the long description of a module. First check README-la_LA.md then README.md + * If not markdown files found, it return translated value of the key ->descriptionlong. * - * @return string Translated module description + * @return string Long description of a module */ function getDescLong() { global $langs; $langs->load("admin"); - if (empty($this->descriptionlong)) return ''; + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; + + $filefound= false; - // If module description translation does not exist using its unique id, we can use its name to find translation - if (is_array($this->langfiles)) + // Define path to file README.md. + // First check README-la_LA.md then README.md + $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0); + if (dol_is_file($pathoffile)) { - foreach($this->langfiles as $val) + $filefound = true; + } + if (! $filefound) + { + $pathoffile = dol_buildpath(strtolower($this->name).'/README.md', 0); + if (dol_is_file($pathoffile)) { - if ($val) $langs->load($val); + $filefound = true; } } - return $langs->trans($this->descriptionlong); + + if ($filefound) // Mostly for external modules + { + $content = file_get_contents($pathoffile); + + if ((float) DOL_VERSION >= 6.0) + { + @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; + $content = dolMd2Html($content, 'parsedown', array('doc/'=>dol_buildpath('cabinetmed/doc/', 1))); + } + else + { + $content = nl2br($content); + } + } + else // Mostly for internal modules + { + if (! empty($this->descriptionlong)) + { + if (is_array($this->langfiles)) + { + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } + } + + $content = $langs->trans($this->descriptionlong); + } + } + + return $content; } /** diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 3d6e8868bec..26a0c8d21ed 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -632,6 +632,13 @@ div.myavailability { margin-bottom: 12px; } +/* For the long description of module */ +.moduledesclong p img, .moduledesclong p a img { + max-width: 90% !important; + height: auto !important; +} + + /* DOL_XXX for future usage (when left menu has been removed). If we do not use datatable */ /*.table-responsive { width: calc(100% - 330px); diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index aae0fd7f677..c930b82dd8c 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -640,6 +640,13 @@ div.myavailability { margin-bottom: 12px; } +/* For the long description of module */ +.moduledesclong p img,.moduledesclong p a img { + max-width: 90% !important; + height: auto !important; +} + + /* DOL_XXX for future usage (when left menu has been removed). If we do not use datatable */ /*.table-responsive { width: calc(100% - 330px); From a0fe79a1132b329b744c7bd1b487d358beb9db4a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 16:46:12 +0100 Subject: [PATCH 161/410] Fix duplicate include. --- htdocs/core/lib/parsemd.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php index 1eb962463c0..13334fd400c 100644 --- a/htdocs/core/lib/parsemd.lib.php +++ b/htdocs/core/lib/parsemd.lib.php @@ -42,7 +42,7 @@ function dolMd2Html($content, $parser='parsedown',$replaceimagepath=null) } if ($parser == 'parsedown') { - include DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; + include_once DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; $Parsedown = new Parsedown(); $content = $Parsedown->text($content); } From 1e63b9873181cc0ad5907f0d03cbfb6df43f513f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:06:27 +0100 Subject: [PATCH 162/410] Fix responsive --- htdocs/core/boxes/box_produits.php | 10 +++++----- htdocs/core/boxes/box_produits_alerte_stock.php | 10 +++++----- htdocs/core/boxes/box_services_contracts.php | 2 +- htdocs/theme/eldy/style.css.php | 9 ++++++++- htdocs/theme/md/style.css.php | 8 +++++++- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 5cce3254bfb..51ee156fbeb 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -106,13 +106,13 @@ class box_produits extends ModeleBoxes $productstatic->entity = $objp->entity; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $productstatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', 'text' => $objp->label, ); @@ -144,7 +144,7 @@ class box_produits extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left" class="nowrap"', + 'td' => 'class="nowrap"', 'text' => $price_base_type, ); @@ -174,14 +174,14 @@ class box_produits extends ModeleBoxes $db->free($result); } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php index 3ec0fc7070c..884cf92b52a 100644 --- a/htdocs/core/boxes/box_produits_alerte_stock.php +++ b/htdocs/core/boxes/box_produits_alerte_stock.php @@ -113,13 +113,13 @@ class box_produits_alerte_stock extends ModeleBoxes $productstatic->entity = $objp->entity; $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $productstatic->getNomUrl(1), 'asis' => 1, ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left"', + 'td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', 'text' => $objp->label, ); @@ -153,7 +153,7 @@ class box_produits_alerte_stock extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'align="left" class="nowrap"', + 'td' => 'class="nowrap"', 'text' => $price_base_type, ); @@ -180,7 +180,7 @@ class box_produits_alerte_stock extends ModeleBoxes else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), ); @@ -188,7 +188,7 @@ class box_produits_alerte_stock extends ModeleBoxes } else { $this->info_box_contents[0][0] = array( - 'td' => 'align="left"', + 'td' => '', 'text' => $langs->trans("ReadPermissionNotAllowed"), ); } diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 752509a0616..4d7759ff081 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -135,7 +135,7 @@ class box_services_contracts extends ModeleBoxes 'asis' => 1 ); - $this->info_box_contents[$i][] = array('td' => '', + $this->info_box_contents[$i][] = array('td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', 'text' => $thirdpartytmp->getNomUrl(1), 'asis' => 1 ); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 7c699c31e7f..966493861c8 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2973,8 +2973,15 @@ div.tabBar .noborder { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - width: 110px; + width: 115px; } +@media only screen and (max-width: 767px) +{ + .boxstats { + width: 100px; + } +} + .boxstats:hover { box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.20); } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 4c5016268a8..c2d76f9d9d0 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2854,7 +2854,13 @@ div .tdtop { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - width: 110px; + width: 115px; +} +@media only screen and (max-width: 767px) +{ + .boxstats { + width: 100px; + } } .boxstats:hover { box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.20); From e7a45a7f6ad69e42b325d4cf514a2610edc23fc1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:50:43 +0100 Subject: [PATCH 163/410] NEW Use html5 type "number" on select field for year and duration. --- htdocs/core/class/html.form.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 0ec07e1c3fa..90c2a98720f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4735,7 +4735,7 @@ class Form // Year if ($emptydate || $set_time == -1) { - $retstring.=''; + $retstring.=''; } else { @@ -4918,7 +4918,7 @@ class Form } elseif ($typehour=='text') { - $retstring.=''; + $retstring.=''; } else return 'BadValueForParameterTypeHour'; @@ -4942,7 +4942,7 @@ class Form } elseif ($typehour=='text') { - $retstring.=''; + $retstring.=''; } if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); From b0a75da2ac62ca0fd34fd665d8c46ba4a0426bb8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:50:52 +0100 Subject: [PATCH 164/410] Fix css --- htdocs/expensereport/card.php | 59 +++++------------------------------ 1 file changed, 8 insertions(+), 51 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 6061250bfbd..4c28fe0281c 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1217,53 +1217,10 @@ if (empty($reshook)) } } - - /* - * Generate or regenerate the PDF document - */ - if ($action == 'builddoc') // GET or POST - { - $depl = new ExpenseReport($db, 0, $_GET['id']); - $depl->fetch($id); - - if ($_REQUEST['model']) - { - $depl->setDocModel($user, $_REQUEST['model']); - } - - $outputlangs = $langs; - if (! empty($_REQUEST['lang_id'])) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); - } - $result=expensereport_pdf_create($db, $depl, '', $depl->modelpdf, $outputlangs); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } - } - - // Remove file in doc form - else if ($action == 'remove_file') - { - $object = new ExpenseReport($db, 0, $_GET['id']); - if ($object->fetch($id)) - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $object->fetch_thirdparty(); - - $langs->load("other"); - $upload_dir = $conf->expensereport->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); - else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); - $action=''; - } - } + // Actions to build doc + $upload_dir = $conf->expensereport->dir_output; + $permissioncreate = $user->rights->expensereport->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -1352,8 +1309,8 @@ if ($action == 'create') // Public note print '
    ' . $langs->trans('NotePublic') . ''; + print '' . $langs->trans('NotePublic') . ''; $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); @@ -1362,8 +1319,8 @@ if ($action == 'create') // Private note if (empty($user->societe_id)) { print '
    ' . $langs->trans('NotePrivate') . ''; + print '' . $langs->trans('NotePrivate') . ''; $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); From 559232a4d726cb70fe296a7bae6df966c563d9d2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:56:11 +0100 Subject: [PATCH 165/410] bottom-border useless --- htdocs/expensereport/card.php | 6 +++--- htdocs/expensereport/document.php | 2 +- htdocs/expensereport/info.php | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 4c28fe0281c..8ec9d9140cb 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1272,8 +1272,8 @@ if ($action == 'create') print ''; $defaultselectuser=$user->id; if (GETPOST('fk_user_author') > 0) $defaultselectuser=GETPOST('fk_user_author'); - $include_users = 'hierarchyme'; - if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); + $include_users = 'hierarchyme'; + if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); $s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users); print $s; print ''; $defaultselectuser=$user->id; if (GETPOST('fk_user_author') > 0) $defaultselectuser=GETPOST('fk_user_author'); - $include_users = 'hierarchyme'; - if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); + $include_users = 'hierarchyme'; + if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); $s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users); print $s; print '
    '; - - // Ref - print '"; - - print "
    '.$langs->trans("Ref").''; - print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref'); - print "
    "; - - print '
    '; - */ print '
    '; print '
    '; @@ -111,7 +97,6 @@ if ($id > 0 || ! empty($ref)) print '
    '; dol_fiche_end(); - } From acdfd6ab9edc33cb8299b9bb853786afe110b54a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 18:23:58 +0100 Subject: [PATCH 168/410] css enhancement --- htdocs/core/class/html.form.class.php | 6 +++--- htdocs/expensereport/card.php | 14 +++++++------- htdocs/theme/eldy/style.css.php | 17 +++++++++++------ htdocs/theme/md/style.css.php | 17 +++++++++++------ 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 90c2a98720f..c5118ec56ef 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4528,7 +4528,7 @@ class Form $disabled=true; } - if (! $options_only) $return.= ''; $selectedfound=false; foreach ($this->cache_vatrates as $rate) @@ -4717,7 +4717,7 @@ class Form $retstring.=""; - $retstring.=''; + $retstring.=''; if ($emptydate || $set_time == -1) { $retstring.=''; @@ -4739,7 +4739,7 @@ class Form } else { - $retstring.=''; + $retstring.=''; for ($year = $syear - 5; $year < $syear + 10 ; $year++) { diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 8ec9d9140cb..fa6018fcd07 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1959,7 +1959,7 @@ else print ''; // Select date - print ''; + print ''; $form->select_date($objp->date,'date'); print ''; @@ -1972,13 +1972,13 @@ else } // Select type - print ''; + print ''; select_type_fees_id($objp->type_fees_code,'fk_c_type_fees'); print ''; // Add comments print ''; - print ''; + print ''; print ''; // VAT @@ -1988,12 +1988,12 @@ else // Unit price print ''; - print ''; + print ''; print ''; // Quantity print ''; - print ''; + print ''; print ''; if ($action != 'editline') @@ -2074,12 +2074,12 @@ else // Unit price print ''; - print ''; + print ''; print ''; // Quantity print ''; - print ''; + print ''; print ''; if ($action != 'editline') diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 26a0c8d21ed..086e78f3552 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -693,6 +693,7 @@ div.fiche>form>div.div-table-responsive { .minwidth400 { min-width: 400px; } .minwidth500 { min-width: 500px; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -709,6 +710,7 @@ div.fiche>form>div.div-table-responsive { .maxwidth400 { max-width: 400px; } .maxwidth500 { max-width: 500px; } .maxwidth50imp { max-width: 50px !important; } +.maxwidth75imp { max-width: 75px !important; } .minheight20 { min-height: 20px; } .minheight40 { min-height: 40px; } .titlefieldcreate { width: 20%; } @@ -722,6 +724,7 @@ div.fiche>form>div.div-table-responsive { .titlefield { width: 30% !important; } .titlefieldcreate { width: 30% !important; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -734,7 +737,8 @@ div.fiche>form>div.div-table-responsive { { .maxwidthonsmartphone { max-width: 100px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } + .minwidth75imp { min-width: 70px !important; } + .minwidth100imp { min-width: 80px !important; } .minwidth200imp { min-width: 100px !important; } .minwidth300imp { min-width: 100px !important; } .minwidth400imp { min-width: 100px !important; } @@ -785,11 +789,12 @@ div.fiche>form>div.div-table-responsive { .maxwidth300onsmartphone { max-width: 300px; } .maxwidth400onsmartphone { max-width: 400px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } - .minwidth200imp { min-width: 50px !important; } - .minwidth300imp { min-width: 50px !important; } - .minwidth400imp { min-width: 50px !important; } - .minwidth500imp { min-width: 50px !important; } + .minwidth75imp { min-width: 60px !important; } + .minwidth100imp { min-width: 60px !important; } + .minwidth200imp { min-width: 60px !important; } + .minwidth300imp { min-width: 60px !important; } + .minwidth400imp { min-width: 60px !important; } + .minwidth500imp { min-width: 60px !important; } .titlefield { width: auto; } .titlefieldcreate { width: auto; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c930b82dd8c..e90311ca0d2 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -702,6 +702,7 @@ div.fiche>form>div.div-table-responsive { .minwidth400 { min-width: 400px; } .minwidth500 { min-width: 500px; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -718,6 +719,7 @@ div.fiche>form>div.div-table-responsive { .maxwidth400 { max-width: 400px; } .maxwidth500 { max-width: 500px; } .maxwidth50imp { max-width: 50px !important; } +.maxwidth75imp { max-width: 75px !important; } .minheight20 { min-height: 20px; } .minheight40 { min-height: 40px; } .titlefieldcreate { width: 20%; } @@ -732,6 +734,7 @@ div.fiche>form>div.div-table-responsive { .titlefield { width: 30% !important; } .titlefieldcreate { width: 30% !important; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -744,7 +747,8 @@ div.fiche>form>div.div-table-responsive { { .maxwidthonsmartphone { max-width: 100px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } + .minwidth75imp { min-width: 70px !important; } + .minwidth100imp { min-width: 80px !important; } .minwidth200imp { min-width: 100px !important; } .minwidth300imp { min-width: 100px !important; } .minwidth400imp { min-width: 100px !important; } @@ -794,11 +798,12 @@ div.fiche>form>div.div-table-responsive { .maxwidth300onsmartphone { max-width: 300px; } .maxwidth400onsmartphone { max-width: 400px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } - .minwidth200imp { min-width: 50px !important; } - .minwidth300imp { min-width: 50px !important; } - .minwidth400imp { min-width: 50px !important; } - .minwidth500imp { min-width: 50px !important; } + .minwidth75imp { min-width: 60px !important; } + .minwidth100imp { min-width: 60px !important; } + .minwidth200imp { min-width: 60px !important; } + .minwidth300imp { min-width: 60px !important; } + .minwidth400imp { min-width: 60px !important; } + .minwidth500imp { min-width: 60px !important; } .titlefield { width: auto; } .titlefieldcreate { width: auto; } From 61031f1633807a5a3397496f12109bab332fd15d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 19:10:43 +0100 Subject: [PATCH 169/410] FIX Missing total on project overview. --- htdocs/projet/element.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 80cc6b11539..0e83fbe26a1 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -956,7 +956,7 @@ foreach ($listofreferent as $key => $value) print ''; if (empty($value['disableamount'])) { - if (! empty($conf->salaries->enabled)) print ''.$langs->trans("TotalHT").' : '.price($total_ht); + if ($tablename != 'projet_task' || ! empty($conf->salaries->enabled)) print ''.$langs->trans("TotalHT").' : '.price($total_ht); } print ''; //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print ''.$langs->trans("TotalTTC").' : '.price($total_ttc).''; @@ -964,8 +964,7 @@ foreach ($listofreferent as $key => $value) print ''; if (empty($value['disableamount'])) { - - if (! empty($conf->salaries->enabled)) print $langs->trans("TotalTTC").' : '.price($total_ttc); + if ($tablename != 'projet_task' || ! empty($conf->salaries->enabled)) print $langs->trans("TotalTTC").' : '.price($total_ttc); } print ''; print ' '; From 7999cb9a46c31dd85e5782d6cc8566ff136ec39d Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Tue, 21 Mar 2017 23:48:06 +0100 Subject: [PATCH 170/410] introducing "mixte" mode for select_duration If 'select' then input hour and input min is a combo, if 'text' input hour is in text and input min is a text, if 'mixte' input hour is in text and input min is a combo --- htdocs/core/class/html.form.class.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c5118ec56ef..4202c27f744 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4878,11 +4878,13 @@ class Form * Function to show a form to select a duration on a page * * @param string $prefix Prefix for input fields - * @param int $iSecond Default preselected duration (number of seconds or '') - * @param int $disabled Disable the combo box - * @param string $typehour If 'select' then input hour and input min is a combo, if 'text' input hour is in text and input min is a text - * @param integer $minunderhours If 1, show minutes selection under the hours - * @param int $nooutput Do not output html string but return it + * @param int $iSecond Default preselected duration (number of seconds or '') + * @param int $disabled Disable the combo box + * @param string $typehour If 'select' then input hour and input min is a combo, + * if 'text' input hour is in text and input min is a text, + * if 'mixte' input hour is in text and input min is a combo + * @param integer $minunderhours If 1, show minutes selection under the hours + * @param int $nooutput Do not output html string but return it * @return string|null */ function select_duration($prefix, $iSecond='', $disabled=0, $typehour='select', $minunderhours=0, $nooutput=0) @@ -4902,7 +4904,7 @@ class Form $minSelected = convertSecondToTime($iSecond,'min'); } - if ($typehour=='select') + if ($typehour=='select' ) { $retstring.='"; } - elseif ($typehour=='text') + elseif ($typehour=='text' || $typehour=='mixte') { $retstring.=''; } @@ -4929,7 +4931,7 @@ class Form if ($minunderhours) $retstring.='
    '; else $retstring.=" "; - if ($typehour=='select') + if ($typehour=='select' || $typehour=='mixte') { $retstring.='"; } - elseif ($typehour=='text') + elseif ($typehour=='text' ) { $retstring.=''; } From 6cecab4c920b51c29758e35869536fd328a8f5a0 Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 22 Mar 2017 16:43:12 +0100 Subject: [PATCH 171/410] FIX : forgottent fk_unit field on llx_supplier_propaldet --- .../install/mysql/migration/4.0.0-5.0.0.sql | 1 + .../mysql/tables/llx_supplier_proposaldet.sql | 3 +- htdocs/supplier_proposal/card.php | 10 +++--- .../class/supplier_proposal.class.php | 33 ++++++++++++------- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql index 05d059d2bf5..81191e7a84e 100644 --- a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql +++ b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql @@ -166,6 +166,7 @@ ALTER TABLE llx_commandedet ADD COLUMN vat_src_code varchar(10) DEFAULT '' AFTER ALTER TABLE llx_commande_fournisseurdet ADD COLUMN vat_src_code varchar(10) DEFAULT '' AFTER tva_tx; ALTER TABLE llx_propaldet ADD COLUMN vat_src_code varchar(10) DEFAULT '' AFTER tva_tx; ALTER TABLE llx_supplier_proposaldet ADD COLUMN vat_src_code varchar(10) DEFAULT '' AFTER tva_tx; +ALTER TABLE llx_supplier_proposaldet ADD COLUMN fk_unit integer DEFAULT NULL; ALTER TABLE llx_contratdet ADD COLUMN vat_src_code varchar(10) DEFAULT '' AFTER tva_tx; ALTER TABLE llx_c_payment_term change fdm type_cdr tinyint; diff --git a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql index f94df8f2e74..ebe44b0f702 100644 --- a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql +++ b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql @@ -51,5 +51,6 @@ CREATE TABLE llx_supplier_proposaldet ( multicurrency_subprice double(24,8) DEFAULT 0, multicurrency_total_ht double(24,8) DEFAULT 0, multicurrency_total_tva double(24,8) DEFAULT 0, - multicurrency_total_ttc double(24,8) DEFAULT 0 + multicurrency_total_ttc double(24,8) DEFAULT 0, + fk_unit integer DEFAULT NULL -- lien vers table des unités ) ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index e02a512f327..aadec9726f8 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -354,7 +354,7 @@ if (empty($reshook)) $array_options = $lines[$i]->array_options; } - $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_options); + $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_options, $lines[$i]->ref_fourn, $lines[$i]->fk_unit); if ($result > 0) { $lineid = $result; @@ -633,7 +633,8 @@ if (empty($reshook)) $buyingprice, $label, $array_options, - $ref_fourn + $ref_fourn, + $fk_unit ); //var_dump($tva_tx);var_dump($productsupplier->fourn_pu);var_dump($price_base_type);exit; } @@ -683,7 +684,7 @@ if (empty($reshook)) $price_base_type = 'HT'; } - $result = $object->addline($desc, $ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $ref_fourn); + $result = $object->addline($desc, $ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $ref_fourn, $fk_unit); //$result = $object->addline($desc, $ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', $remise_percent, $price_base_type, $ttc, $type,'','', $date_start, $date_end, $array_options, $fk_unit); } @@ -826,7 +827,8 @@ if (empty($reshook)) if (! $error) { $db->begin(); $ref_fourn = GETPOST('fourn_ref'); - $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $array_options, $ref_fourn); + $fk_unit = GETPOST('units'); + $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $array_options, $ref_fourn, $fk_unit); if ($result >= 0) { $db->commit(); diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index d666f421cdb..3d7c9a033cb 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -359,7 +359,7 @@ class SupplierProposal extends CommonObject * * @see add_product */ - function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$array_option=0, $ref_fourn='') + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$array_option=0, $ref_fourn='', $fk_unit='') { global $mysoc; @@ -460,6 +460,7 @@ class SupplierProposal extends CommonObject $this->line->product_type=$type; $this->line->special_code=$special_code; $this->line->fk_parent_line=$fk_parent_line; + $this->line->fk_unit=$fk_unit; $this->line->ref_fourn = $this->db->escape($ref_fourn); @@ -548,7 +549,7 @@ class SupplierProposal extends CommonObject * @param string $ref_fourn Supplier price reference * @return int 0 if OK, <0 if KO */ - function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $array_option=0, $ref_fourn='') + function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $array_option=0, $ref_fourn='', $fk_unit='') { global $conf,$user,$langs, $mysoc; @@ -634,7 +635,8 @@ class SupplierProposal extends CommonObject $this->line->special_code = $special_code; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; - $this->line->ref_fourn = $ref_fourn; + $this->line->ref_fourn = $ref_fourn; + $this->line->fk_unit = $fk_unit; // infos marge if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { @@ -1195,7 +1197,7 @@ class SupplierProposal extends CommonObject $sql.= " d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,"; $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,'; $sql.= ' d.ref_fourn as ref_produit_fourn,'; - $sql.= ' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc'; + $sql.= ' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc, d.fk_unit'; $sql.= " FROM ".MAIN_DB_PREFIX."supplier_proposaldet as d"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid"; $sql.= " WHERE d.fk_supplier_proposal = ".$this->id; @@ -1261,6 +1263,7 @@ class SupplierProposal extends CommonObject $line->multicurrency_total_ht = $objp->multicurrency_total_ht; $line->multicurrency_total_tva = $objp->multicurrency_total_tva; $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc; + $line->fk_unit = $objp->fk_unit; $this->lines[$i] = $line; @@ -2429,7 +2432,7 @@ class SupplierProposal extends CommonObject $sql.= ' pt.product_type, pt.rang, pt.fk_parent_line,'; $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,'; $sql.= ' p.description as product_desc, pt.ref_fourn as ref_produit_fourn'; - $sql.= ' ,pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc'; + $sql.= ' ,pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc, pt.fk_unit'; $sql.= ' FROM '.MAIN_DB_PREFIX.'supplier_proposaldet as pt'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pt.fk_product=p.rowid'; $sql.= ' WHERE pt.fk_supplier_proposal = '.$this->id; @@ -2484,6 +2487,7 @@ class SupplierProposal extends CommonObject $this->lines[$i]->multicurrency_total_ht = $obj->multicurrency_total_ht; $this->lines[$i]->multicurrency_total_tva = $obj->multicurrency_total_tva; $this->lines[$i]->multicurrency_total_ttc = $obj->multicurrency_total_ttc; + $this->lines[$i]->fk_unit = $obj->fk_unit; $i++; } @@ -2557,7 +2561,7 @@ class SupplierProposal extends CommonObject * \class SupplierProposalLine * \brief Class to manage supplier_proposal lines */ -class SupplierProposalLine extends CommonObject +class SupplierProposalLine extends CommonObjectLine { var $db; var $error; @@ -2693,7 +2697,7 @@ class SupplierProposalLine extends CommonObject $sql.= ' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,'; $sql.= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; $sql.= ' pd.product_type, pd.ref_fourn as ref_produit_fourn,'; - $sql.= ' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc'; + $sql.= ' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc, pd.fk_unit'; $sql.= ' FROM '.MAIN_DB_PREFIX.'supplier_proposaldet as pd'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pd.fk_product = p.rowid'; $sql.= ' WHERE pd.rowid = '.$rowid; @@ -2749,6 +2753,7 @@ class SupplierProposalLine extends CommonObject $this->multicurrency_total_ht = $objp->multicurrency_total_ht; $this->multicurrency_total_tva = $objp->multicurrency_total_tva; $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; + $this->fk_unit = $objp->fk_unit; $this->db->free($result); } @@ -2787,7 +2792,8 @@ class SupplierProposalLine extends CommonObject if (empty($this->special_code)) $this->special_code=0; if (empty($this->fk_parent_line)) $this->fk_parent_line=0; if (empty($this->fk_fournprice)) $this->fk_fournprice=0; - + if (empty($this->fk_unit)) $this->fk_unit=0; + if (empty($this->pa_ht)) $this->pa_ht=0; // if buy price not defined, define buyprice as configured in margin admin @@ -2816,7 +2822,7 @@ class SupplierProposalLine extends CommonObject $sql.= ' info_bits, '; $sql.= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,'; $sql.= ' ref_fourn'; - $sql.= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)'; + $sql.= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc, fk_unit)'; $sql.= " VALUES (".$this->fk_supplier_proposal.","; $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").","; $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; @@ -2849,7 +2855,8 @@ class SupplierProposalLine extends CommonObject $sql.= ", ".$this->multicurrency_total_ht; $sql.= ", ".$this->multicurrency_total_tva; $sql.= ", ".$this->multicurrency_total_ttc; - $sql.= ')'; + $sql.= ", ".$this->fk_unit; + $sql.= ')'; dol_syslog(get_class($this).'::insert', LOG_DEBUG); $resql=$this->db->query($sql); @@ -2969,7 +2976,8 @@ class SupplierProposalLine extends CommonObject if (empty($this->special_code)) $this->special_code=0; if (empty($this->fk_parent_line)) $this->fk_parent_line=0; if (empty($this->fk_fournprice)) $this->fk_fournprice=0; - + if (empty($this->fk_unit)) $this->fk_unit=0; + if (empty($this->pa_ht)) $this->pa_ht=0; // if buy price not defined, define buyprice as configured in margin admin @@ -3023,8 +3031,9 @@ class SupplierProposalLine extends CommonObject $sql.= " , multicurrency_total_ht=".price2num($this->multicurrency_total_ht).""; $sql.= " , multicurrency_total_tva=".price2num($this->multicurrency_total_tva).""; $sql.= " , multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc).""; + $sql.= " , fk_unit=".$this->fk_unit; - $sql.= " WHERE rowid = ".$this->rowid; + $sql.= " WHERE rowid = ".$this->rowid; dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql=$this->db->query($sql); From 8199ac9f89600273b91fe20a118b466c0f1d3381 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 22 Mar 2017 19:49:58 +0100 Subject: [PATCH 172/410] FIX Can't download delivery receipts (function dol_check_secure_access_document) --- htdocs/core/lib/files.lib.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 59e5a3426a2..586622538e9 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1725,9 +1725,8 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } $original_file=$conf->expedition->dir_output."/sending/".$original_file; } - // Wrapping pour les bons de livraison - else if ($modulepart == 'livraison' && !empty($conf->livraison->dir_output)) + if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) { if ($fuser->rights->expedition->livraison->lire || preg_match('/^specimen/i',$original_file)) { From 917ef1e01e0f98e3914d9a9d1c1c04bacee3e44e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 22 Mar 2017 20:34:01 +0100 Subject: [PATCH 173/410] Uniformize code --- htdocs/admin/confexped.php | 26 +++----- htdocs/admin/expedition.php | 75 +++++++++------------- htdocs/admin/expedition_extrafields.php | 2 +- htdocs/admin/expeditiondet_extrafields.php | 2 +- htdocs/admin/livraison.php | 6 +- htdocs/admin/livraison_extrafields.php | 2 +- htdocs/admin/livraisondet_extrafields.php | 2 +- 7 files changed, 46 insertions(+), 69 deletions(-) diff --git a/htdocs/admin/confexped.php b/htdocs/admin/confexped.php index 859534d53fd..0059f337752 100644 --- a/htdocs/admin/confexped.php +++ b/htdocs/admin/confexped.php @@ -94,28 +94,23 @@ print load_fiche_titre($langs->trans("SendingsSetup"),$linkback,'title_setup'); print '
    '; $head = expedition_admin_prepare_head(); -dol_fiche_head($head, 'general', $langs->trans("Sendings"), 0, 'sending'); +dol_fiche_head($head, 'general', $langs->trans("Sendings"), -1, 'sending'); -/* - * Formulaire parametres divers - */ - -$var=true; +// Miscellaneous parameters print ''; print ''; print ''; -print ''; -print ''; +print ''; +print ''; print ''."\n"; // expedition activation/desactivation -$var=!$var; -print ""; +print ""; print ''; -print ''; -print '"; print ''; // Bon de livraison activation/desactivation -$var=!$var; -print ''; +print ''; print ''; -print ''; -print ''; print ''; print ''; print ''; -print ''; -print ''; +print ''; +print ''; print "\n"; clearstatcache(); @@ -250,8 +250,6 @@ foreach ($dirmodels as $reldir) $handle = opendir($dir); if (is_resource($handle)) { - $var=true; - while (($file = readdir($handle))!==false) { if (substr($file, 0, 15) == 'mod_expedition_' && substr($file, dol_strlen($file)-3, 3) == 'php') @@ -268,8 +266,7 @@ foreach ($dirmodels as $reldir) if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; - $var=!$var; - print '\n"; + print '\n"; print ''; @@ -374,7 +371,6 @@ print "\n"; clearstatcache(); -$var=true; foreach ($dirmodels as $reldir) { foreach (array('','/doc') as $valdir) @@ -412,8 +408,7 @@ foreach ($dirmodels as $reldir) if ($modulequalified) { - $var = !$var; - print ''; print ''; From 0a35d172079da39f1c303c8f2fc0ff98c8e8c0b9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 10:59:13 +0100 Subject: [PATCH 175/410] CSS enhancement --- htdocs/admin/events.php | 2 +- htdocs/admin/perms.php | 2 +- htdocs/admin/proxy.php | 2 +- htdocs/admin/security.php | 2 +- htdocs/admin/security_file.php | 2 +- htdocs/admin/security_other.php | 2 +- htdocs/admin/translation.php | 2 +- htdocs/core/class/html.form.class.php | 4 +- htdocs/core/lib/functions.lib.php | 2 +- htdocs/holiday/card.php | 10 +- htdocs/theme/eldy/style.css.php | 18 +++- htdocs/theme/md/style.css.php | 23 +++-- htdocs/user/class/user.class.php | 132 +++++++++++++------------- htdocs/user/hierarchy.php | 3 +- htdocs/user/home.php | 11 +-- htdocs/user/index.php | 12 +-- 16 files changed, 128 insertions(+), 101 deletions(-) diff --git a/htdocs/admin/events.php b/htdocs/admin/events.php index 6092a95d0b9..892e0860cbd 100644 --- a/htdocs/admin/events.php +++ b/htdocs/admin/events.php @@ -86,7 +86,7 @@ print ''; $head=security_prepare_head(); -dol_fiche_head($head, 'audit', $langs->trans("Security")); +dol_fiche_head($head, 'audit', $langs->trans("Security"), -1); $var=true; diff --git a/htdocs/admin/perms.php b/htdocs/admin/perms.php index 4302222630c..84cb9ed8bf2 100644 --- a/htdocs/admin/perms.php +++ b/htdocs/admin/perms.php @@ -118,7 +118,7 @@ $db->commit(); $head=security_prepare_head(); -dol_fiche_head($head, 'default', $langs->trans("Security")); +dol_fiche_head($head, 'default', $langs->trans("Security"), -1); // Show warning about external users diff --git a/htdocs/admin/proxy.php b/htdocs/admin/proxy.php index 1f6e45223b4..84836407499 100644 --- a/htdocs/admin/proxy.php +++ b/htdocs/admin/proxy.php @@ -96,7 +96,7 @@ print ''; $head=security_prepare_head(); -dol_fiche_head($head, 'proxy', $langs->trans("Security")); +dol_fiche_head($head, 'proxy', $langs->trans("Security"), -1); if ($conf->use_javascript_ajax) diff --git a/htdocs/admin/security.php b/htdocs/admin/security.php index 97cae20377c..3aa0bdf33bf 100644 --- a/htdocs/admin/security.php +++ b/htdocs/admin/security.php @@ -198,7 +198,7 @@ print "
    \n"; $head=security_prepare_head(); -dol_fiche_head($head, 'passwords', $langs->trans("Security")); +dol_fiche_head($head, 'passwords', $langs->trans("Security"), -1); $var=false; diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php index f7a776c7249..0114bbb74b8 100644 --- a/htdocs/admin/security_file.php +++ b/htdocs/admin/security_file.php @@ -124,7 +124,7 @@ print ''; $head=security_prepare_head(); -dol_fiche_head($head, 'file', $langs->trans("Security")); +dol_fiche_head($head, 'file', $langs->trans("Security"), -1); // Upload options diff --git a/htdocs/admin/security_other.php b/htdocs/admin/security_other.php index ac0a1e883eb..9ce79359a7c 100644 --- a/htdocs/admin/security_other.php +++ b/htdocs/admin/security_other.php @@ -103,7 +103,7 @@ print ''; $head=security_prepare_head(); -dol_fiche_head($head, 'misc', $langs->trans("Security")); +dol_fiche_head($head, 'misc', $langs->trans("Security"), -1); // Other Options diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index 7d07f7ead94..4dbfc53c821 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -181,7 +181,7 @@ print ''; $head=translation_prepare_head(); -dol_fiche_head($head, $mode, '', 0, ''); +dol_fiche_head($head, $mode, '', -1, ''); if ($mode == 'overwrite') { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 1366435f144..1256732999a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5998,7 +5998,7 @@ class Form if ($urladvanced) $ret.=''; else $ret.=''; } - $ret.='Photo'; + $ret.='Photo'; if ($addlinktofullsize) $ret.=''; } else if ($altfile && file_exists($dir."/".$altfile)) @@ -6009,7 +6009,7 @@ class Form if ($urladvanced) $ret.=''; else $ret.=''; } - $ret.='Photo alt'; + $ret.='Photo alt'; if ($addlinktofullsize) $ret.=''; } else diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 3851a173c24..4ca49934bcd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2378,7 +2378,7 @@ function img_picto($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $ if (preg_match('/:[^\s0-9]/',$titlealt)) $tmparray=explode(':',$titlealt); // We explode if we have TextA:TextB. Not if we have TextA: TextB $title=$tmparray[0]; $alt=empty($tmparray[1])?'':$tmparray[1]; - return ''.dol_escape_htmltag($alt).''; // Alt is used for accessibility, title for popup + return ''.dol_escape_htmltag($alt).''; // Alt is used for accessibility, title for popup } } diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 6583ad09b61..bd520676f75 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -828,7 +828,10 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create // Date start print '
    '; - print ''; + print ''; print ''; - print ''; + print ''; print '\n"; $user2=new User($db); -$var=True; $i = 0; while ($i < min($num,$limit)) { $obj = $db->fetch_object($result); - $var=!$var; $userstatic->id=$obj->rowid; $userstatic->ref=$obj->label; @@ -482,18 +480,18 @@ while ($i < min($num,$limit)) $li=$userstatic->getNomUrl(-1,'',0,0,24,1,'login'); - print ""; + print ""; if (! empty($arrayfields['u.login']['checked'])) { print ''; } @@ -584,11 +582,11 @@ while ($i < min($num,$limit)) print $user2->getNomUrl(-1,'',0,0,24,0,''); if (! empty($conf->multicompany->enabled) && $obj->admin2 && ! $obj->entity2) { - print img_picto($langs->trans("SuperAdministrator"),'redstar'); + print img_picto($langs->trans("SuperAdministrator"), 'redstar', 'class="valignmiddle paddingleft"'); } else if ($obj->admin2) { - print img_picto($langs->trans("Administrator"),'star'); + print img_picto($langs->trans("Administrator"), 'star', 'class="valignmiddle paddingleft"'); } } print ''; From 996cb9d3f17f23ca0b2bb81868ced4f0cda3a2cd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 11:16:30 +0100 Subject: [PATCH 176/410] NEW Add function ajax_autoselect --- htdocs/core/lib/ajax.lib.php | 19 +++++++++++++++++++ htdocs/opensurvey/card.php | 14 ++------------ htdocs/paypal/lib/paypal.lib.php | 3 ++- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 68e3f079361..c16453b73b4 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -347,6 +347,25 @@ function ajax_dialog($title,$message,$w=350,$h=150) return $msg; } + +/** + * Make a input box content all selected + * + * @param string $htmlname Id of html object + * @param int $addlink Add a link to after + */ +function ajax_autoselect($htmlname, $addlink=0) +{ + global $langs; + $out = ''; + if ($addlink) $out.=' '.$langs->trans("Link").''; + return $out; +} + /** * Convert a html select field into an ajax combobox. * Use ajax_combobox() only for small combo list! If not, use instead ajax_autocompleter(). diff --git a/htdocs/opensurvey/card.php b/htdocs/opensurvey/card.php index 133f1554b49..bb4d4650344 100644 --- a/htdocs/opensurvey/card.php +++ b/htdocs/opensurvey/card.php @@ -338,18 +338,8 @@ $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current $url=$urlwithouturlroot.dol_buildpath('/public/opensurvey/studs.php',1).'?sondage='.$object->id_sondage; -$urllink=''; -print $urllink; -if ($action != 'edit') -{ - print ''; - print ' '.$langs->trans("Link").''; - -} +print ''; +if ($action != 'edit') print ajax_autoselect("opensurveyurl", 1); print ''; diff --git a/htdocs/paypal/lib/paypal.lib.php b/htdocs/paypal/lib/paypal.lib.php index 1496bb3552e..4c1cb588f1f 100644 --- a/htdocs/paypal/lib/paypal.lib.php +++ b/htdocs/paypal/lib/paypal.lib.php @@ -209,7 +209,8 @@ function showPaypalPaymentUrl($type,$ref) $out='

    '; $out.=img_picto('','object_globe.png').' '.$langs->trans("ToOfferALinkForOnlinePayment",$servicename).'
    '; $url=getPaypalPaymentUrl(0,$type,$ref); - $out.='
    '; + $out.=''; + $out.=ajax_autoselect("paypalurl", 0); return $out; } From 0730f84cf64042366c29385caba76da7b081be28 Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 23 Mar 2017 12:14:09 +0100 Subject: [PATCH 177/410] FIX : param php doc --- htdocs/supplier_proposal/class/supplier_proposal.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 3d7c9a033cb..85bba0ad6e6 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -355,6 +355,7 @@ class SupplierProposal extends CommonObject * @param string $label ??? * @param array $array_option extrafields array * @param string $ref_fourn Supplier price reference + * @param int $fk_unit Id of the unit to use. * @return int >0 if OK, <0 if KO * * @see add_product @@ -547,6 +548,7 @@ class SupplierProposal extends CommonObject * @param int $type 0/1=Product/service * @param array $array_option extrafields array * @param string $ref_fourn Supplier price reference + * @param int $fk_unit Id of the unit to use. * @return int 0 if OK, <0 if KO */ function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $array_option=0, $ref_fourn='', $fk_unit='') From a790ef9f7c334368219c0264c81de6ebd07f45f6 Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 23 Mar 2017 12:35:43 +0100 Subject: [PATCH 178/410] FIX : origin & origin id on supplier order line --- htdocs/fourn/class/fournisseur.commande.class.php | 7 +++++-- htdocs/fourn/commande/card.php | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 8d45b11beb3..e68fbd36a94 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1340,9 +1340,11 @@ class CommandeFournisseur extends CommonOrder * @param array $array_options extrafields array * @param string $fk_unit Code of the unit to use. Null to use the default one * @param string $pu_ht_devise Amount in currency + * @param string $origin 'order', ... + * @param int $origin_id Id of origin object * @return int <=0 if KO, >0 if OK */ - public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $fk_prod_fourn_price=0, $fourn_ref='', $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $type=0, $info_bits=0, $notrigger=false, $date_start=null, $date_end=null, $array_options=0, $fk_unit=null, $pu_ht_devise=0) + public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $fk_prod_fourn_price=0, $fourn_ref='', $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $type=0, $info_bits=0, $notrigger=false, $date_start=null, $date_end=null, $array_options=0, $fk_unit=null, $pu_ht_devise=0, $origin='', $origin_id=0) { global $langs,$mysoc,$conf; @@ -1511,7 +1513,8 @@ class CommandeFournisseur extends CommonOrder $this->line->total_ttc=$total_ttc; $this->line->product_type=$type; $this->line->special_code=$this->special_code; - $this->line->origin=$this->origin; + $this->line->origin=$origin; + $this->line->origin_id=$origin_id; $this->line->fk_unit=$fk_unit; $this->line->date_start=$date_start; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index fb6bc840354..f891ed11a90 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1068,7 +1068,10 @@ if (empty($reshook)) null, null, array(), - $lines[$i]->fk_unit + $lines[$i]->fk_unit, + 0, + $element, + !empty($lines[$i]->id) ? $lines[$i]->id : $lines[$i]->rowid ); } From 7df9c25e60e8f586f7f9e3839638eef5ec67b9fa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 12:23:32 +0100 Subject: [PATCH 179/410] Several fixes on multicurrency --- htdocs/comm/propal/card.php | 15 +++++++-- htdocs/commande/card.php | 4 +-- htdocs/compta/facture.php | 4 +-- .../modules/propale/doc/pdf_azur.modules.php | 1 + .../pdf/pdf_canelle.modules.php | 3 +- .../pdf/pdf_muscadet.modules.php | 5 +-- .../doc/pdf_aurore.modules.php | 6 ++-- .../class/fournisseur.commande.class.php | 4 +-- htdocs/fourn/commande/card.php | 4 +-- htdocs/fourn/facture/card.php | 19 +++++------ htdocs/supplier_proposal/card.php | 33 ++++++++++++++++--- 11 files changed, 66 insertions(+), 32 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 99ff663689e..8c1c579b0c2 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1301,8 +1301,18 @@ if ($action == 'create') // Replicate extrafields $objectsrc->fetch_optionals($originid); $object->array_options = $objectsrc->array_options; + + if (!empty($conf->multicurrency->enabled)) + { + if (!empty($objectsrc->multicurrency_code)) $currency_code = $objectsrc->multicurrency_code; + if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx)) $currency_tx = $objectsrc->multicurrency_tx; + } } } + else + { + if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; + } $object = new Propal($db); @@ -1480,7 +1490,6 @@ if ($action == 'create') print ''; print ''; print ''; } @@ -2018,7 +2027,7 @@ if ($action == 'create') print '
    '.$langs->trans("Feature").' '.$langs->trans("Status").' '.$langs->trans("Status").'
    '.$langs->trans("SendingsAbility").''; +print ''; print ''; +print ''; print $langs->trans("Required"); /*if (empty($conf->global->MAIN_SUBMODULE_EXPEDITION)) { @@ -129,15 +124,14 @@ print "
    '; print $langs->trans("DeliveriesOrderAbility"); print '
    '.info_admin($langs->trans("NoNeedForDeliveryReceipts"), 0, 1); print '
    '; +print ''; print ''; +print ''; if (empty($conf->global->MAIN_SUBMODULE_LIVRAISON)) { diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 34a561121b2..ef8b10c411f 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -72,26 +72,28 @@ if ($action == 'updateMask') } } -else if ($action == 'set_SHIPPING_FREE_TEXT') +else if ($action == 'set_param') { $freetext=GETPOST('SHIPPING_FREE_TEXT'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "SHIPPING_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); - - if ($res > 0) - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - else + if ($res <= 0) + { + $error++; setEventMessages($langs->trans("Error"), null, 'errors'); -} - -else if ($action == 'set_SHIPPING_DRAFT_WATERMARK') -{ + } + $draft=GETPOST('SHIPPING_DRAFT_WATERMARK','alpha'); $res = dolibarr_set_const($db, "SHIPPING_DRAFT_WATERMARK",trim($draft),'chaine',0,'',$conf->entity); - - if ($res > 0) - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - else + if ($res <= 0) + { + $error++; setEventMessages($langs->trans("Error"), null, 'errors'); + } + + if (! $error) + { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } } else if ($action == 'specimen') @@ -222,11 +224,9 @@ print load_fiche_titre($langs->trans("SendingsSetup"),$linkback,'title_setup'); print '
    '; $head = expedition_admin_prepare_head(); -dol_fiche_head($head, 'shipment', $langs->trans("Sendings"), 0, 'sending'); +dol_fiche_head($head, 'shipment', $langs->trans("Sendings"), -1, 'sending'); -/* - * Expedition numbering model - */ +// Shipment numbering model print load_fiche_titre($langs->trans("SendingsNumberingModules")); @@ -235,8 +235,8 @@ print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
    '.$module->nom."
    '.$module->nom."'; print $module->info(); print '
    '; + print '
    '; print (empty($module->name)?$name:$module->name); print "\n"; if (method_exists($module,'info')) print $module->info($langs); @@ -498,19 +493,16 @@ print '
    '; */ print load_fiche_titre($langs->trans("OtherOptions")); -$var=true; +print '
    '; +print ''; +print ''; + print ""; print ""; print "\n"; -print '\n"; -print "\n"; print ""; -$var=! $var; -print ''; -print ''; -print ''; -print '\n"; -print ''; -$var=!$var; -print ''; -print ''; -print ''; -print '\n"; -print ''; print '
    ".$langs->trans("Parameter")."'.$langs->trans("Value")." 
    '; +print '
    '; print $langs->trans("FreeLegalTextOnShippings").' ('.$langs->trans("AddCRIfTooLong").')
    '; $variablename='SHIPPING_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) @@ -523,25 +515,18 @@ else $doleditor=new DolEditor($variablename, $conf->global->$variablename,'',80,'dolibarr_details'); print $doleditor->Create(); } -print '
    '; -print ''; print "
    '; +print '
    '; print $langs->trans("WatermarkOnDraft").'
    '; print ''; -print '
    '; -print ''; print "
    '; +print '
    '; + +print ''; llxFooter(); $db->close(); diff --git a/htdocs/admin/expedition_extrafields.php b/htdocs/admin/expedition_extrafields.php index d682f73ce6d..8c24c49cb23 100644 --- a/htdocs/admin/expedition_extrafields.php +++ b/htdocs/admin/expedition_extrafields.php @@ -78,7 +78,7 @@ print "
    \n"; $head = expedition_admin_prepare_head(); -dol_fiche_head($head, 'attributes_shipment', $langs->trans("Sendings"), 0, 'sending'); +dol_fiche_head($head, 'attributes_shipment', $langs->trans("Sendings"), -1, 'sending'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; diff --git a/htdocs/admin/expeditiondet_extrafields.php b/htdocs/admin/expeditiondet_extrafields.php index c4d45f08ded..283eeab452a 100644 --- a/htdocs/admin/expeditiondet_extrafields.php +++ b/htdocs/admin/expeditiondet_extrafields.php @@ -78,7 +78,7 @@ print "
    \n"; $head = expedition_admin_prepare_head(); -dol_fiche_head($head, 'attributeslines_shipment', $langs->trans("Sendings"), 0, 'sending'); +dol_fiche_head($head, 'attributeslines_shipment', $langs->trans("Sendings"), -1, 'sending'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; diff --git a/htdocs/admin/livraison.php b/htdocs/admin/livraison.php index 42d7fa69ac8..e49f25d7ef8 100644 --- a/htdocs/admin/livraison.php +++ b/htdocs/admin/livraison.php @@ -214,12 +214,10 @@ print load_fiche_titre($langs->trans("SendingsSetup"),$linkback,'title_setup'); print '
    '; $head = expedition_admin_prepare_head(); -dol_fiche_head($head, 'receivings', $langs->trans("Receivings"), 0, 'sending'); +dol_fiche_head($head, 'receivings', $langs->trans("Receivings"), -1, 'sending'); -/* - * Livraison numbering model - */ +// Delivery numbering model print load_fiche_titre($langs->trans("DeliveryOrderNumberingModules"),'',''); diff --git a/htdocs/admin/livraison_extrafields.php b/htdocs/admin/livraison_extrafields.php index 71a34039084..84037ae9b80 100644 --- a/htdocs/admin/livraison_extrafields.php +++ b/htdocs/admin/livraison_extrafields.php @@ -78,7 +78,7 @@ print "
    \n"; $head = expedition_admin_prepare_head(); -dol_fiche_head($head, 'attributes_receivings', $langs->trans("Receivings"), 0, 'sending'); +dol_fiche_head($head, 'attributes_receivings', $langs->trans("Receivings"), -1, 'sending'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; diff --git a/htdocs/admin/livraisondet_extrafields.php b/htdocs/admin/livraisondet_extrafields.php index 4679123352a..22a7e89d724 100644 --- a/htdocs/admin/livraisondet_extrafields.php +++ b/htdocs/admin/livraisondet_extrafields.php @@ -78,7 +78,7 @@ print "
    \n"; $head = expedition_admin_prepare_head(); -dol_fiche_head($head, 'attributeslines_receivings', $langs->trans("Receivings"), 0, 'sending'); +dol_fiche_head($head, 'attributeslines_receivings', $langs->trans("Receivings"), -1, 'sending'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; From 9b42177bd5c47079a030053bef0ad37caad06d53 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 10:52:09 +0100 Subject: [PATCH 174/410] Fix half day for leave request. --- htdocs/hrm/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index 30d0c911ba1..714f329add3 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -148,7 +148,7 @@ $langs->load("boxes"); -// Last leave requests +// Latest leave requests if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) { $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.photo, u.statut, x.rowid, x.rowid as ref, x.fk_type, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.tms as dm, x.statut as status"; @@ -204,7 +204,7 @@ if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) $starthalfday=($obj->halfday == -1 || $obj->halfday == 2)?'afternoon':'morning'; $endhalfday=($obj->halfday == 1 || $obj->halfday == 2)?'morning':'afternoon'; - print '
    '.dol_print_date($obj->date_start,'day').' '.$langs->trans($listhalfday[$endhalfday]); + print ''.dol_print_date($obj->date_start,'day').' '.$langs->trans($listhalfday[$starthalfday]); print ''.dol_print_date($obj->date_end,'day').' '.$langs->trans($listhalfday[$endhalfday]); print ''.dol_print_date($db->jdate($obj->dm),'day').''.$holidaystatic->LibStatut($obj->status,3).'
    '.$langs->trans("DateDebCP").' ('.$langs->trans("FirstDayOfHoliday").')'; + print $langs->trans("DateDebCP"); + print ' ('.$langs->trans("FirstDayOfHoliday").')'; + print ''; // Si la demande ne vient pas de l'agenda if (! GETPOST('date_debut_')) { @@ -844,7 +847,10 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create // Date end print '
    '.$langs->trans("DateFinCP").' ('.$langs->trans("LastDayOfHoliday").')'; + print $langs->trans("DateFinCP"); + print ' ('.$langs->trans("LastDayOfHoliday").')'; + print ''; // Si la demande ne vient pas de l'agenda if (! GETPOST('date_fin_')) { diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 3d6e8868bec..6f8e7293efb 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -519,6 +519,12 @@ textarea.centpercent { .nounderline { text-decoration: none; } +.paddingleft { + padding-: 4px; +} +.paddingright { + padding-: 4px; +} .cursorpointer { cursor: pointer; } @@ -1090,7 +1096,8 @@ img.photorefnoborder { height: 48px; width: 48px; object-fit: contain; - border: 1px solid #CCC; + border: 1px solid #AAA; + border-radius: 100px; } .underrefbanner { } @@ -1615,11 +1622,16 @@ img.login, img.printer, img.entity { color: white; font-weight: bold; } -img.loginphoto { - border-radius: 2px; +.userimgatoplogin img.userphoto { /* size for user photo in login bar */ width: 16px; height: 16px; } +img.userphoto { /* size for user photo in lists */ + border-radius: 2px; + width: 18px; + height: 18px; + vertical-align: middle; +} .span-icon-user { background-image: url(); background-repeat: no-repeat; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index aae0fd7f677..46d410e61cb 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -526,6 +526,12 @@ textarea.centpercent { .nounderline { text-decoration: none; } +.paddingleft { + padding-: 4px; +} +.paddingright { + padding-: 4px; +} .cursorpointer { cursor: pointer; } @@ -1141,7 +1147,8 @@ img.photorefnoborder { height: 48px; width: 48px; object-fit: contain; - border: 1px solid #CCC; + border: 1px solid #AAA; + border-radius: 100px; } .underrefbanner { } @@ -1654,13 +1661,17 @@ img.login, img.printer, img.entity { color: white; font-weight: bold; } -img.loginphoto { +.userimgatoplogin img.userphoto { /* size for user photo in login bar */ border-radius: 5px; - margin-top: -4px; - width: 20px; - height: 20px; + width: 16px; + height: 16px; + vertical-align: text-bottom; +} +img.userphoto { /* size for user photo in lists */ + width: 18px; + height: 18px; + vertical-align: middle; } - .span-icon-user { background-image: url(); background-repeat: no-repeat; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index c107c1587ae..4b9c1c9960c 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1981,77 +1981,77 @@ class User extends CommonObject function getNomUrl($withpictoimg=0, $option='', $infologin=0, $notooltip=0, $maxlen=24, $hidethirdpartylogo=0, $mode='',$morecss='') { global $langs, $conf, $db, $hookmanager; - global $dolibarr_main_authentication, $dolibarr_main_demo; - global $menumanager; + global $dolibarr_main_authentication, $dolibarr_main_demo; + global $menumanager; if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; - $result = ''; - $companylink = ''; - $link = ''; + $result = ''; + $companylink = ''; + $link = ''; - $label = '' . $langs->trans("User") . ''; - $label.= '
    '; - $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,'',''); - if (! empty($this->login)) - $label.= '
    ' . $langs->trans('Login') . ': ' . $this->login; - $label.= '
    ' . $langs->trans("EMail").': '.$this->email; - if (! empty($this->admin)) - $label.= '
    ' . $langs->trans("Administrator").': '.yn($this->admin); - if (! empty($this->societe_id) ) // Add thirdparty for external users - { - $thirdpartystatic = new Societe($db); - $thirdpartystatic->fetch($this->societe_id); - if (empty($hidethirdpartylogo)) $companylink = ' '.$thirdpartystatic->getNomUrl(2); // picto only of company - $company=' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')'; - } - $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal")); - $label.= '
    ' . $langs->trans("Type") . ': ' . $type; - $label.='
    '; - if (! empty($this->photo)) - { - $label.= '
    '; + $label = '' . $langs->trans("User") . ''; + $label.= '
    '; + $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,'',''); + if (! empty($this->login)) + $label.= '
    ' . $langs->trans('Login') . ': ' . $this->login; + $label.= '
    ' . $langs->trans("EMail").': '.$this->email; + if (! empty($this->admin)) + $label.= '
    ' . $langs->trans("Administrator").': '.yn($this->admin); + if (! empty($this->societe_id) ) // Add thirdparty for external users + { + $thirdpartystatic = new Societe($db); + $thirdpartystatic->fetch($this->societe_id); + if (empty($hidethirdpartylogo)) $companylink = ' '.$thirdpartystatic->getNomUrl(2); // picto only of company + $company=' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')'; + } + $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal")); + $label.= '
    ' . $langs->trans("Type") . ': ' . $type; + $label.='
    '; + if (! empty($this->photo)) + { + $label.= '
    '; $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); - $label.= '
    '; - } + $label.= '
    '; + } - // Info Login - if ($infologin) - { - $label.= '
    '; - $label.= '
    '.$langs->trans("Connection").''; - $label.= '
    '.$langs->trans("IPAddress").': '.$_SERVER["REMOTE_ADDR"]; - if (! empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $label.= '
    '.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (user entity '.$this->entity.')'; - $label.= '
    '.$langs->trans("AuthenticationMode").': '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo)?'':' (demo)'); - $label.= '
    '.$langs->trans("ConnectedSince").': '.dol_print_date($this->datelastlogin,"dayhour",'tzuser'); - $label.= '
    '.$langs->trans("PreviousConnexion").': '.dol_print_date($this->datepreviouslogin,"dayhour",'tzuser'); - $label.= '
    '.$langs->trans("CurrentTheme").': '.$conf->theme; - $label.= '
    '.$langs->trans("CurrentMenuManager").': '.$menumanager->name; - $s=picto_from_langcode($langs->getDefaultLang()); - $label.= '
    '.$langs->trans("CurrentUserLanguage").': '.($s?$s.' ':'').$langs->getDefaultLang(); - $label.= '
    '.$langs->trans("Browser").': '.$conf->browser->name.($conf->browser->version?' '.$conf->browser->version:'').' ('.$_SERVER['HTTP_USER_AGENT'].')'; - $label.= '
    '.$langs->trans("Layout").': '.$conf->browser->layout; - $label.= '
    '.$langs->trans("Screen").': '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']; - if (! empty($conf->browser->phone)) $label.= '
    '.$langs->trans("Phone").': '.$conf->browser->phone; - if (! empty($_SESSION["disablemodules"])) $label.= '
    '.$langs->trans("DisabledModules").':
    '.join(', ',explode(',',$_SESSION["disablemodules"])); - } + // Info Login + if ($infologin) + { + $label.= '
    '; + $label.= '
    '.$langs->trans("Connection").''; + $label.= '
    '.$langs->trans("IPAddress").': '.$_SERVER["REMOTE_ADDR"]; + if (! empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $label.= '
    '.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (user entity '.$this->entity.')'; + $label.= '
    '.$langs->trans("AuthenticationMode").': '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo)?'':' (demo)'); + $label.= '
    '.$langs->trans("ConnectedSince").': '.dol_print_date($this->datelastlogin,"dayhour",'tzuser'); + $label.= '
    '.$langs->trans("PreviousConnexion").': '.dol_print_date($this->datepreviouslogin,"dayhour",'tzuser'); + $label.= '
    '.$langs->trans("CurrentTheme").': '.$conf->theme; + $label.= '
    '.$langs->trans("CurrentMenuManager").': '.$menumanager->name; + $s=picto_from_langcode($langs->getDefaultLang()); + $label.= '
    '.$langs->trans("CurrentUserLanguage").': '.($s?$s.' ':'').$langs->getDefaultLang(); + $label.= '
    '.$langs->trans("Browser").': '.$conf->browser->name.($conf->browser->version?' '.$conf->browser->version:'').' ('.$_SERVER['HTTP_USER_AGENT'].')'; + $label.= '
    '.$langs->trans("Layout").': '.$conf->browser->layout; + $label.= '
    '.$langs->trans("Screen").': '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']; + if (! empty($conf->browser->phone)) $label.= '
    '.$langs->trans("Phone").': '.$conf->browser->phone; + if (! empty($_SESSION["disablemodules"])) $label.= '
    '.$langs->trans("DisabledModules").':
    '.join(', ',explode(',',$_SESSION["disablemodules"])); + } - if ($option == 'leave') $link.= 'global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $langs->load("users"); - $label=$langs->trans("ShowUser"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; - } + $linkclose=""; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $langs->load("users"); + $label=$langs->trans("ShowUser"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } if (! is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; @@ -2071,9 +2071,11 @@ class User extends CommonObject { $paddafterimage=''; if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"'; - if ($withpictoimg > 0) $picto='
    '.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'
    '; - else $picto='
    '.Form::showphoto('userphoto', $this, 0, 0, 0, 'loginphoto', 'mini', 0, 1).'
    '; - $result.=$picto; + // Only picto + if ($withpictoimg > 0) $picto='
    '.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'
    '; + // Picto must be a photo + else $picto='
    '.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto', 'mini', 0, 1).'
    '; + $result.=$picto; } if (abs($withpictoimg) != 2) { diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php index bb558bd56b3..888d4ca5317 100644 --- a/htdocs/user/hierarchy.php +++ b/htdocs/user/hierarchy.php @@ -146,8 +146,7 @@ $param="search_statut=".$search_statut; print ''; print ''; print_liste_field_titre($langs->trans("HierarchicView")); -print ''; +print_liste_field_titre('',$_SERVER['PHP_SELF'],"",'',"",'align="center"'); print_liste_field_titre($langs->trans("Status"),$_SERVER['PHP_SELF'],"",'',"",'align="right"'); print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','','','','maxwidthsearch '); print ''; diff --git a/htdocs/user/home.php b/htdocs/user/home.php index a5e9db67867..29ef7dac061 100644 --- a/htdocs/user/home.php +++ b/htdocs/user/home.php @@ -62,22 +62,21 @@ print '
    '; // Search User -$var=false; print '
    '; print ''; print '
    '; -print ''; -print ''; +print ''; +print ''; // Search Group if ($canreadperms) { - $var=false; - print ''; } +print ''; print "
    '.$langs->trans("Search").'
    '; -print $langs->trans("User").':
    '.$langs->trans("Search").'
    '; +print $langs->trans("User").':
    '; + print '
    '; print $langs->trans("Group").':

    \n"; print ''; diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 623e2df3434..60defe580a7 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -461,12 +461,10 @@ print "
    '; print $li; if (! empty($conf->multicompany->enabled) && $obj->admin && ! $obj->entity) { - print img_picto($langs->trans("SuperAdministrator"),'redstar'); + print img_picto($langs->trans("SuperAdministrator"), 'redstar', 'class="valignmiddle paddingleft"'); } else if ($obj->admin) { - print img_picto($langs->trans("Administrator"),'star'); + print img_picto($langs->trans("Administrator"), 'star', 'class="valignmiddle paddingleft"'); } print '
    '.fieldLabel('Currency','multicurrency_code').''; - $currency_code = (!empty($soc->multicurrency_code) ? $soc->multicurrency_code : ($object->multicurrency_code ? $object->multicurrency_code : $conf->currency)); print $form->selectMultiCurrency($currency_code, 'multicurrency_code', 0); print '
    '; - if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon)) + if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) print ''; print '
    '; print fieldLabel('CurrencyRate','multicurrency_tx'); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
    '; print ''; @@ -2029,7 +2038,7 @@ if ($action == 'create') $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code); } else { $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); - if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code != $conf->currency) { + if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { print '
            '; print ''.$langs->trans("ActualizeCurrency").''; print '
    '; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index fda37a88467..749f40fef4e 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2213,7 +2213,7 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; - if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon)) + if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) print ''; print '
    '; print fieldLabel('CurrencyRate','multicurrency_tx'); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
    '; print ''; @@ -2224,7 +2224,7 @@ if ($action == 'create' && $user->rights->commande->creer) $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code); } else { $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); - if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code != $conf->currency) { + if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { print '
            '; print ''.$langs->trans("ActualizeCurrency").''; print '
    '; diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 73959687527..b71dbe0cc70 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -3257,7 +3257,7 @@ else if ($id > 0 || ! empty($ref)) print ''; - if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon)) + if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) print ''; print '
    '; print fieldLabel('CurrencyRate','multicurrency_tx'); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
    '; print ''; @@ -3268,7 +3268,7 @@ else if ($id > 0 || ! empty($ref)) $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code); } else { $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); - if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code != $conf->currency) { + if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { print '
            '; print ''.$langs->trans("ActualizeCurrency").''; print '
    '; diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 41cd29f8b35..972a75eecc8 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -554,6 +554,7 @@ class pdf_azur extends ModelePDFPropales // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva; else $tvaligne=$object->lines[$i]->total_tva; + $localtax1ligne=$object->lines[$i]->total_localtax1; $localtax2ligne=$object->lines[$i]->total_localtax2; $localtax1_rate=$object->lines[$i]->localtax1_tx; 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 9865fc86136..1e7e6f4bcad 100644 --- a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php @@ -430,7 +430,8 @@ class pdf_canelle extends ModelePDFSuppliersInvoices $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->postotalht, 3, $total_excl_tax, 0, 'R', 0); // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva - $tvaligne=$object->lines[$i]->total_tva; + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva; + else $tvaligne=$object->lines[$i]->total_tva; $localtax1ligne=$object->lines[$i]->total_localtax1; $localtax2ligne=$object->lines[$i]->total_localtax2; 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 2c699190a7c..c882ed89800 100644 --- a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php @@ -437,8 +437,9 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->postotalht, 3, $total_excl_tax, 0, 'R', 0); // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva - $tvaligne=$object->lines[$i]->total_tva; - + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva; + else $tvaligne=$object->lines[$i]->total_tva; + $localtax1ligne=$object->lines[$i]->total_localtax1; $localtax2ligne=$object->lines[$i]->total_localtax2; $localtax1_rate=$object->lines[$i]->localtax1_tx; diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index 650be00c25d..3b2812c7b90 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -460,7 +460,9 @@ class pdf_aurore extends ModelePDFSupplierProposal */ // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva - $tvaligne=$object->lines[$i]->total_tva; + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva; + else $tvaligne=$object->lines[$i]->total_tva; + $localtax1ligne=$object->lines[$i]->total_localtax1; $localtax2ligne=$object->lines[$i]->total_localtax2; $localtax1_rate=$object->lines[$i]->localtax1_tx; @@ -560,7 +562,7 @@ class pdf_aurore extends ModelePDFSupplierProposal $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); // Affiche zone totaux - $posy=$this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); + //$posy=$this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); // Affiche zone versements /* diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 8d45b11beb3..1616df39503 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -176,7 +176,7 @@ class CommandeFournisseur extends CommonOrder // Check parameters if (empty($id) && empty($ref)) return -1; - $sql = "SELECT c.rowid, c.ref, ref_supplier, c.fk_soc, c.fk_statut, c.amount_ht, c.total_ht, c.total_ttc, c.tva,"; + $sql = "SELECT c.rowid, c.ref, ref_supplier, c.fk_soc, c.fk_statut, c.amount_ht, c.total_ht, c.total_ttc, c.tva as total_vat,"; $sql.= " c.localtax1, c.localtax2, "; $sql.= " c.date_creation, c.date_valid, c.date_approve, c.date_approve2,"; $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_approve, c.fk_user_approve2,"; @@ -222,7 +222,7 @@ class CommandeFournisseur extends CommonOrder $this->user_approve_id = $obj->fk_user_approve; $this->user_approve_id2 = $obj->fk_user_approve2; $this->total_ht = $obj->total_ht; - $this->total_tva = $obj->tva; + $this->total_tva = $obj->total_vat; $this->total_localtax1 = $obj->localtax1; $this->total_localtax2 = $obj->localtax2; $this->total_ttc = $obj->total_ttc; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index fb6bc840354..805052092fb 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1862,7 +1862,7 @@ elseif (! empty($object->id)) print ''; - if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon)) + if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) print ''; print '
    '; print fieldLabel('CurrencyRate','multicurrency_tx'); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
    '; print ''; @@ -1873,7 +1873,7 @@ elseif (! empty($object->id)) $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code); } else { $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); - if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code != $conf->currency) { + if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { print '
            '; print ''.$langs->trans("ActualizeCurrency").''; print '
    '; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 09ce7ef46aa..b0cdd488adf 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1796,17 +1796,14 @@ if ($action == 'create') echo ''; print ''.$langs->trans('TotalHT').''.price($objectsrc->total_ht).''; print ''.$langs->trans('TotalVAT').''.price($objectsrc->total_tva).""; - if ($mysoc->country_code=='ES') + if ($mysoc->localtax1_assuj=="1" || $object->total_localtax1 != 0) //Localtax1 { - if ($mysoc->localtax1_assuj=="1" || $object->total_localtax1 != 0) //Localtax1 - { - print ''.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1).""; - } + print ''.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1).""; + } - if ($mysoc->localtax2_assuj=="1" || $object->total_localtax2 != 0) //Localtax2 - { - print ''.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2).""; - } + if ($mysoc->localtax2_assuj=="1" || $object->total_localtax2 != 0) //Localtax2 + { + print ''.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2).""; } print ''.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc).""; @@ -2165,7 +2162,7 @@ else print ''; - if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon)) + if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) print ''; print '
    '; print fieldLabel('CurrencyRate','multicurrency_tx'); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
    '; print ''; @@ -2176,7 +2173,7 @@ else $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code); } else { $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); - if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code != $conf->currency) { + if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { print '
            '; print ''.$langs->trans("ActualizeCurrency").''; print '
    '; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index e02a512f327..741ed0f2b5c 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1040,6 +1040,15 @@ if ($action == 'create') $objectsrc->fetch_optionals($originid); $object->array_options = $objectsrc->array_options; + if (!empty($conf->multicurrency->enabled)) + { + if (!empty($objectsrc->multicurrency_code)) $currency_code = $objectsrc->multicurrency_code; + if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx)) $currency_tx = $objectsrc->multicurrency_tx; + } + } + else + { + if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; } $object = new SupplierProposal($db); @@ -1149,7 +1158,6 @@ if ($action == 'create') print ''; print ''.fieldLabel('Currency','multicurrency_code').''; print ''; - $currency_code = (!empty($soc->multicurrency_code) ? $soc->multicurrency_code : ($object->multicurrency_code ? $object->multicurrency_code : $conf->currency)); print $form->selectMultiCurrency($currency_code, 'multicurrency_code'); print ''; } @@ -1196,6 +1204,13 @@ if ($action == 'create') print '' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '' . price($objectsrc->total_localtax2) . ""; } print '' . $langs->trans('TotalTTC') . '' . price($objectsrc->total_ttc) . ""; + + if (!empty($conf->multicurrency->enabled)) + { + print '' . $langs->trans('MulticurrencyTotalHT') . '' . price($objectsrc->multicurrency_total_ht) . ''; + print '' . $langs->trans('MulticurrencyTotalVAT') . '' . price($objectsrc->multicurrency_total_tva) . ""; + print '' . $langs->trans('MulticurrencyTotalTTC') . '' . price($objectsrc->multicurrency_total_ttc) . ""; + } } print "\n"; @@ -1491,14 +1506,22 @@ if ($action == 'create') print ''; - if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon)) + if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) print ''; print '
    '; print fieldLabel('CurrencyRate','multicurrency_tx'); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
    '; print ''; - if ($action == 'editmulticurrencyrate') { - $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code); + if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') { + if($action == 'actualizemulticurrencyrate') { + list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code); + } + $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code); } else { - $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); + $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); + if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { + print '
            '; + print ''.$langs->trans("ActualizeCurrency").''; + print '
    '; + } } print ''; } From e72f0076edf57a51dd39d7c1726830826b6a0810 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 13:06:38 +0100 Subject: [PATCH 180/410] Remove border-bottom useless --- htdocs/margin/tabs/thirdpartyMargins.php | 2 +- htdocs/societe/agenda.php | 2 +- htdocs/societe/commerciaux.php | 2 +- htdocs/societe/consumption.php | 2 +- htdocs/societe/document.php | 2 +- htdocs/societe/note.php | 2 +- htdocs/societe/notify/card.php | 2 +- htdocs/societe/project.php | 2 +- htdocs/societe/rib.php | 2 +- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 7 ++++--- 11 files changed, 14 insertions(+), 13 deletions(-) diff --git a/htdocs/margin/tabs/thirdpartyMargins.php b/htdocs/margin/tabs/thirdpartyMargins.php index df472489c36..99df684342d 100644 --- a/htdocs/margin/tabs/thirdpartyMargins.php +++ b/htdocs/margin/tabs/thirdpartyMargins.php @@ -89,7 +89,7 @@ if ($socid > 0) $head = societe_prepare_head($object); - dol_fiche_head($head, 'margin', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'margin', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/societe/agenda.php b/htdocs/societe/agenda.php index 644cda92bc4..36fbe790bf3 100644 --- a/htdocs/societe/agenda.php +++ b/htdocs/societe/agenda.php @@ -118,7 +118,7 @@ if ($socid > 0) if (! empty($conf->notification->enabled)) $langs->load("mails"); $head = societe_prepare_head($object); - dol_fiche_head($head, 'agenda', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'agenda', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/societe/commerciaux.php b/htdocs/societe/commerciaux.php index dd8802779b8..2126c81ddfe 100644 --- a/htdocs/societe/commerciaux.php +++ b/htdocs/societe/commerciaux.php @@ -112,7 +112,7 @@ if (! empty($socid)) $head=societe_prepare_head2($object); - dol_fiche_head($head, 'salesrepresentative', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'salesrepresentative', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index fb154790210..0bff649d7d3 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -112,7 +112,7 @@ if (empty($socid)) } $head = societe_prepare_head($object); -dol_fiche_head($head, 'consumption', $langs->trans("ThirdParty"),0,'company'); +dol_fiche_head($head, 'consumption', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/societe/document.php b/htdocs/societe/document.php index d83822c2cd7..48f5fd79621 100644 --- a/htdocs/societe/document.php +++ b/htdocs/societe/document.php @@ -98,7 +98,7 @@ if ($object->id) $form=new Form($db); - dol_fiche_head($head, 'document', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'document', $langs->trans("ThirdParty"), -1, 'company'); // Construit liste des fichiers diff --git a/htdocs/societe/note.php b/htdocs/societe/note.php index 9ca7f1fcd2a..c713250a0e2 100644 --- a/htdocs/societe/note.php +++ b/htdocs/societe/note.php @@ -71,7 +71,7 @@ if ($id > 0) $head = societe_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'note', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/societe/notify/card.php b/htdocs/societe/notify/card.php index bc754d8e9a4..63d33dcee1d 100644 --- a/htdocs/societe/notify/card.php +++ b/htdocs/societe/notify/card.php @@ -153,7 +153,7 @@ if ($result > 0) $head = societe_prepare_head($object); - dol_fiche_head($head, 'notify', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'notify', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/societe/project.php b/htdocs/societe/project.php index fe206dd4cc5..72c371ce934 100644 --- a/htdocs/societe/project.php +++ b/htdocs/societe/project.php @@ -79,7 +79,7 @@ if ($socid) if (! empty($conf->notification->enabled)) $langs->load("mails"); $head = societe_prepare_head($object); - dol_fiche_head($head, 'project', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'project', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/societe/rib.php b/htdocs/societe/rib.php index feea1aca0ce..f1db2d21835 100644 --- a/htdocs/societe/rib.php +++ b/htdocs/societe/rib.php @@ -344,7 +344,7 @@ if ($socid && $action == 'create' && $user->rights->societe->creer) // View if ($socid && $action != 'edit' && $action != "create") { - dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company'); // Confirm delete third party if ($action == 'delete') diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index c1b0ece5df0..4495f5e2719 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2451,7 +2451,7 @@ div.refid { font-size: 160%; } div.refidno { - padding-top: 2px; + padding-top: 8px; font-weight: normal; color: #444; font-size: px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 3c3e60ca129..e464482addb 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1906,17 +1906,18 @@ div.tabBar { padding-top: px; padding-left: px; padding-right: px; - padding-bottom: px; margin: 0px 0px 16px 0px; -moz-border-radius:3px; -webkit-border-radius: 3px; border-radius: 3px; border-right: 1px solid #BBB; - /* border-bottom: 1px solid #BBB; */ border-left: 1px solid #BBB; border-top: 1px solid #CCC; width: auto; background: rgb(); + + padding-bottom: 12px; + border-bottom: 1px solid #aaa; } div.tabBarWithBottom { padding-bottom: 18px; @@ -2363,7 +2364,7 @@ div.refid { font-size: 160%; } div.refidno { - padding-top: 2px; + padding-top: 8px; font-weight: normal; color: #444; font-size: px; From 22247271f6c36a7494e9239375042df0c4c080fc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 13:19:00 +0100 Subject: [PATCH 181/410] CSS enhancement --- htdocs/compta/bank/ligne.php | 3 ++- htdocs/theme/eldy/style.css.php | 2 ++ htdocs/theme/md/style.css.php | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 8c1f2af7b1f..53153c62189 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -539,7 +539,8 @@ if ($result) // Releve rappro if ($acct->canBeConciliated() > 0) // Si compte rapprochable { - print '
    '."\n"; + print '

    '."\n"; + print load_fiche_titre($langs->trans("Reconciliation"), '', 'title_bank.png'); print '
    '; print ''; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 4495f5e2719..6197458fc74 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -388,6 +388,8 @@ input[name=surface] { margin-right: 4px; } fieldset { border: 1px solid #AAAAAA !important; } .legendforfieldsetstep { padding-bottom: 10px; } +hr { border: 0; border-top: 1px solid #ccc; } + .button, .buttonDelete, input[name="sbmtConnexion"] { font-family: ; border-color: #c5c5c5; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index e464482addb..26c3f75b8e2 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -393,6 +393,7 @@ input:-moz-placeholder { color:#ccc; } fieldset { border: 1px solid #AAAAAA !important; } .legendforfieldsetstep { padding-bottom: 10px; } +hr { border: 0; border-top: 1px solid #ccc; } .button, .buttonDelete, input[name="sbmtConnexion"] { font-family: ; From 53a04703d636cdd3f314a8695b09068e43906624 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 16:10:38 +0100 Subject: [PATCH 182/410] Uniformize code --- htdocs/compta/sociales/document.php | 2 +- htdocs/compta/sociales/info.php | 2 +- .../install/mysql/migration/5.0.0-6.0.0.sql | 1 + .../mysql/tables/llx_chargesociales.sql | 3 ++- htdocs/projet/document.php | 2 +- htdocs/projet/element.php | 26 +++++++++---------- htdocs/projet/note.php | 2 +- htdocs/projet/tasks/task.php | 6 +++-- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 10 files changed, 26 insertions(+), 22 deletions(-) diff --git a/htdocs/compta/sociales/document.php b/htdocs/compta/sociales/document.php index a6f4bc10daf..4d3f908e73c 100644 --- a/htdocs/compta/sociales/document.php +++ b/htdocs/compta/sociales/document.php @@ -99,7 +99,7 @@ if ($object->id) $head=tax_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("SocialContribution"), 0, 'bill'); + dol_fiche_head($head, 'documents', $langs->trans("SocialContribution"), -1, 'bill'); $morehtmlref='
    '; // Label of social contribution diff --git a/htdocs/compta/sociales/info.php b/htdocs/compta/sociales/info.php index ff905f1ee6c..7caa212be9e 100644 --- a/htdocs/compta/sociales/info.php +++ b/htdocs/compta/sociales/info.php @@ -62,7 +62,7 @@ $object->info($id); $head = tax_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("SocialContribution"), 0, 'bill'); +dol_fiche_head($head, 'info', $langs->trans("SocialContribution"), -1, 'bill'); $morehtmlref='
    '; // Label of social contribution diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 6804576c9bd..d0accdda693 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -122,4 +122,5 @@ INSERT INTO llx_const (name, entity, value, type, visible, note) VALUES ('CONTRA INSERT INTO llx_const (name, entity, value, type, visible, note) VALUES ('USERGROUP_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/usergroups', 'chaine', 0, ''); INSERT INTO llx_const (name, entity, value, type, visible, note) VALUES ('USER_ADDON_PDF_ODT_PATH', 1, 'DOL_DATA_ROOT/doctemplates/users', 'chaine', 0, ''); +ALTER TABLE llx_chargesociales ADD COLUMN ref varchar(16); ALTER TABLE llx_chargesociales ADD COLUMN fk_projet integer DEFAULT NULL; diff --git a/htdocs/install/mysql/tables/llx_chargesociales.sql b/htdocs/install/mysql/tables/llx_chargesociales.sql index 5c07c9a74fc..519ceacc9e5 100644 --- a/htdocs/install/mysql/tables/llx_chargesociales.sql +++ b/htdocs/install/mysql/tables/llx_chargesociales.sql @@ -21,6 +21,7 @@ create table llx_chargesociales ( rowid integer AUTO_INCREMENT PRIMARY KEY, + ref varchar(16), -- "TX...." date_ech datetime NOT NULL, -- date echeance libelle varchar(80) NOT NULL, entity integer DEFAULT 1 NOT NULL, -- multi company id @@ -46,4 +47,4 @@ create table llx_chargesociales -- 1 : first company tax -- 2 : second company tax -- 3 : etc... --- \ No newline at end of file +-- diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index d61c9085f68..ab43a752d15 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -96,7 +96,7 @@ if ($object->id > 0) //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; $head = project_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans("Project"), 0, ($object->public?'projectpub':'project')); + dol_fiche_head($head, 'document', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); // Files list constructor $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index eec48b2a5bd..1efc4465d81 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -388,6 +388,19 @@ $listofreferent=array( 'buttonnew'=>'AddLoan', 'testnew'=>$user->rights->loan->write, 'test'=>$conf->loan->enabled && $user->rights->loan->read), +'chargesociales'=>array( + 'name'=>"SocialContribution", + 'title'=>"ListSocialContributionAssociatedProject", + 'class'=>'ChargeSociales', + 'margin'=>'add', + 'table'=>'chargesociales', + 'datefieldname'=>'date_ech', + 'disableamount'=>0, + 'urlnew'=>DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$id, + 'lang'=>'compta', + 'buttonnew'=>'AddSocialContribution', + 'testnew'=>$user->rights->tax->charges->lire, + 'test'=>$conf->tax->enabled && $user->rights->tax->charges->lire), 'project_task'=>array( 'name'=>"TaskTimeValorised", 'title'=>"ListTaskTimeUserProject", @@ -409,19 +422,6 @@ $listofreferent=array( 'datefieldname'=>'datem', 'disableamount'=>0, 'test'=>($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))), -'chargesociales'=>array( - 'name'=>"SocialContribution", - 'title'=>"ListSocialContributionAssociatedProject", - 'class'=>'ChargeSociales', - 'margin'=>'add', - 'table'=>'chargesociales', - 'datefieldname'=>'date_ech', - 'disableamount'=>0, - 'urlnew'=>DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$id, - 'lang'=>'compta', - 'buttonnew'=>'AddSocialContribution', - 'testnew'=>$user->rights->tax->charges->lire, - 'test'=>$conf->tax->enabled && $user->rights->tax->charges->lire) /* No need for this, available on dedicated tab "Agenda/Events" 'agenda'=>array( 'name'=>"Agenda", diff --git a/htdocs/projet/note.php b/htdocs/projet/note.php index b00eae5d54d..a6b6e3c93e2 100644 --- a/htdocs/projet/note.php +++ b/htdocs/projet/note.php @@ -77,7 +77,7 @@ if ($id > 0 || ! empty($ref)) //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; $head = project_prepare_head($object); - dol_fiche_head($head, 'notes', $langs->trans('Project'), 0, ($object->public?'projectpub':'project')); + dol_fiche_head($head, 'notes', $langs->trans('Project'), -1, ($object->public?'projectpub':'project')); // Project card diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 84dccbb93e7..2665b0b33b5 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -430,13 +430,14 @@ if ($id > 0 || ! empty($ref)) $param=($withproject?'&withproject=1':''); $linkback=$withproject?''.$langs->trans("BackToList").'':''; - dol_fiche_head($head, 'task_task', $langs->trans("Task"),0,'projecttask'); + dol_fiche_head($head, 'task_task', $langs->trans("Task"), -1, 'projecttask'); if ($action == 'delete') { print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$_GET["id"].'&withproject='.$withproject,$langs->trans("DeleteATask"),$langs->trans("ConfirmDeleteATask"),"confirm_delete"); } + print '
    '; print ''; // Ref @@ -522,7 +523,8 @@ if ($id > 0 || ! empty($ref)) } print '
    '; - + print '
    '; + dol_fiche_end(); } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 6197458fc74..a394eae4312 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1061,7 +1061,7 @@ div.nopadding { width: 44px; } div.attacharea { - padding-top: 10px; + padding-top: 18px; padding-bottom: 10px; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 26c3f75b8e2..55741cdcffd 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1112,7 +1112,7 @@ table.noborder tr.liste_titre td { width: 44px; } div.attacharea { - padding-top: 10px; + padding-top: 18px; padding-bottom: 10px; } div.arearef { From c4b63787511c20b7b6e0fc22b9f7d46c450dec6c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 16:46:00 +0100 Subject: [PATCH 183/410] Fix english translation --- htdocs/langs/en_US/admin.lang | 2 +- htdocs/langs/en_US/agenda.lang | 4 ++-- htdocs/langs/en_US/banks.lang | 4 ++-- htdocs/langs/en_US/companies.lang | 2 +- htdocs/langs/en_US/main.lang | 4 ++-- htdocs/langs/en_US/projects.lang | 12 ++++++------ htdocs/langs/en_US/propal.lang | 6 +++--- htdocs/langs/en_US/sendings.lang | 8 ++++---- htdocs/langs/en_US/stocks.lang | 2 +- htdocs/langs/en_US/supplier_proposal.lang | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 2df0ffcc9d4..7cd29345e98 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1079,7 +1079,7 @@ TotalNumberOfActivatedModules=Total number of activated feature modules: %s%s. Correct stock or go back to choose another warehouse. WeightVolShort=Weight/Vol. ValidateOrderFirstBeforeShipment=You must first validate the order before being able to make shipments. diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 58a71b08857..746268f7e98 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -72,7 +72,7 @@ RealStock=Real Stock RealStockDesc=Physical or real stock is the stock you currently have into your internal warehouses/emplacements. RealStockWillAutomaticallyWhen=The real stock will automatically change according to this rules (see stock module setup to change this): VirtualStock=Virtual stock -VirtualStockDesc=Virtual stock is the stock you will get once all opened pending actions that affect stocks will be closed (supplier order received, customer order shipped, ...) +VirtualStockDesc=Virtual stock is the stock you will get once all open pending actions that affect stocks will be closed (supplier order received, customer order shipped, ...) IdWarehouse=Id warehouse DescWareHouse=Description warehouse LieuWareHouse=Localisation warehouse diff --git a/htdocs/langs/en_US/supplier_proposal.lang b/htdocs/langs/en_US/supplier_proposal.lang index 61b031459b0..621d7784e35 100644 --- a/htdocs/langs/en_US/supplier_proposal.lang +++ b/htdocs/langs/en_US/supplier_proposal.lang @@ -8,7 +8,7 @@ SearchRequest=Find a request DraftRequests=Draft requests SupplierProposalsDraft=Draft supplier proposals LastModifiedRequests=Latest %s modified price requests -RequestsOpened=Opened price requests +RequestsOpened=Open price requests SupplierProposalArea=Supplier proposals area SupplierProposalShort=Supplier proposal SupplierProposals=Supplier proposals @@ -23,7 +23,7 @@ ConfirmValidateAsk=Are you sure you want to validate this price request under na DeleteAsk=Delete request ValidateAsk=Validate request SupplierProposalStatusDraft=Draft (needs to be validated) -SupplierProposalStatusValidated=Validated (request is opened) +SupplierProposalStatusValidated=Validated (request is open) SupplierProposalStatusClosed=Closed SupplierProposalStatusSigned=Accepted SupplierProposalStatusNotSigned=Refused From 6ab94ddbe723cf3e89f94cd5a295343e9688c97a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 19:26:02 +0100 Subject: [PATCH 184/410] Fix translation --- htdocs/langs/en_US/main.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 22b9eb0ef4a..216c9187b0f 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -406,7 +406,7 @@ Duration=Duration TotalDuration=Total duration Summary=Summary DolibarrStateBoard=Statistics -DolibarrWorkBoard=Work tasks board +DolibarrWorkBoard=Open items board Available=Available NotYetAvailable=Not yet available NotAvailable=Not available From 4bc2864a6f86b7fb41732a5b98524a4a6bc02dc8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 19:26:28 +0100 Subject: [PATCH 185/410] Better board for open items --- htdocs/index.php | 80 +++++++++++++++------------------ htdocs/projet/info.php | 2 +- htdocs/theme/eldy/style.css.php | 51 ++++++++++++++++----- htdocs/theme/md/style.css.php | 50 ++++++++++++++++----- 4 files changed, 115 insertions(+), 68 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 75ee74144f2..86ea10b801f 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -337,7 +337,7 @@ if (empty($user->societe_id)) $text=$langs->trans($titres[$key]); $boxstat.=''; $boxstat.='
    '; - $boxstat.=''.img_object("",$icons[$key]).' '.$text.'
    '; + $boxstat.=''.img_object("",$icons[$key]).' '.$text.'
    '; $boxstat.=''.$board->nb[$val].''; $boxstat.='
    '; $boxstat.='
    '; @@ -530,33 +530,26 @@ $boxwork.='
    '; $boxwork.=''."\n"; $boxwork.=''; $boxwork.=''; -$boxwork.=''; -$boxwork.=''; -$boxwork.=''; +//$boxwork.=''; +//$boxwork.=''; +//$boxwork.=''; //print ''; //if ($showweather) $boxwork.=''; $boxwork.=''."\n"; if ($showweather) -{ - $var=!$var; +{/* $boxwork.=''; - $boxwork.=''; - /*$boxwork.='';*/ - $boxwork.=''; - $showweather=0; + $boxwork.='';*/ } +$boxwork.=''; - $boxwork .= ''; - $boxwork .= ''; - $boxwork .=''; - /*print '';*/ - /* - if ($showweather) + + $boxwork .='
    '; + $boxwork .= '
    '; + $boxwork .= $board->img.' '.$board->label.'
    '; + $boxwork .= ''.$board->nbtodo.''; + $boxwork .= '
    '; + if ($board->nbtodolate > 0) { - $boxwork.='
    '; - $showweather=0; - }*/ - $boxwork .=''; + $boxwork .= ''; + } + $boxwork.=''; $boxwork .="\n"; } + + $boxwork .='
    '; + $boxwork .='
    '; + $boxwork .='
    '; + $boxwork .='
    '; + $boxwork .='
    '; + $boxwork .='
    '; } else { @@ -610,6 +598,8 @@ else $boxwork.=''; } +$boxwork.=''; + $boxwork.='
    '.$langs->trans("DolibarrWorkBoard").''.$langs->trans("Number").''.$form->textwithpicto($langs->trans("Late"),$langs->trans("LateDesc")).' '.$langs->trans("Number").''.$form->textwithpicto($langs->trans("Late"),$langs->trans("LateDesc")).'   
    '; - //$boxwork.=$langs->trans("Meteo"); - //$boxwork.=''; + $boxwork.=''; $text=''; if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate).')'; $options='height="64px"'; $boxwork.=showWeather($totallate,$text,$options); $boxwork.=''; - if ($board->nbtodolate > 0) $boxwork.=img_picto($textlate,"warning"); - else $boxwork.=' '; - $boxwork.='
    '; // Show dashboard $nbworkboardempty=0; @@ -565,41 +558,36 @@ if (! empty($valid_dashboardlines)) foreach($valid_dashboardlines as $board) { if (empty($boad->nbtodo)) $nbworkboardempty++; - - $var=!$var; - $boxwork .= '
    '.$board->img.'   '.$board->label.''.$board->nbtodo.''; + $textlate = $langs->trans("NActionsLate",$board->nbtodolate); $textlate.= ' ('.$langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($board->warning_delay) >= 0 ? '+' : '').ceil($board->warning_delay).' '.$langs->trans("days").')'; - $boxwork .= ''; - $boxwork .= ''; - $boxwork .= $board->nbtodolate; - $boxwork .= ''; - $boxwork .= ''; - $boxwork .=''; - if ($board->nbtodolate > 0) $boxwork .=img_picto($textlate, "warning", 'class="valignmiddle"').' '; - $boxwork .=''; - print ' (>'.ceil($board->warning_delay).' '.$langs->trans("days").')'; - print ''; - $text=''; - if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate).')'; - $options='height="64px"'; - if ($rowspan <= 2) $options='height="24"'; // Weather logo is smaller if dashboard has few elements - else if ($rowspan <= 3) $options='height="48"'; // Weather logo is smaller if dashboard has few elements - $boxwork.=showWeather($totallate,$text,$options); - $boxwork.='
    '; // End table array of working board $boxwork.='
    '; diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index 65a95e232ff..3206fd51244 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -107,7 +107,7 @@ llxHeader("",$title,$help_url); $head = project_prepare_head($object); -dol_fiche_head($head, 'agenda', $langs->trans("Project"), 0, ($object->public?'projectpub':'project')); +dol_fiche_head($head, 'agenda', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); // Project card diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a394eae4312..aaa9254987b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -677,6 +677,11 @@ div.fiche>form>div.div-table-responsive { } .thumbstat { flex: 1 1 120px; +} +.thumbstat150 { + flex: 1 1 150px; +} +.thumbstat, thumbstat150 { /* flex-grow: 1; */ /* flex-shrink: 1; */ /* flex-basis: 140px; */ @@ -2854,26 +2859,37 @@ div.tabBar .noborder { .ficheaddleft div.boxstats { border: none; } -.boxstats { +.boxstatsborder { + border: 1px solid #CCC !important; +} +.boxstats, .boxstats130 { display: inline-block; margin: 3px; - padding: 3px; - /*-moz-box-shadow: 3px 3px 4px #DDD; - -webkit-box-shadow: 3px 3px 4px #DDD; - box-shadow: 3px 3px 4px #DDD; - margin-bottom: 8px !important;*/ border: 1px solid #CCC; text-align: center; border-radius: 2px; - +} +.boxstats, .boxstats130, .boxstatscontent { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - width: 115px; } +.boxstats { + padding: 3px; + width: 105px; +} +.boxstats130 { + width: 135px; + height: 48px; + padding: 3px +} +.boxstatscontent { + padding: 3px; +} + @media only screen and (max-width: 767px) { - .boxstats { + .boxstats, .boxstats130 { width: 100px; } } @@ -2890,15 +2906,25 @@ span.boxstatsindicator { font-weight: normal; } span.dashboardlineindicator, span.dashboardlineindicatorlate { - font-size: 120%; + font-size: 130%; font-weight: normal; } +.dashboardlineindicatorlate img { + width: 16px; +} span.dashboardlineok { color: #008800; } span.dashboardlineko { color: #880000; - font-weight: bold; + /* font-weight: bold; */ + font-size: 100%; +} +.dashboardlinelatecoin { + float: right; + position: relative; + text-align: right; + top: -22px } .boxtable { margin-bottom: 8px !important; @@ -2910,6 +2936,9 @@ span.dashboardlineko { .tdboxstats { text-align: center; } +a.valignmiddle.dashboardlineindicator { + line-height: 30px; +} .box { padding-right: 0px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 55741cdcffd..994a5be6924 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -684,6 +684,11 @@ div.fiche>form>div.div-table-responsive { } .thumbstat { flex: 1 1 120px; +} +.thumbstat150 { + flex: 1 1 150px; +} +.thumbstat, thumbstat150 { /* flex-grow: 1; */ /* flex-shrink: 1; */ /* flex-basis: 140px; */ @@ -2769,27 +2774,33 @@ div .tdtop { .ficheaddleft div.boxstats { border: none; } -.boxstats { +.boxstatsborder { + border: 1px solid #CCC !important; +} +.boxstats, .boxstats130 { display: inline-block; margin: 3px; - padding: 3px; - /*-moz-box-shadow: 3px 3px 4px #f4f4f4; - -webkit-box-shadow: 3px 3px 4px #f4f4f4; - box-shadow: 3px 3px 4px #f4f4f4; - margin-bottom: 8px !important;*/ border: 1px solid #CCC; text-align: center; border-radius: 2px; - min-height: 38px; - +} +.boxstats, .boxstats130, .boxstatscontent { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - width: 115px; +} +.boxstats { + padding: 3px; + width: 105px; +} +.boxstats130 { + width: 135px; + height: 48px; + padding: 3px } @media only screen and (max-width: 767px) { - .boxstats { + .boxstats, .boxstats130 { width: 100px; } } @@ -2806,7 +2817,10 @@ span.boxstatsindicator { } span.dashboardlineindicator, span.dashboardlineindicatorlate { font-size: 120%; - font-weight: bold; + font-weight: normal; +} +.dashboardlineindicatorlate img { + width: 16px; } span.dashboardlineok { color: #008800; @@ -2815,6 +2829,16 @@ span.dashboardlineko { color: #880000; font-weight: bold; } +.dashboardlinelatecoin { + float: right; + position: relative; + text-align: right; + top: -22px +} +.boxtable { + margin-bottom: 8px !important; + border-bottom-width: 1px; +} .boxtable { margin-bottom: 8px !important; border-bottom-width: 1px; @@ -2825,6 +2849,10 @@ span.dashboardlineko { .tdboxstats { text-align: center; } +a.valignmiddle.dashboardlineindicator { + line-height: 30px; +} + .box { padding-right: 0px; From eb145faffd31b3b78a8ebd4cbe0b834072587774 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 19:57:45 +0100 Subject: [PATCH 186/410] Replace parameter mixte with textselect --- htdocs/core/class/html.form.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index af0502e7def..21c3b5dbcfe 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4878,13 +4878,13 @@ class Form * Function to show a form to select a duration on a page * * @param string $prefix Prefix for input fields - * @param int $iSecond Default preselected duration (number of seconds or '') - * @param int $disabled Disable the combo box + * @param int $iSecond Default preselected duration (number of seconds or '') + * @param int $disabled Disable the combo box * @param string $typehour If 'select' then input hour and input min is a combo, - * if 'text' input hour is in text and input min is a text, - * if 'mixte' input hour is in text and input min is a combo - * @param integer $minunderhours If 1, show minutes selection under the hours - * @param int $nooutput Do not output html string but return it + * if 'text' input hour is in text and input min is a text, + * if 'textselect' input hour is in text and input min is a combo + * @param integer $minunderhours If 1, show minutes selection under the hours + * @param int $nooutput Do not output html string but return it * @return string|null */ function select_duration($prefix, $iSecond='', $disabled=0, $typehour='select', $minunderhours=0, $nooutput=0) @@ -4918,7 +4918,7 @@ class Form } $retstring.=""; } - elseif ($typehour=='text' || $typehour=='mixte') + elseif ($typehour=='text' || $typehour=='textselect') { $retstring.=''; } @@ -4931,7 +4931,7 @@ class Form if ($minunderhours) $retstring.='
    '; else $retstring.=" "; - if ($typehour=='select' || $typehour=='mixte') + if ($typehour=='select' || $typehour=='textselect') { $retstring.=''; print ''; } - print ''."\n"; + print '
    '."\n"; print ''; print_liste_field_titre($langs->trans("Documents2"),$url,"name","",$param,'align="left"',$sortfield,$sortorder); diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php index 5402ac5bbd1..4b19ffd5f3b 100644 --- a/htdocs/core/menus/standard/auguria_menu.php +++ b/htdocs/core/menus/standard/auguria_menu.php @@ -150,8 +150,8 @@ class MenuManager print ''."\n"; foreach($this->menu->liste as $key => $val) // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu' { - print '
    '; - - $linkback = '' . $langs->trans("BackToList") . ''; - - // Ref - print ''; - - // Ref client - print ''; - print ''; - print ''; - - - // Thirdparty - print ''; - print ''; - print ''; - - // Status - print ''; - print ''; - print ''; - - // Discount - print ''; - print ''; - - // Date - print ''; - print ''; - - // Right part with $rowspan lines - $rowspan=4; - print ''; - print ''; - - // Total HT - left part - print ''; - print ''; - print ''; - - // Total VAT - left part - print ''; - print ''; - print ''; - - // Total TTC - left part - print ''; - print ''; - print ''; - - print '
    ' . $langs->trans('Ref') . ''; - print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); - print '
    '.$langs->trans('RefCustomer').''.$object->ref_client.'
    '.$langs->trans('Company').''.$soc->getNomUrl(1).'
    '.$langs->trans("Status").''.$object->getLibStatut(4).'
    '.$langs->trans('Discounts').''; - if ($soc->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_percent); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - $absolute_discount=$soc->getAvailableDiscounts(); - print '. '; - if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",$absolute_discount,$langs->trans("Currency".$conf->currency)); - else print $langs->trans("CompanyHasNoAbsoluteDiscount"); - print '.
    '.$langs->trans('Date').''.dol_print_date($object->date,'daytext').''; - - /* - * Documents - */ - $objectref = dol_sanitizeFileName($object->ref); - $dir_output = $conf->propal->dir_output . "/"; - $filepath = $dir_output . $objectref . "/"; - $file = $filepath . $objectref . ".pdf"; - $filedetail = $filepath . $objectref . "-detail.pdf"; - $relativepath = $objectref.'/'.$objectref.'.pdf'; - $relativepathdetail = $objectref.'/'.$objectref.'-detail.pdf'; - - // Define path to preview pdf file (preview precompiled "file.ext" are "file.ext_preview.png") - $fileimage = $file.'_preview.png'; // If PDF has 1 page - $fileimagebis = $file.'_preview-0.pdf.png'; // If PDF has more than one page - $relativepathimage = $relativepath.'_preview.png'; - - $var=true; - - // Si fichier PDF existe - if (file_exists($file)) - { - $encfile = urlencode($file); - print ''; - print ''; - - print ''; - - print ''; - - print ''; - print ''; - print ''; - - print "
    '.$langs->trans("Documents").'
    '.$langs->trans("Proposal").' PDF'.$object->ref.'.pdf'.dol_print_size(dol_filesize($file)).''.dol_print_date(dol_filemtime($file),'dayhour').'
    \n"; - - // Conversion du PDF en image png si fichier png non existant - if ((! file_exists($fileimage) && ! file_exists($fileimagebis)) || (filemtime($fileimage) < filemtime($file))) - { - if (class_exists("Imagick")) - { - $ret = dol_convert_file($file,'png',$fileimage); - if ($ret < 0) $error++; - } - else - { - $langs->load("errors"); - print ''.$langs->trans("ErrorNoImagickReadimage").''; - } - } - } - - print '
    '.$langs->trans('AmountHT').'' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '.$langs->trans('AmountVAT').'' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '.$langs->trans('AmountTTC').'' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '; - - dol_fiche_end(); - } - else - { - // Propal non trouvee - print $langs->trans("ErrorPropalNotFound",$_GET["id"]); - } -} - -print ''; -print ''; -print '
    '; -print '
    '; -// Si fichier png PDF d'1 page trouve -if (file_exists($fileimage)) -{ - print ''; -} -// Si fichier png PDF de plus d'1 page trouve -elseif (file_exists($fileimagebis)) -{ - $multiple = preg_replace('/\.png/','',$relativepath) . "-"; - - for ($i = 0; $i < 20; $i++) - { - $preview = $multiple.$i.'.png'; - - if (file_exists($dir_output.$preview)) - { - print '

    '; - } - } -} -print '

    '; -print '
    '; - - -llxFooter(); - -$db->close(); diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 810d6bd1abb..9b70ee36ace 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1675,7 +1675,7 @@ if ($action == 'create') $soc->fetch($object->socid); $head = propal_prepare_head($object); - dol_fiche_head($head, 'comm', $langs->trans('Proposal'), 0, 'propal'); + dol_fiche_head($head, 'comm', $langs->trans('Proposal'), -1, 'propal'); $formconfirm = ''; @@ -1804,42 +1804,7 @@ if ($action == 'create') print ''; - // Ref - /* - print ''; - */ - - // Ref customer - /* - print ''; - print ''; - */ - - // Company - /* - print ''; - print '';*/ - - // Lin for thirdparty discounts + // Link for thirdparty discounts print '
    ' . $langs->trans('Ref') . ''; - print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); - print '
    '; - print ''; - if ($action != 'refclient' && ! empty($object->brouillon)) - print ''; - print '
    '; - print $langs->trans('RefCustomer') . '' . img_edit($langs->trans('Modify')) . '
    '; - print '
    '; - if ($user->rights->propal->creer && $action == 'refclient') { - print ''; - print ''; - print ''; - print ''; - print ' '; - print ''; - } else { - print $object->ref_client; - } - print '
    ' . $langs->trans('Company') . '' . $soc->getNomUrl(1) . '
    ' . $langs->trans('Discounts') . ''; if ($soc->remise_percent) print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent); diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php index 8588bfc5749..3c3aa6aef88 100644 --- a/htdocs/comm/propal/contact.php +++ b/htdocs/comm/propal/contact.php @@ -151,7 +151,7 @@ $formother = new FormOther($db); if ($object->id > 0) { $head = propal_prepare_head($object); - dol_fiche_head($head, 'contact', $langs->trans("Proposal"), 0, 'propal'); + dol_fiche_head($head, 'contact', $langs->trans("Proposal"), -1, 'propal'); // Proposal card diff --git a/htdocs/comm/propal/document.php b/htdocs/comm/propal/document.php index 9b875e434f7..82978daf2c1 100644 --- a/htdocs/comm/propal/document.php +++ b/htdocs/comm/propal/document.php @@ -89,7 +89,7 @@ if ($object->id > 0) $upload_dir = $conf->propal->dir_output.'/'.dol_sanitizeFileName($object->ref); $head = propal_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans('Proposal'), 0, 'propal'); + dol_fiche_head($head, 'document', $langs->trans('Proposal'), -1, 'propal'); // Construit liste des fichiers $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); diff --git a/htdocs/comm/propal/info.php b/htdocs/comm/propal/info.php index 14a4911b80f..d8af8fb87a8 100644 --- a/htdocs/comm/propal/info.php +++ b/htdocs/comm/propal/info.php @@ -59,7 +59,7 @@ llxHeader('',$langs->trans('Proposal'),'EN:Commercial_Proposals|FR:Proposition_c $object->fetch_thirdparty(); $head = propal_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans('Proposal'), 0, 'propal'); +dol_fiche_head($head, 'info', $langs->trans('Proposal'), -1, 'propal'); $object->info($object->id); diff --git a/htdocs/comm/propal/note.php b/htdocs/comm/propal/note.php index 57181b83f6b..ec1dac31c24 100644 --- a/htdocs/comm/propal/note.php +++ b/htdocs/comm/propal/note.php @@ -74,7 +74,7 @@ if ($id > 0 || ! empty($ref)) if ($object->fetch_thirdparty() > 0) { $head = propal_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans('Proposal'), 0, 'propal'); + dol_fiche_head($head, 'note', $langs->trans('Proposal'), -1, 'propal'); $cssclass='titlefield'; //if ($action == 'editnote_public') $cssclass='titlefieldcreate'; diff --git a/htdocs/commande/apercu.php b/htdocs/commande/apercu.php deleted file mode 100644 index 1ec3a0533cc..00000000000 --- a/htdocs/commande/apercu.php +++ /dev/null @@ -1,223 +0,0 @@ - - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2011 Laurent Destailleur - * Copyright (C) 2005-2011 Regis Houssin - * Copyright (C) 2011 Juanjo Menent - * Copyright (C) 2014 Frederic 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/commande/apercu.php - * \ingroup commande - * \brief Preview tab of order - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; - -$langs->load('orders'); -$langs->load("bills"); -$langs->load('compta'); - -// Security check -$socid=0; -$id = GETPOST('id','int'); -$ref = GETPOST("ref"); -if ($user->societe_id) $socid=$user->societe_id; -$result=restrictedArea($user,'commande',$id,''); - - -/* - * View Mode - */ - -$form = new Form($db); - -llxHeader('',$langs->trans('Order'),'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'); - -if ($id > 0 || ! empty($ref)) -{ - $object = new Commande($db); - - if ($object->fetch($id,$ref) > 0) - { - $soc = new Societe($db); - $soc->fetch($object->socid); - - - $head = commande_prepare_head($object); - dol_fiche_head($head, 'preview', $langs->trans("CustomerOrder"), 0, 'order'); - - print ''; - - //$linkback = '' . $langs->trans("BackToList") . ''; - - // Ref - print ''; - - // Ref cde client - print ''; - print ''; - print ''; - - // Client - print ''; - print ''; - print ''; - - // Statut - print ''; - print ''; - print ''; - - // Discount - left part - print ''; - print ''; - print ''; - - // Date - left part - print ''; - print ''; - - // Right part with $rowspan lines - $rowspan=4; - print ''; - - // Total HT - left part - print ''; - print ''; - print ''; - - // Total VAT - left part - print ''; - print ''; - print ''; - - // Total TTC - left part - print ''; - print ''; - print ''; - - print '
    ' . $langs->trans('Ref') . ''; - print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); - print '
    '.$langs->trans('RefCustomer').''.$object->ref_client.'
    '.$langs->trans("Customer").''.$soc->getNomUrl(1).'
    '.$langs->trans("Status").''.$object->getLibStatut(4).'
    '.$langs->trans('Discounts').''.$object->remise_percent.'%
    '.$langs->trans("Date").''.dol_print_date($object->date,"daytext").''; - - /* - * Documents - */ - $objectref = dol_sanitizeFileName($object->ref); - $dir_output = $conf->commande->dir_output . "/"; - $filepath = $dir_output . $objectref . "/"; - $file = $filepath . $objectref . ".pdf"; - $filedetail = $filepath . $objectref . "-detail.pdf"; - $relativepath = $objectref.'/'.$objectref.'.pdf'; - $relativepathdetail = $objectref.'/'.$objectref.'-detail.pdf'; - - // Define path to preview pdf file (preview precompiled "file.ext" are "file.ext_preview.png") - $fileimage = $file.'_preview.png'; // If PDF has 1 page - $fileimagebis = $file.'_preview-0.pdf.png'; // If PDF has more than one page - $relativepathimage = $relativepath.'_preview.png'; - - $var=true; - - // if PDF file exist - if (file_exists($file)) - { - $encfile = urlencode($file); - print ''; - print ''; - - print ""; - - print ''; - print ''; - print ''; - print ''; - - // Si fichier detail PDF existe - // TODO deprecated ? - if (file_exists($filedetail)) - { - print ""; - - print ''; - print ''; - print ''; - print ''; - } - print "
    '.$langs->trans("Documents").'
    ".$langs->trans("Order")." PDF'.$object->ref.'.pdf'.dol_print_size(dol_filesize($file)).''.dol_print_date(dol_filemtime($file),'dayhour').'
    Commande detaillee'.$object->ref.'-detail.pdf'.dol_print_size(dol_filesize($filedetail)).''.dol_print_date(dol_filemtime($filedetail),'dayhour').'
    \n"; - - // Conversion du PDF en image png si fichier png non existant - if ((! file_exists($fileimage) && ! file_exists($fileimagebis)) || (filemtime($fileimage) < filemtime($file))) - { - if (class_exists("Imagick")) - { - $ret = dol_convert_file($file,'png',$fileimage); - if ($ret < 0) $error++; - } - else - { - $langs->load("errors"); - print ''.$langs->trans("ErrorNoImagickReadimage").''; - } - } - } - - print '
    '.$langs->trans('AmountHT').'' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '.$langs->trans('AmountVAT').'' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '.$langs->trans('AmountTTC').'' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '; - - dol_fiche_end(); - } - else - { - // Object not found - print $langs->trans("ErrorOrderNotFound",$id); - } -} - -print ''; -print ''; -print '
    '; -print '
    '; -// Si fichier png PDF d'1 page trouve -if (file_exists($fileimage)) -{ - print ''; -} -// Si fichier png PDF de plus d'1 page trouve -elseif (file_exists($fileimagebis)) -{ - $multiple = preg_replace('/\.png/','',$relativepath) . "-"; - - for ($i = 0; $i < 20; $i++) - { - $preview = $multiple.$i.'.png'; - - if (file_exists($dir_output.$preview)) - { - print '

    '; - } - } -} -print '

    '; -print '
    '; - - -llxFooter(); - -$db->close(); diff --git a/htdocs/compta/facture/apercu.php b/htdocs/compta/facture/apercu.php deleted file mode 100644 index b22571ad93f..00000000000 --- a/htdocs/compta/facture/apercu.php +++ /dev/null @@ -1,392 +0,0 @@ - - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2007 Laurent Destailleur - * Copyright (C) 2005-2011 Regis Houssin - * Copyright (C) 2011 Juanjo Menent - * Copyright (C) 2014 Frederic 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * \file htdocs/compta/facture/apercu.php - * \ingroup facture - * \brief Preview Tab of invoice - */ - -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; -if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - -$langs->load("bills"); - -// Security check -$socid=0; -$id = GETPOST('facid','int'); -$ref = GETPOST("ref"); -if ($user->societe_id) $socid=$user->societe_id; -$result = restrictedArea($user, 'facture', $id); - - -/* - * View - */ - -$now=dol_now(); - -$title = $langs->trans('InvoiceCustomer') . " - " . $langs->trans('Preview'); -$helpurl = "EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes"; -llxHeader('', $title, $helpurl); - -$form = new Form($db); - -/* *************************************************************************** */ -/* */ -/* Mode fiche */ -/* */ -/* *************************************************************************** */ - -if ($id > 0 || ! empty($ref)) -{ - $object = New Facture($db); - - if ($object->fetch($id,$ref) > 0) - { - $soc = new Societe($db); - $soc->fetch($object->socid); - - $head = facture_prepare_head($object); - dol_fiche_head($head, 'preview', $langs->trans("InvoiceCustomer"), 0, 'bill'); - - - $totalpaye = $object->getSommePaiement(); - - /* - * Invoice - */ - print ''; - - $linkback = '' . $langs->trans("BackToList") . ''; - - // Ref - print ''; - - // Ref customer - print ''; - print ''; - print ''; - - // Thirdparty - print ''; - print ''; - print ''; - - // Type - print ''; - print ''; - print ''; - - // Relative and absolute discounts - $addabsolutediscount=' '.$langs->trans("AddGlobalDiscount").''; - $addcreditnote=' '.$langs->trans("AddCreditNote").''; - - print ''; - print ''; - print ''; - - // Dates - print ''; - print ''; - - // Right part with $rowspan lines - $rowspan=5; - if (! empty($conf->projet->enabled)) $rowspan++; - print '"; - - // Total HT - print ''; - print ''; - print ''; - - // Total VAT - print ''; - print ''; - print ''; - - // Total TTC - print ''; - print ''; - print ''; - - // Statut - print ''; - print ''; - print ''; - - // Projet - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - print ''; - print ''; - } - - print '
    ' . $langs->trans('Ref') . ''; - $morehtmlref = ''; - $discount = new DiscountAbsolute($db); - $result = $discount->fetch(0, $object->id); - if ($result > 0) { - $morehtmlref = ' (' . $langs->trans("CreditNoteConvertedIntoDiscount", $discount->getNomUrl(1, 'discount')) . ')'; - } - if ($result < 0) { - dol_print_error('', $discount->error); - } - print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); - print '
    '.$langs->trans('RefCustomer').''.$object->ref_client.'
    '.$langs->trans("Company").''.$soc->getNomUrl(1,'compta').'
    '.$langs->trans('Type').''; - print $object->getLibType(); - if ($object->type == Facture::TYPE_REPLACEMENT) - { - $facreplaced=new Facture($db); - $facreplaced->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; - } - if ($object->type == Facture::TYPE_CREDIT_NOTE) - { - $facusing=new Facture($db); - $facusing->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; - } - - $facidavoir=$object->getListIdAvoirFromInvoice(); - if (count($facidavoir) > 0) - { - print ' ('.$langs->transnoentities("InvoiceHasAvoir"); - $i=0; - foreach($facidavoir as $id) - { - if ($i==0) print ' '; - else print ','; - $facavoir=new Facture($db); - $facavoir->fetch($id); - print $facavoir->getNomUrl(1); - } - print ')'; - } - if ($objectidnext > 0) - { - $facthatreplace=new Facture($db); - $facthatreplace->fetch($objectidnext); - print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; - } - print '
    '.$langs->trans('Discounts').''; - if ($soc->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_percent); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - - if ($absolute_discount > 0) - { - print '. '; - if ($object->statut > Facture::STATUS_DRAFT || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) - { - if ($object->statut == Facture::STATUS_DRAFT) - { - print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '. '; - } - else - { - if ($object->statut < Facture::STATUS_VALIDATED || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '
    '.$text.'.
    '; - } - else - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - $text2=$langs->trans("AbsoluteDiscountUse"); - print $form->textwithpicto($text,$text2); - } - } - } - else - { - // Remise dispo de type remise fixe (not credit note) - $filter='fk_facture_source IS NULL'; - print '
    '; - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id',$soc->id, $absolute_discount, $filter, $resteapayer, ' - '.$addabsolutediscount, 1); - } - } - else - { - if ($absolute_creditnote > 0) // If not linked will be added later - { - if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) print ' - '.$addabsolutediscount.'
    '; - else print '.'; - } - else print '. '; - } - if ($absolute_creditnote > 0) - { - // If validated, we show link "add credit note to payment" - if ($object->statut != Facture::STATUS_VALIDATED || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) - { - if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_DEPOSIT) - { - $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); - print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); - } - else - { - print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; - } - } - else - { - // Remise dispo de type avoir - $filter='fk_facture_source IS NOT NULL'; - if (! $absolute_discount) print '
    '; - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filter, $resteapayer, '', 1); - } - } - if (! $absolute_discount && ! $absolute_creditnote) - { - print $langs->trans("CompanyHasNoAbsoluteDiscount"); - if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) print ' - '.$addabsolutediscount.'
    '; - else print '. '; - } - /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) - { - if (! $absolute_discount && ! $absolute_creditnote) print '
    '; - //print '   -   '; - print $addabsolutediscount; - //print '   -   '.$addcreditnote; // We disbale link to credit note - }*/ - print '
    '.$langs->trans("DateInvoice").''.dol_print_date($object->date,"daytext").''; - - /* - * Documents - */ - $objectref = dol_sanitizeFileName($object->ref); - $dir_output = $conf->facture->dir_output . "/"; - $filepath = $dir_output . $objectref . "/"; - $file = $filepath . $objectref . ".pdf"; - $filedetail = $filepath . $objectref . "-detail.pdf"; - $relativepath = $objectref.'/'.$objectref.'.pdf'; - $relativepathdetail = $objectref.'/'.$objectref.'-detail.pdf'; - - // Define path to preview pdf file (preview precompiled "file.ext" are "file.ext_preview.png") - $fileimage = $file.'_preview.png'; // If PDF has 1 page - $fileimagebis = $file.'_preview-0.pdf.png'; // If PDF has more than one page - $relativepathimage = $relativepath.'_preview.png'; - - $var=true; - - // Si fichier PDF existe - if (file_exists($file)) - { - $encfile = urlencode($file); - print ''; - print ''; - - print ""; - - print ''; - print ''; - print ''; - print ''; - - // Si fichier detail PDF existe - if (file_exists($filedetail)) // facture detaillee supplementaire - { - print ""; - - print ''; - print ''; - print ''; - print ''; - } - - print "
    '.$langs->trans("Documents").'
    ".$langs->trans("Bill")." PDF'.$object->ref.'.pdf'.dol_print_size(dol_filesize($file)). ''.dol_print_date(dol_filemtime($file),'dayhour').'
    Facture detaillee'.$object->ref.'-detail.pdf'.dol_print_size(dol_filesize($filedetail)).''.dol_print_date(dol_filemtime($filedetail),'dayhour').'
    \n"; - - // Conversion du PDF en image png si fichier png non existant - if ((! file_exists($fileimage) && ! file_exists($fileimagebis)) || (filemtime($fileimage) < filemtime($file))) - { - if (class_exists("Imagick")) - { - $ret = dol_convert_file($file,'png',$fileimage); - if ($ret < 0) $error++; - } - else - { - $langs->load("errors"); - print ''.$langs->trans("ErrorNoImagickReadimage").''; - } - } - } - print "
    '.$langs->trans("AmountHT").'' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '.$langs->trans('AmountVAT').'' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '.$langs->trans('AmountTTC').'' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '
    '.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
    '.$langs->trans("Project").''; - if ($object->fk_project > 0) - { - $project = New Project($db); - $project->fetch($object->fk_project); - print ''.$project->title.''; - } - else - { - print ' '; - } - print '
    '; - - dol_fiche_end(); - } - else - { - // Facture non trouvee - print $langs->trans("ErrorBillNotFound",$id); - } -} - -print ''; -print ''; -print '
    '; -print '
    '; -// Si fichier png PDF d'1 page trouve -if (file_exists($fileimage)) -{ - print ''; -} -// Si fichier png PDF de plus d'1 page trouve -elseif (file_exists($fileimagebis)) -{ - $multiple = preg_replace('/\.png/','',$relativepath) . "-"; - - for ($i = 0; $i < 20; $i++) - { - $preview = $multiple.$i.'.png'; - - if (file_exists($dir_output.$preview)) - { - print '

    '; - } - } -} -print '

    '; -print '
    '; - -llxFooter(); - -$db->close(); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 21c3b5dbcfe..315e920947d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6028,13 +6028,13 @@ class Form */ global $dolibarr_main_url_root; $ret.=''; - $ret.='Gravatar avatar'; // gravatar need md5 hash + $ret.='Gravatar avatar'; // gravatar need md5 hash } else { if ($conf->browser->layout != 'phone') { - $ret.='No photo'; + $ret.='No photo'; } } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a872d166283..dd2d9a00a50 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1006,12 +1006,15 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) $showbarcode=0; $modulepart='unknown'; - if ($object->element == 'societe') $modulepart='societe'; - if ($object->element == 'contact') $modulepart='contact'; - if ($object->element == 'member') $modulepart='memberphoto'; - if ($object->element == 'user') $modulepart='userphoto'; - if ($object->element == 'product') $modulepart='product'; - + if ($object->element == 'societe') $modulepart='societe'; + if ($object->element == 'contact') $modulepart='contact'; + if ($object->element == 'member') $modulepart='memberphoto'; + if ($object->element == 'user') $modulepart='userphoto'; + if ($object->element == 'product') $modulepart='product'; + if ($object->element == 'propal') $modulepart='propal'; + if ($object->element == 'commande') $modulepart='commande'; + if ($object->element == 'facture') $modulepart='facture'; + if ($object->element == 'product') { $width=80; $cssclass='photoref'; @@ -1037,7 +1040,56 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r { if ($modulepart != 'unknown') { - $phototoshow = $form->showphoto($modulepart,$object,0,0,0,'photoref','small',1,0,$maxvisiblephotos); + // Check if a preview file is available + if (in_array($modulepart, array('propal', 'commande', 'facture')) && class_exists("Imagick")) + { + $objectref = dol_sanitizeFileName($object->ref); + $dir_output = $conf->$modulepart->dir_output . "/"; + $filepath = $dir_output . $objectref . "/"; + $file = $filepath . $objectref . ".pdf"; + $relativepath = $objectref.'/'.$objectref.'.pdf'; + + // Define path to preview pdf file (preview precompiled "file.ext" are "file.ext_preview.png") + $fileimage = $file.'_preview.png'; // If PDF has 1 page + $fileimagebis = $file.'_preview-0.pdf.png'; // If PDF has more than one page + $relativepathimage = $relativepath.'_preview.png'; + + // Si fichier PDF existe + if (file_exists($file)) + { + $encfile = urlencode($file); + // Conversion du PDF en image png si fichier png non existant + if ((! file_exists($fileimage) && ! file_exists($fileimagebis)) || (filemtime($fileimage) < filemtime($file))) + { + $ret = dol_convert_file($file,'png',$fileimage); + if ($ret < 0) $error++; + } + + // Si fichier png PDF d'1 page trouve + if (file_exists($fileimage)) + { + $phototoshow = '
    '; + $phototoshow.= ''; + $phototoshow.= '
    '; + } + // Si fichier png PDF de plus d'1 page trouve + elseif (file_exists($fileimagebis)) + { + $preview = preg_replace('/\.png/','',$relativepath) . "-0.png"; + if (file_exists($dir_output.$preview)) + { + $phototoshow = '
    '; + $phototoshow.= '

    '; + $phototoshow.= '

    '; + } + } + } + } + else if (! $phototoshow) + { + $phototoshow = $form->showphoto($modulepart,$object,0,0,0,'photoref','small',1,0,$maxvisiblephotos); + } + if ($phototoshow) { $morehtmlleft.='
    '; @@ -1045,7 +1097,8 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r $morehtmlleft.='
    '; } } - elseif ($conf->browser->layout != 'phone') // Show No photo link (picto of pbject) + + if (! $phototoshow && $conf->browser->layout != 'phone') // Show No photo link (picto of pbject) { $morehtmlleft.='
    '; if ($object->element == 'action') diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index fa8151563b1..6e5640d1e0a 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -53,14 +53,6 @@ function facture_prepare_head($object) $h++; } - if (! empty($conf->global->MAIN_USE_PREVIEW_TABS)) - { - $head[$h][0] = DOL_URL_ROOT.'/compta/facture/apercu.php?facid='.$object->id; - $head[$h][1] = $langs->trans('Preview'); - $head[$h][2] = 'preview'; - $h++; - } - //if ($fac->mode_reglement_code == 'PRE') if (! empty($conf->prelevement->enabled)) { diff --git a/htdocs/core/lib/order.lib.php b/htdocs/core/lib/order.lib.php index 1458f37fdce..6bfb2541c11 100644 --- a/htdocs/core/lib/order.lib.php +++ b/htdocs/core/lib/order.lib.php @@ -60,14 +60,6 @@ function commande_prepare_head(Commande $object) $h++; } - if (! empty($conf->global->MAIN_USE_PREVIEW_TABS)) - { - $head[$h][0] = DOL_URL_ROOT.'/commande/apercu.php?id='.$object->id; - $head[$h][1] = $langs->trans("Preview"); - $head[$h][2] = 'preview'; - $h++; - } - if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) { $nbContact = count($object->liste_contact(-1,'internal')) + count($object->liste_contact(-1,'external')); diff --git a/htdocs/core/lib/propal.lib.php b/htdocs/core/lib/propal.lib.php index 13fbe06e7d4..66ef1146850 100644 --- a/htdocs/core/lib/propal.lib.php +++ b/htdocs/core/lib/propal.lib.php @@ -55,13 +55,6 @@ function propal_prepare_head($object) $head[$h][2] = 'shipping'; $h++; } - if (! empty($conf->global->MAIN_USE_PREVIEW_TABS)) - { - $head[$h][0] = DOL_URL_ROOT.'/comm/propal/apercu.php?id='.$object->id; - $head[$h][1] = $langs->trans("Preview"); - $head[$h][2] = 'preview'; - $h++; - } if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) { From 6116145d8a55d983f59a9a042646bd6fc9c25e3e Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 24 Mar 2017 06:23:40 +0100 Subject: [PATCH 191/410] Fix : Missing language file in accountancy configuration --- htdocs/accountancy/admin/defaultaccounts.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 1c49b65bac8..08ce543c525 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -39,6 +39,7 @@ $langs->load("bills"); $langs->load("admin"); $langs->load("accountancy"); $langs->load("salaries"); +$langs->load("loan"); // Security check if (! empty($user->rights->accountancy->chartofaccount)) From 35da94bbc2d61d9416c0c2d65efd728f0db3a56b Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 24 Mar 2017 06:38:26 +0100 Subject: [PATCH 192/410] Fix : missing language file in salaries index --- htdocs/compta/salaries/index.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/compta/salaries/index.php b/htdocs/compta/salaries/index.php index 54a3c891e6a..88414e45566 100644 --- a/htdocs/compta/salaries/index.php +++ b/htdocs/compta/salaries/index.php @@ -30,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; $langs->load("compta"); $langs->load("salaries"); $langs->load("bills"); +$langs->load("hrm"); // Security check $socid = GETPOST("socid","int"); From ef0caa71e21abdfff625948c52f28ecb9c9de220 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 24 Mar 2017 06:50:07 +0100 Subject: [PATCH 193/410] Fix : Missing picture for module multicurrency in md theme --- htdocs/theme/md/img/object_multicurrency.png | Bin 0 -> 733 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 htdocs/theme/md/img/object_multicurrency.png diff --git a/htdocs/theme/md/img/object_multicurrency.png b/htdocs/theme/md/img/object_multicurrency.png new file mode 100644 index 0000000000000000000000000000000000000000..51896a4c051a345c09fcffbe9c24d08dd8f70a88 GIT binary patch literal 733 zcmV<30wVp1P)j&|t~VM)>s4Kk57SvccsX5PFvZ~4BjON&a-@BTad7lJjk4?ISE=m-!Q zL~HjRxjY&mrs?q1VwS!dJ;4CraQ_6zD(UhR;@8`-``mb-Ze!VY#`&odRjIaZY8a;T z#59WW_)yydfWPA2-f>KibYf@ESo!9Ls%xQ;ug~xI*qpIN#<^-)ZZw}SCNgQg-_WfI zVc+?O0D$R{P5>Zv_2on1u-a!^PArl5);Tr#u6_39=cCJ+!XP-dFv?CkE)@v??7#HL z&s=&&E%DUX)JA)=nl7Z5^23rWE(jo^ZM$MtE4(c&3#vuaPHM}APo%zmRESiC&qgZ3 zqlzNAk|au$GH`GQ9E5W&Sf-QwKA-8CjdeZ!9Zgca3dyB)s%wQ|HKZOAB%#^Tt=o(; z?ND@=oMMA76u2YGB0vZ@2qdq30h|K>7-e=*x2~>iUz<-rqPEdN z9c6|(#3BR%+3VTrIL>4F|n)pt6{py2#1u`8O$z#|Q3< zviF!>(68i{=3SH!oj_5f#mhht=J Date: Fri, 24 Mar 2017 15:30:46 +0100 Subject: [PATCH 194/410] error on install --- htdocs/install/mysql/tables/llx_usergroup.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_usergroup.sql b/htdocs/install/mysql/tables/llx_usergroup.sql index 9afe72f3b24..cc8501a5fcd 100644 --- a/htdocs/install/mysql/tables/llx_usergroup.sql +++ b/htdocs/install/mysql/tables/llx_usergroup.sql @@ -26,7 +26,7 @@ create table llx_usergroup datec datetime, tms timestamp, note text, - model_pdf varchar(255) DEFAULT NULL, + model_pdf varchar(255) DEFAULT NULL )ENGINE=innodb; -- From cdb1de75960263fce74b26cae24172632ecb0e73 Mon Sep 17 00:00:00 2001 From: jean Date: Fri, 24 Mar 2017 16:48:44 +0100 Subject: [PATCH 195/410] bug 6563 installation issue with doctemplates/usergroups/template_usergroups.odt --- ...mplate_usergroup.odt => template_usergroups.odt} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename htdocs/install/doctemplates/usergroups/{template_usergroup.odt => template_usergroups.odt} (100%) diff --git a/htdocs/install/doctemplates/usergroups/template_usergroup.odt b/htdocs/install/doctemplates/usergroups/template_usergroups.odt similarity index 100% rename from htdocs/install/doctemplates/usergroups/template_usergroup.odt rename to htdocs/install/doctemplates/usergroups/template_usergroups.odt From d1a988a0beba0fe0cd689bf4824520e606a67b9f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 24 Mar 2017 17:32:38 +0100 Subject: [PATCH 196/410] Fix document_preview is possible on files with + chars inside. --- htdocs/contact/card.php | 3 ++- htdocs/core/class/html.formfile.class.php | 13 ++++++------ htdocs/core/lib/company.lib.php | 24 +++++++---------------- htdocs/core/lib/functions.lib.php | 16 +++++++++++---- htdocs/main.inc.php | 19 +++++++++++++++++- htdocs/societe/rib.php | 6 +++--- 6 files changed, 49 insertions(+), 32 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 7d95da69aef..dfa6eec515c 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -673,7 +673,8 @@ else print "

    "; - + print '
    '; + // Add personnal information print load_fiche_titre('
    '.$langs->trans("PersonalInformations").'
    ','',''); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 5aa699c055c..d90b906882f 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -867,9 +867,9 @@ class FormFile // Preview $urladvanced = getAdvancedPreviewUrl($modulepart, $relativepath); - if ($urladvanced) $tmpout.= '
  • '.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'
  • '; + if ($urladvanced) $tmpout.= '
  • '.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'
  • '; // Download - $tmpout.= '
  • browser->layout != 'phone') { - $urladvancedpreview=getAdvancedPreviewUrl($modulepart, $relativepath); // Return if a file is qualified for preview - if ($urladvancedpreview) + $urladvancedpreview=getAdvancedPreviewUrl($modulepart, $relativepath, 1); // Return if a file is qualified for preview. + if (count($urladvancedpreview)) { - $out.= ''; - if (empty($ruleforpicto)) $out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail'); + $out.= ''; + //$out.= ''; + if (empty($ruleforpicto)) $out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail'); else $out.= img_mime($relativepath, $langs->trans('Preview').' '.$file['name']); $out.= ''; } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index bfb893d92ee..fb901198852 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -693,7 +693,6 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') $colspan=9; print ''; - print_liste_field_titre(''); print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"p.lastname","",$param,'',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Poste"),$_SERVER["PHP_SELF"],"p.poste","",$param,'',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Address").' / '.$langs->trans("Phone").' / '.$langs->trans("Email"),$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); @@ -728,21 +727,16 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') { print ''; - // Photo - print ''; - print ''; - - // Name - Position + // Photo - Name print ''; print ''; print ''; - // Address / Phone + // Position print ''; - //print ''; print ''; - // Email + // Address - Phone - Email print ' '; // Status @@ -797,14 +791,10 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') print ""; - // Photo - print ''; - print $form->showphoto('contact',$contactstatic,0,0,0,'photorefnoborder','small',1,0,1); - print ''; - - // Name + // Photo - Name print ''; - print $contactstatic->getNomUrl(0,'',0,'&backtopage='.urlencode($backtopage)); + print $form->showphoto('contact',$contactstatic,0,0,0,'photorefnoborder valignmiddle marginrightonly','small',1,0,1); + print $contactstatic->getNomUrl(0,'',0,'&backtopage='.urlencode($backtopage)); print ''; // Job position @@ -812,7 +802,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') if ($obj->poste) print $obj->poste; print ''; - // Address and phone + // Address - Phone - Email print ''; print $contactstatic->getBannerAddress('contact', $object); print ''; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a872d166283..64b26ed7875 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5855,10 +5855,11 @@ function getImageFileNameForSize($file, $extName, $extImgTarget='') * Return URL we can use for advanced preview links * * @param string $modulepart propal, facture, facture_fourn, ... - * @param string $relativepath Relative path of docs - * @return string Output string with HTML + * @param string $relativepath Relative path of docs. + * @param int $alldata Return array with all components (1 is recommended) + * @return string|array Output string with href link or array with all components of link */ -function getAdvancedPreviewUrl($modulepart, $relativepath) +function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0) { global $conf, $langs; @@ -5868,8 +5869,15 @@ function getAdvancedPreviewUrl($modulepart, $relativepath) //$mime_preview[]='vnd.oasis.opendocument.presentation'; //$mime_preview[]='archive'; $num_mime = array_search(dol_mimetype($relativepath, '', 1), $mime_preview); + + if ($alldata == 1) + { + if ($num_mime !== false) return array('target'=>'_blank', 'css'=>'documentpreview', 'url'=>DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&attachment=0&file='.urlencode($relativepath), 'mime'=>dol_mimetype($relativepath), ); + else return array(); + } - if ($num_mime !== false) return 'javascript:document_preview(\''.dol_escape_js(DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&attachment=0&file='.$relativepath).'\', \''.dol_mimetype($relativepath).'\', \''.dol_escape_js($langs->trans('Preview')).'\')'; + // old behavior + if ($num_mime !== false) return 'javascript:document_preview(\''.dol_escape_js(DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&attachment=0&file='.urlencode($relativepath)).'\', \''.dol_mimetype($relativepath).'\', \''.dol_escape_js($langs->trans('Preview')).'\')'; else return ''; } diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 9c0a98cbcfb..7d5e5dfa64c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1882,7 +1882,9 @@ if (! function_exists("llxFooter")) if (! empty($delayedhtmlcontent)) print $delayedhtmlcontent; - // Wrapper to show tooltips + // TODO Move this in lib_head.js + + // Wrapper to show tooltips (html or onclick popup) if (! empty($conf->use_javascript_ajax) && empty($conf->dol_no_mouse_hover)) { print "\n\n"; @@ -1902,6 +1904,21 @@ if (! function_exists("llxFooter")) ' . "\n"; } + // Wrapper to manage document_preview + if (! empty($conf->use_javascript_ajax)) + { + print "\n\n"; + print '' . "\n"; + } + // Wrapper to manage dropdown if ($conf->use_javascript_ajax) { diff --git a/htdocs/societe/rib.php b/htdocs/societe/rib.php index f1db2d21835..42860abb98a 100644 --- a/htdocs/societe/rib.php +++ b/htdocs/societe/rib.php @@ -802,7 +802,7 @@ if ($socid && $action == 'create' && $user->rights->societe->creer) dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom'); - print '
    '; + print '
    '; print '
    '; print ''; @@ -845,7 +845,7 @@ if ($socid && $action == 'create' && $user->rights->societe->creer) } print '"; @@ -854,7 +854,7 @@ if ($socid && $action == 'create' && $user->rights->societe->creer) print "\n"; print '"; From 2b1c29316fa3d348bd76a591626e1119313e89f5 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 22:13:58 +0100 Subject: [PATCH 197/410] Display totalLine if one of total field are present --- htdocs/compta/facture/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index aad49656e2e..8ed52eddb97 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -1210,7 +1210,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 94a1fc19fa9b3656878a5379a6600f17c0f2a5ab Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:39:25 +0100 Subject: [PATCH 198/410] display total line for all total line --- htdocs/comm/propal/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index aa6df1afb2b..44a2b9356e8 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -977,7 +977,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 3aff05382825a94ab47e5e25738bbaeb940a5cdb Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:40:34 +0100 Subject: [PATCH 199/410] Update list.php --- htdocs/commande/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index f92836599de..f4fc3b76745 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1393,7 +1393,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 6b33a755ba4fb15adf8ba5c7649a771a0a724718 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 24 Mar 2017 23:52:06 +0100 Subject: [PATCH 200/410] Add more log on tableDnD --- htdocs/core/tpl/ajaxrow.tpl.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index d0a7b45efea..61c27579b50 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -44,6 +44,7 @@ $(document).ready(function(){ $("#").tableDnD({ onDrop: function(table, row) { var reloadpage = ""; + console.log("tableDND onDrop"); console.log($("#").tableDnDSerialize()); var roworder = cleanSerialize($("#").tableDnDSerialize()); var table_element_line = ""; @@ -59,14 +60,15 @@ $(document).ready(function(){ filepath: filepath }, function() { + console.log("tableDND end of ajax call"); if (reloadpage == 1) { location.href = ''; } else { $("# .drag").each( function( intIndex ) { - $(this).removeClass("pair impair"); - if (intIndex % 2 == 0) $(this).addClass('impair'); - if (intIndex % 2 == 1) $(this).addClass('pair'); + // $(this).removeClass("pair impair"); + //if (intIndex % 2 == 0) $(this).addClass('impair'); + //if (intIndex % 2 == 1) $(this).addClass('pair'); }); } }); From db76a05d0cabe59343aa098fb63bc5c568225bdf Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:53:32 +0100 Subject: [PATCH 201/410] Update list.php --- htdocs/fourn/facture/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index bff5c773cfc..3afb97c5fb1 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -956,7 +956,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 720a820ee4c116c5a298921da277ca947ed0a5e4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 00:04:21 +0100 Subject: [PATCH 202/410] border-bottom not required. --- htdocs/comm/propal/card.php | 2 +- htdocs/comm/propal/contact.php | 2 +- htdocs/comm/propal/document.php | 2 +- htdocs/comm/propal/info.php | 2 +- htdocs/comm/propal/note.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 810d6bd1abb..e1224ad0e72 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1675,7 +1675,7 @@ if ($action == 'create') $soc->fetch($object->socid); $head = propal_prepare_head($object); - dol_fiche_head($head, 'comm', $langs->trans('Proposal'), 0, 'propal'); + dol_fiche_head($head, 'comm', $langs->trans('Proposal'), -1, 'propal'); $formconfirm = ''; diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php index 8588bfc5749..3c3aa6aef88 100644 --- a/htdocs/comm/propal/contact.php +++ b/htdocs/comm/propal/contact.php @@ -151,7 +151,7 @@ $formother = new FormOther($db); if ($object->id > 0) { $head = propal_prepare_head($object); - dol_fiche_head($head, 'contact', $langs->trans("Proposal"), 0, 'propal'); + dol_fiche_head($head, 'contact', $langs->trans("Proposal"), -1, 'propal'); // Proposal card diff --git a/htdocs/comm/propal/document.php b/htdocs/comm/propal/document.php index 9b875e434f7..82978daf2c1 100644 --- a/htdocs/comm/propal/document.php +++ b/htdocs/comm/propal/document.php @@ -89,7 +89,7 @@ if ($object->id > 0) $upload_dir = $conf->propal->dir_output.'/'.dol_sanitizeFileName($object->ref); $head = propal_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans('Proposal'), 0, 'propal'); + dol_fiche_head($head, 'document', $langs->trans('Proposal'), -1, 'propal'); // Construit liste des fichiers $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); diff --git a/htdocs/comm/propal/info.php b/htdocs/comm/propal/info.php index 14a4911b80f..d8af8fb87a8 100644 --- a/htdocs/comm/propal/info.php +++ b/htdocs/comm/propal/info.php @@ -59,7 +59,7 @@ llxHeader('',$langs->trans('Proposal'),'EN:Commercial_Proposals|FR:Proposition_c $object->fetch_thirdparty(); $head = propal_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans('Proposal'), 0, 'propal'); +dol_fiche_head($head, 'info', $langs->trans('Proposal'), -1, 'propal'); $object->info($object->id); diff --git a/htdocs/comm/propal/note.php b/htdocs/comm/propal/note.php index 57181b83f6b..ec1dac31c24 100644 --- a/htdocs/comm/propal/note.php +++ b/htdocs/comm/propal/note.php @@ -74,7 +74,7 @@ if ($id > 0 || ! empty($ref)) if ($object->fetch_thirdparty() > 0) { $head = propal_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans('Proposal'), 0, 'propal'); + dol_fiche_head($head, 'note', $langs->trans('Proposal'), -1, 'propal'); $cssclass='titlefield'; //if ($action == 'editnote_public') $cssclass='titlefieldcreate'; From aa9d991923ba17f675c883472d953501f21bd90f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 01:03:02 +0100 Subject: [PATCH 203/410] Fix css --- htdocs/comm/index.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 4e99b7072fc..7ea7b840d6b 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -158,10 +158,10 @@ if (! empty($conf->propal->enabled) && $user->rights->propal->lire) print ''; print ''; + $var=true; if ($num > 0) { $i = 0; - $var=true; while ($i < $num) { $obj = $db->fetch_object($resql); @@ -239,10 +239,10 @@ if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_propos print ''; print ''; + $var=true; if ($num > 0) { $i = 0; - $var=true; while ($i < $num) { $obj = $db->fetch_object($resql); @@ -318,10 +318,10 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire) print ''; print ''; - if ($num) + $var = true; + if ($num > 0) { $i = 0; - $var = true; while ($i < $num) { $var=!$var; @@ -399,10 +399,10 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande print ''; print ''; - if ($num) + $var = true; + if ($num > 0) { $i = 0; - $var = true; while ($i < $num) { $var=!$var; From df59a595de716f16a3c7aa2ca75debf1c355f7af Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 01:29:19 +0100 Subject: [PATCH 204/410] Fix link to files --- htdocs/core/lib/files.lib.php | 2 +- htdocs/core/tpl/ajaxrow.tpl.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 586622538e9..d27d6c1cdb1 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1726,7 +1726,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->expedition->dir_output."/sending/".$original_file; } // Wrapping pour les bons de livraison - if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) + else if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) { if ($fuser->rights->expedition->livraison->lire || preg_match('/^specimen/i',$original_file)) { diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index 123fcef662c..a28bbac5e5a 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -40,6 +40,7 @@ $(document).ready(function(){ $(".tdlineupdown").css("background-repeat","no-repeat"); $(".tdlineupdown").css("background-position","center center"); + console.log("Prepare tableDnd for #"); $("#").tableDnD({ onDrop: function(table, row) { var reloadpage = ""; From 2f4a4f493e4a04507ce96748d15e81ace1afd4bc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 01:47:52 +0100 Subject: [PATCH 205/410] Missin translation --- htdocs/product/fournisseurs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 69a9344832b..6ff8d9deca0 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class. $langs->load("products"); $langs->load("suppliers"); $langs->load("bills"); -if (! empty($conf->margin->enabled)) $langs->load("margins"); +$langs->load("margins"); $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); From 106d19a8af74db6cc24c0862cdd4138e106a6ea3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 03:53:11 +0100 Subject: [PATCH 206/410] FIX #6468 + Fix missing translation --- htdocs/comm/action/card.php | 15 +--------- .../class/fournisseur.commande.class.php | 27 ++++++++++------- htdocs/fourn/commande/dispatch.php | 30 ++++--------------- htdocs/langs/en_US/errors.lang | 1 + 4 files changed, 25 insertions(+), 48 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 7378e35db80..90596b54197 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1208,20 +1208,12 @@ if ($id > 0) // Affichage fiche action en mode visu print '
    '.$langs->trans("BankAccountDomiciliation").''; - print '
    '.$langs->trans("BankAccountOwnerAddress").''; - print '
    '.$langs->trans("ProposalsDraft").($num?' '.$num.'':'').'
    '.$langs->trans("SupplierProposalsDraft").($num?' '.$num.'':'').'
    '.$langs->trans("DraftOrders").($num?' '.$num.'':'').'
    '.$langs->trans("DraftSuppliersOrders").($num?' '.$num.'':'').'
    '; - // Ref - /*print '';*/ - // Type if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) { print ''; } - // Title - //print ''; - // Full day event print ''; @@ -1243,11 +1235,6 @@ if ($id > 0) if ($object->percentage > 0 && $object->percentage < 100 && $object->datef && $object->datef < ($now- $delay_warning)) print img_warning($langs->trans("Late")); print ''; - // Status - /*print '';*/ - // Location if (empty($conf->global->AGENDA_DISABLE_LOCATION)) { @@ -1281,7 +1268,7 @@ if ($id > 0) print '
    '; print $form->select_dolusers_forevent('view', 'assignedtouser', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); print '
    '; - if (in_array($user->id,array_keys($listofuserid))) + if ($object->datep != $object->datef && in_array($user->id,array_keys($listofuserid))) { print '
    '; print $langs->trans("MyAvailability").': '.(($object->userassigned[$user->id]['transparency'] > 0)?$langs->trans("Busy"):$langs->trans("Available")); // We show nothing if event is assigned to nobody diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 98939ee01f2..676ca9f23ab 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1949,7 +1949,7 @@ class CommandeFournisseur extends CommonOrder } } - if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot')) // Accept to move to rception done, only if status of all line are ok (refuse denied) + if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot')) // Accept to move to reception done, only if status of all line are ok (refuse denied) { $dispatcheddenied=$this->getDispachedLines(2); if (count($dispatchedlinearray) > 0) @@ -1988,7 +1988,8 @@ class CommandeFournisseur extends CommonOrder $result = 0; $old_statut = $this->statut; $this->statut = $statut; - + $this->actionmsg2 = $comment; + // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_RECEIVE',$user); if ($result < 0) $error++; @@ -2810,13 +2811,14 @@ class CommandeFournisseur extends CommonOrder * * @param User $user User action * @param int $closeopenorder Close if received + * @param string $comment Comment * @return int <0 if KO, 0 if not applicable, >0 if OK */ - public function calcAndSetStatusDispatch(User $user, $closeopenorder=1) + public function calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='') { - global $conf; + global $conf, $langs; - if (! empty($conf->commande->enabled) && ! empty($conf->fournisseur->enabled)) + if (! empty($conf->fournisseur->enabled)) { require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php'; @@ -2845,14 +2847,18 @@ class CommandeFournisseur extends CommonOrder foreach($this->lines as $line) { $qtywished[$line->fk_product]+=$line->qty; } + + $date_liv = dol_now(); + //Compare array $diff_array=array_diff_assoc($qtydelivered,$qtywished); - if (count($diff_array)==0) + + if (count($diff_array)==0) //No diff => mean everythings is received { - //No diff => mean everythings is received if ($closeopenorder) { - $ret=$this->setStatus($user,5); + //$ret=$this->setStatus($user,5); + $ret = $this->Livraison($user, $date_liv, 'tot', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' if ($ret<0) { return -1; } @@ -2861,7 +2867,8 @@ class CommandeFournisseur extends CommonOrder else { //Diff => received partially - $ret=$this->setStatus($user,4); + //$ret=$this->setStatus($user,4); + $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' if ($ret<0) { return -1; } @@ -2871,7 +2878,7 @@ class CommandeFournisseur extends CommonOrder else { //Diff => received partially - $ret=$this->setStatus($user,4); + $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' if ($ret<0) { return -1; } diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index dc34686361f..c87b3a62bed 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -230,7 +230,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) } if (! $error) { - $result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder')?1:0); + $result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder')?1:0, GETPOST('comment')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error ++; @@ -340,26 +340,7 @@ if ($id > 0 || ! empty($ref)) { print '
    '; print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', ''); - print '
    '.$langs->trans("Type").''.$object->type.'
    '.$langs->trans("Title").''.dol_htmlentities($object->label).'
    '.$langs->trans("EventOnFullDay").''.yn($object->fulldayevent, 3).'
    '.$langs->trans("Status").' / '.$langs->trans("Percentage").''; - print $object->getLibStatut(4); - print '
    '; -/* - // Ref - print ''; - print ''; - print ''; - // Fournisseur - print '"; - print ''; - print ''; - - // Statut - print ''; - print ''; - print '"; -*/ // Date if ($object->methode_commande_id > 0) { print '\n"; @@ -609,7 +591,7 @@ if ($id > 0 || ! empty($ref)) { print '
    '; print $langs->trans("Comment") . ' : '; - print 'trans("DispatchSupplierOrder", $object->ref); // print ' / '.$object->ref_supplier; // Not yet available print '" class="flat">
    '; @@ -662,7 +644,7 @@ if ($id > 0 || ! empty($ref)) { print '
    ' . $langs->trans("Ref") . ''; - print $form->showrefnav($object, 'ref', '', 1, 'ref', 'ref'); - print '
    ' . $langs->trans("Supplier") . "' . $soc->getNomUrl(1, 'supplier') . '
    ' . $langs->trans("Status") . ''; - print $object->getLibStatut(4); - print "
    ' . $langs->trans("Date") . ''; @@ -585,7 +566,8 @@ if ($id > 0 || ! empty($ref)) { } elseif (count($listwarehouses) == 1) { print $formproduct->selectWarehouses(GETPOST("entrepot" . $suffix), "entrepot" . $suffix, '', 0, 0, $objp->fk_product); } else { - print $langs->trans("NoWarehouseDefined"); + $langs->load("errors"); + print $langs->trans("ErrorNoWarehouseDefined"); } print "
    '; print ''; - print ''; + print ''; if (! empty($conf->productbatch->enabled)) { print ''; print ''; @@ -705,7 +687,7 @@ if ($id > 0 || ! empty($ref)) { print ''; // Comment - print ''; + print ''; // Status if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) { diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 77a99994fef..af18693f9d4 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -184,6 +184,7 @@ ErrorTaskAlreadyAssigned=Task already assigned to user ErrorModuleFileSeemsToHaveAWrongFormat=The module package seems to have a wrong format. ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (%s) does not match expected name syntax: %s ErrorDuplicateTrigger=Error, duplicate trigger name %s. Already loaded from %s. +ErrorNoWarehouseDefined=Error, no warehouses defined. # Warnings WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. From 10b7712965853d12e163c61872272f8498549499 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sat, 25 Mar 2017 07:26:26 +0100 Subject: [PATCH 207/410] Fix : Display of textarea in holiday card --- htdocs/holiday/card.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 6583ad09b61..c875caab271 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -4,6 +4,7 @@ * Copyright (C) 2012-2016 Regis Houssin * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2014 Ferran Marcet + * Copyright (C) 2017 Alexandre Spangaro * * 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 @@ -31,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/holiday.lib.php'; require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php'; @@ -869,10 +871,10 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create // Description print ''; print ''; - print ''; - print ''; + print ''; print ''; print '
    ' . $langs->trans("Description") . '' . $langs->trans("Product") . '' . $langs->trans("batch_number") . '' . $langs->trans("EatByDate") . '' . dol_trunc($objp->comment) . '' . $objp->comment . '
    '.$langs->trans("DescCP").''; - print ''; - print '
    '; + $doleditor = new DolEditor('description', GETPOST('description'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + print $doleditor->Create(1); + print '
    '; @@ -1098,8 +1100,10 @@ else { print ''; print ''.$langs->trans('DescCP').''; - print ''; - print ''; + print ''; + $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + print $doleditor->Create(1); + print ''; } print ''; From 2e6ab393df577388bc93571b425dbf232a371bb6 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 10:45:01 +0100 Subject: [PATCH 208/410] add next_prev_filter for pagination --- htdocs/product/price.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index e6bde28d27e..8601ce9c05d 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -657,7 +657,7 @@ $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product'); dol_fiche_head($head, 'price', $titre, 0, $picto); $linkback = ''.$langs->trans("BackToList").''; - +$object->next_prev_filter=" fk_product_type = ".$object->type; dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref'); From cf68039c364a84cc7c0b5379c08a784d19b45000 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 10:47:42 +0100 Subject: [PATCH 209/410] Update document.php --- htdocs/product/document.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/document.php b/htdocs/product/document.php index ae2782cc4de..cedfec4abdc 100644 --- a/htdocs/product/document.php +++ b/htdocs/product/document.php @@ -210,8 +210,8 @@ if ($object->id) $linkback = ''.$langs->trans("BackToList").''; - - dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref'); + $object->next_prev_filter=" fk_product_type = ".$object->type; + dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref'); print '
    '; From a1db02cc0853020fb1ae100e3ee331fbd44ddde4 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 10:48:50 +0100 Subject: [PATCH 210/410] Update fournisseurs.php --- htdocs/product/fournisseurs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index ab74bc29485..ab959f479fd 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -308,7 +308,7 @@ if ($id > 0 || $ref) dol_fiche_head($head, 'suppliers', $titre, 0, $picto); $linkback = ''.$langs->trans("BackToList").''; - + $object->next_prev_filter=" fk_product_type = ".$object->type; dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref'); print '
    '; From 656875acb5ab71702bcb7905f5b973dec158032d Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 10:49:57 +0100 Subject: [PATCH 211/410] Update info.php --- htdocs/product/info.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/info.php b/htdocs/product/info.php index e29d1a168cb..af626cce5dd 100644 --- a/htdocs/product/info.php +++ b/htdocs/product/info.php @@ -94,7 +94,7 @@ if ($id > 0 || $ref) dol_fiche_head($head, 'info', $titre, 0, $picto); $linkback = ''.$langs->trans("BackToList").''; - + $object->next_prev_filter=" fk_product_type = ".$object->type; dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref'); $object->info($object->id); From ec3402a04b1045c9d4cdc91ec2207eb3d0cb6920 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 10:52:03 +0100 Subject: [PATCH 212/410] Update note.php --- htdocs/product/note.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/note.php b/htdocs/product/note.php index 9a914527a83..c63d60229fb 100644 --- a/htdocs/product/note.php +++ b/htdocs/product/note.php @@ -94,7 +94,7 @@ if ($id > 0 || ! empty($ref)) dol_fiche_head($head, 'note', $titre, 0, $picto); $linkback = ''.$langs->trans("BackToList").''; - + $object->next_prev_filter=" fk_product_type = ".$object->type; dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref'); $cssclass='titlefield'; From 1cc8671433a09e9772f43da29d5a7c8f5f828a09 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 12:06:02 +0100 Subject: [PATCH 213/410] FIX : supplier default condition not retrived on create --- htdocs/supplier_proposal/card.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 41fe2db302a..5b007d45774 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1050,7 +1050,9 @@ if ($action == 'create') } else { - if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; + $cond_reglement_id = $soc->cond_reglement_supplier_id; + $mode_reglement_id = $soc->mode_reglement_supplier_id; + if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; } $object = new SupplierProposal($db); @@ -1087,12 +1089,12 @@ if ($action == 'create') // Terms of payment print '' . $langs->trans('PaymentConditionsShort') . ''; - $form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $soc->cond_reglement_id, 'cond_reglement_id', -1, 1); + $form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1); print ''; // Mode of payment print '' . $langs->trans('PaymentMode') . ''; - $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $soc->mode_reglement_id, 'mode_reglement_id'); + $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id'); print ''; // Bank Account From 447607ecd96381ca307c335b8cb2214bcfb7cf0a Mon Sep 17 00:00:00 2001 From: Inovea Conseil Date: Sat, 25 Mar 2017 12:46:32 +0100 Subject: [PATCH 214/410] Update pdf.php Missing translate #6577 --- htdocs/admin/pdf.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index 74684c823e7..55bd83cbc19 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -98,7 +98,7 @@ $formadmin=new FormAdmin($db); $arraydetailsforpdffoot = array( 0 => $langs->trans('NoDetails'), 1 => $langs->trans('DisplayCompanyInfo'), - 2 => $langs->trans('DisplayManagersInfo'), + 2 => $langs->trans('DisplayCompanyManagers'), 3 => $langs->trans('DisplayCompanyInfoAndManagers') ); From 8a1ab35b87c11adaad0de6c6f7a128196c36611b Mon Sep 17 00:00:00 2001 From: fappels Date: Sat, 25 Mar 2017 16:17:43 +0100 Subject: [PATCH 215/410] Fix fetch shipment object on cancel modification --- htdocs/expedition/card.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index fd7c3e2633c..29f2b7fab48 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -115,7 +115,11 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - if ($cancel) { $action = ''; } + if ($cancel) + { + $action = ''; + $object->fetch($id); // show shipment also after canceling modification + } include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once From 3c9d336148d831f542c9e89b1eb282e678ae797d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 17:05:27 +0100 Subject: [PATCH 216/410] Fix error message --- build/generate_filelist_xml.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index ff580fad58c..1eeac5410b2 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -40,6 +40,7 @@ require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); * Main */ +$includecustom=0; $includeconstants=array(); if (empty($argv[1])) @@ -67,8 +68,6 @@ while ($i < $argc) if (empty($includecustom)) { - $includecustom=0; - if (DOL_VERSION != $release) { 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"; @@ -80,7 +79,7 @@ else { if (! preg_match('/'.preg_quote(DOL_VERSION,'/').'-/',$release)) { - print 'Error: When parameter "includecustom" is not set, version declared into ('.DOL_VERSION.') must be used with a suffix into "release" parmater (ex: '.DOL_VERSION.'-mydistrib).'."\n"; + 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; } From 4012aeff908e0ecaf158275713feeb9dbda55056 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 18:35:17 +0100 Subject: [PATCH 217/410] Fix translation --- dev/translation/sanity_check_en_langfiles.php | 2 ++ htdocs/core/boxes/box_graph_product_distribution.php | 2 ++ htdocs/langs/en_US/mails.lang | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/dev/translation/sanity_check_en_langfiles.php b/dev/translation/sanity_check_en_langfiles.php index f566938d7e0..bb3430eb22c 100755 --- a/dev/translation/sanity_check_en_langfiles.php +++ b/dev/translation/sanity_check_en_langfiles.php @@ -300,6 +300,8 @@ if ((! empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($a if (preg_match('/^BoxTitleLatest/', $value)) $qualifiedforclean=0; // install.lang if (preg_match('/^KeepDefaultValues/', $value)) $qualifiedforclean=0; + // mail.lang + if (preg_match('/MailingModuleDesc/i', $value)) $qualifiedforclean=0; // main.lang if (preg_match('/^Duration/', $value)) $qualifiedforclean=0; if (preg_match('/^FormatDate/', $value)) $qualifiedforclean=0; diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php index a709a7aef3a..2b3c69a9e15 100644 --- a/htdocs/core/boxes/box_graph_product_distribution.php +++ b/htdocs/core/boxes/box_graph_product_distribution.php @@ -249,6 +249,8 @@ class box_graph_product_distribution extends ModeleBoxes if (! empty($conf->commande->enabled) && ! empty($user->rights->commande->lire)) { + $langs->load("orders"); + // Build graphic number of object. $data = array(array('Lib',val1,val2,val3),...) if ($showordernb) { diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 897085ec423..61dddb46691 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -79,6 +79,10 @@ MailingModuleDescContactsWithThirdpartyFilter=Contact with customer filters MailingModuleDescContactsByCompanyCategory=Contacts by third party category MailingModuleDescContactsByCategory=Contacts by categories MailingModuleDescContactsByFunction=Contacts by position +MailingModuleDescEmailsFromFile=Emails from file +MailingModuleDescEmailsFromUser=Emails input by user +MailingModuleDescDolibarrUsers=Users with Emails +MailingModuleDescThirdPartiesByCategories=Third parties (by categories) # Libelle des modules de liste de destinataires mailing LineInFile=Line %s in file From aa5ff36a046d4f5cf049560e15d1d8d41c8879d1 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 19:04:27 +0100 Subject: [PATCH 218/410] display input border by setting --- htdocs/theme/eldy/style.css.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 24300718a3b..e16f6136233 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -275,7 +275,10 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla font-size: px; font-family: ; - border: none; +global->THEME_ELDY_SHOW_BORDER_INPUT)) + print "border: none;" +?> + border-bottom: solid 1px rgba(0,0,0,.2); outline: none; margin: 0px 0px 0px 0px; From acfdc9612164bd70ed393cf6d975dfcd99db643d Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 19:34:04 +0100 Subject: [PATCH 219/410] Border input display is allowed by setting --- htdocs/admin/ihm.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 95917a79ab5..554227f4bc1 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -215,6 +215,12 @@ if ($action == 'edit') // Edit print ' '; print ''; + // show input border + print ''.$langs->trans("showInputBorder").''; + print $form->selectyesno('main_showInputBorder',isset($conf->global->THEME_ELDY_SHOW_BORDER_INPUT)?$conf->global->THEME_ELDY_SHOW_BORDER_INPUT:0,1); + print ''; + print ' '; + print ''; // Disable javascript and ajax print ''.$langs->trans("DisableJavascript").''; print $form->selectyesno('main_disable_javascript',isset($conf->global->MAIN_DISABLE_JAVASCRIPT)?$conf->global->MAIN_DISABLE_JAVASCRIPT:0,1); @@ -390,12 +396,16 @@ else // Show print ' '; print ""; + print ''.$langs->trans("showInputBorder").''; + print yn($conf->global->THEME_ELDY_SHOW_BORDER_INPUT).""; + print ' '; + print ""; + // Disable javascript/ajax - print ''.$langs->trans("DisableJavascript").''; print yn($conf->global->MAIN_DISABLE_JAVASCRIPT).""; - print ' '; - print ""; + print ' '; + print ""; // Activate preview tab on element card if (class_exists("Imagick")) From 8c2b70c4a74ac20c9ec6112e4860404dcf077615 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 20:51:02 +0100 Subject: [PATCH 220/410] Fix filechecker --- htdocs/admin/system/filecheck.php | 4 ++-- htdocs/core/modules/mailings/thirdparties.modules.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 498e1ec54f0..679cea1b946 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -95,13 +95,13 @@ print ''."\n"; if (dol_is_file($xmlfile)) { print ' '.$langs->trans("LocalSignature").' = '; - print ''; + print ''; print '
    '; } else { print ' '.$langs->trans("LocalSignature").' = '; - print ''; + print ''; print ' ('.$langs->trans("AvailableOnlyOnPackagedVersions").')'; print '
    '; } diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php index 148c21aa31d..2f9be84aab4 100644 --- a/htdocs/core/modules/mailings/thirdparties.modules.php +++ b/htdocs/core/modules/mailings/thirdparties.modules.php @@ -23,7 +23,7 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; */ class mailing_thirdparties extends MailingTargets { - var $name='ContactsCategories'; + var $name='ThirdPartiesByCategories'; // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found var $desc="Third parties (by categories)"; var $require_admin=0; From dfb24a13d945116da035457c4f0f055236930fb3 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 23:48:30 +0100 Subject: [PATCH 221/410] Bad parasite caracters TD not good --- htdocs/loan/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 18ba36ec382..4b1384aeedb 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -489,7 +489,7 @@ if ($id > 0) print ""; // Nbterms - print ''.$langs->trans("Nbterms").''; + print ''.$langs->trans("Nbterms").''; print ''; if ($action == 'edit') { @@ -502,7 +502,7 @@ if ($id > 0) print ''; // Rate - print ''.$langs->trans("Rate").''; + print ''.$langs->trans("Rate").''; print ''; if ($action == 'edit') { From 9a85e5ef003a7ee7db4bc3633fd2d5d3c751506c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 26 Mar 2017 01:45:09 +0100 Subject: [PATCH 222/410] Enhance the file checker --- build/generate_filelist_xml.php | 28 ++++++++++++++++++++-------- htdocs/admin/system/filecheck.php | 6 +++--- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index 1eeac5410b2..c1a56beacd7 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -123,16 +123,21 @@ foreach ($includeconstants as $countrycode => $tmp) fputs($fp, ''."\n"); -// TODO Replace RecursiveDirectoryIterator with dol_dir_list -$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. 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)$'; // 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"); @@ -160,14 +165,21 @@ $checksumconcat=array(); fputs($fp, ''."\n"); // TODO Replace RecursiveDirectoryIterator with dol_dir_list -$dir_iterator2 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../scripts/'); +/*$dir_iterator2 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../scripts/'); $iterator2 = new RecursiveIteratorIterator($dir_iterator2); // 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"); diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 679cea1b946..62d0999170f 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -95,13 +95,13 @@ print ''."\n"; if (dol_is_file($xmlfile)) { print ' '.$langs->trans("LocalSignature").' = '; - print ''; + print ''; print '
    '; } else { print ' '.$langs->trans("LocalSignature").' = '; - print ''; + print ''; print ' ('.$langs->trans("AvailableOnlyOnPackagedVersions").')'; print '
    '; } @@ -109,7 +109,7 @@ print ''."\n"; if ($enableremotecheck) { print ' '.$langs->trans("RemoteSignature").' = '; - print '
    '; + print '
    '; } else { From 68656dd29cb8e4df78cfc199b3ca087310d13b1b Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 12:06:02 +0100 Subject: [PATCH 223/410] FIX : supplier default condition not retrived on create --- htdocs/supplier_proposal/card.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 050e0186444..6a34a5ddd61 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1050,7 +1050,9 @@ if ($action == 'create') } else { - if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; + $cond_reglement_id = $soc->cond_reglement_supplier_id; + $mode_reglement_id = $soc->mode_reglement_supplier_id; + if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; } $object = new SupplierProposal($db); @@ -1087,12 +1089,12 @@ if ($action == 'create') // Terms of payment print '' . $langs->trans('PaymentConditionsShort') . ''; - $form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $soc->cond_reglement_id, 'cond_reglement_id', -1, 1); + $form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1); print ''; // Mode of payment print '' . $langs->trans('PaymentMode') . ''; - $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $soc->mode_reglement_id, 'mode_reglement_id'); + $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id'); print ''; // Bank Account From f4a7217f20382e39fc29265d5a10fd4f41a97d04 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:39:25 +0100 Subject: [PATCH 224/410] display total line for all total line --- htdocs/comm/propal/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index aa6df1afb2b..44a2b9356e8 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -977,7 +977,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From afefb475984ae29ef30e014e3c3f50da3b75e096 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:40:34 +0100 Subject: [PATCH 225/410] Update list.php --- htdocs/commande/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index c72671319bc..073a20bc391 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1398,7 +1398,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 8d6819c6642e976c0e9235e72a06474f3785c334 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:53:32 +0100 Subject: [PATCH 226/410] Update list.php --- htdocs/fourn/facture/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index bff5c773cfc..3afb97c5fb1 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -956,7 +956,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 6e133e5bf6f3c03083cefaa5355a65015ad8d97d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 26 Mar 2017 01:57:09 +0100 Subject: [PATCH 227/410] Fix security escapment --- htdocs/loan/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 8ef8e09eba9..d0ab75127ab 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -230,7 +230,7 @@ if ($action == 'create') } // Capital - print ''.$langs->trans("LoanCapital").''; + print ''.$langs->trans("LoanCapital").''; // Date Start print ""; @@ -245,10 +245,10 @@ if ($action == 'create') print ''; // Number of terms - print ''.$langs->trans("Nbterms").''; + print ''.$langs->trans("Nbterms").''; // Rate - print ''.$langs->trans("Rate").' %'; + print ''.$langs->trans("Rate").' %'; // Note Private print ''; From e38ad37ce33df734439f73ab4df49d7393a2659c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 26 Mar 2017 05:02:06 +0200 Subject: [PATCH 228/410] FIX #6517 #6525 Autocompletion of thirdparty after n chars not implemented --- htdocs/core/class/html.form.class.php | 86 ++++++++++++++------------- htdocs/core/lib/agenda.lib.php | 2 +- htdocs/societe/ajax/company.php | 32 ++++------ 3 files changed, 59 insertions(+), 61 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 60ff30c6433..664997129df 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -931,36 +931,40 @@ class Form /** * Output html form to select a third party * - * @param string $selected Preselected type - * @param string $htmlname Name of field in form - * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)') - * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param int $limit Maximum number of elements - * @param string $morecss Add more css styles to the SELECT component - * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container - * @return string HTML string with select box for thirdparty. + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)') + * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') + * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int $forcecombo Force to use combo box + * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param int $limit Maximum number of elements + * @param string $morecss Add more css styles to the SELECT component + * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container + * @param string $selected_input_value Value of preselected input text (for use with ajax) + * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) + * @param array $ajaxoptions Options for ajax_autocompleter + * @return string HTML string with select box for thirdparty. */ - function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='') + function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='', $selected_input_value='', $hidelabel=1, $ajaxoptions=array()) { + global $conf,$user,$langs; + $out=''; - /* TODO Use ajax_autocompleter like for products (not finished) if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo) { $placeholder=''; - if ($selected && empty($selected_input_value)) { - require_once DOL_DOCUMENT_ROOT.'/societe/ajaxcompanies.php'; - $societe = new Societe($this->db); - $societe->fetch($selected); - $selected_input_value=$societe->ref; + require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + $societetmp = new Societe($this->db); + $societetmp->fetch($selected); + $selected_input_value=$societetmp->name; + unset($societetmp); } - // mode=1 means customers products - $urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished; + // mode 1 + $urloption='htmlname='.$htmlname.'&outjson=1&filter='.$filter; print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : '; else if ($hidelabel > 1) { @@ -970,15 +974,15 @@ class Form print img_picto($langs->trans("Search"), 'search'); } } - print ''; + print 'global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; if ($hidelabel == 3) { print img_picto($langs->trans("Search"), 'search'); } } else - {*/ + { $out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam); - //} + } return $out; } @@ -1004,7 +1008,8 @@ class Form { global $conf,$user,$langs; - $out=''; $num=0; + $out=''; + $num=0; $outarray=array(); // On recherche les societes @@ -1020,19 +1025,18 @@ class Form if ($filterkey && $filterkey != '') { $sql.=" AND ("; - if (! empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) // Can use index - { - $sql.="(s.name LIKE '".$this->db->escape($filterkey)."%')"; + $prefix=empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on + // For natural search + $scrit = explode(' ', $filterkey); + $i=0; + if (count($scrit) > 1) $sql.="("; + foreach ($scrit as $crit) { + if ($i > 0) $sql.=" AND "; + $sql.="(s.nom LIKE '".$this->db->escape($prefix.$crit)."%')"; + $i++; } - else - { - // For natural search - $scrit = explode(' ', $filterkey); - foreach ($scrit as $crit) { - $sql.=" AND (s.name LIKE '%".$this->db->escape($crit)."%')"; - } - } - if (! empty($conf->barcode->enabled)) + if (count($scrit) > 1) $sql.=")"; + if (! empty($conf->barcode->enabled)) { $sql .= " OR s.barcode LIKE '".$this->db->escape($filterkey)."%'"; } @@ -1041,20 +1045,22 @@ class Form $sql.=$this->db->order("nom","ASC"); if ($limit > 0) $sql.=$this->db->plimit($limit); + // Build output string dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { + $events = null; + if ($conf->use_javascript_ajax && ! $forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } // Construct $out and $outarray - $out.= ''."\n"; $textifempty=''; // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. @@ -1066,7 +1072,7 @@ class Form } if ($showempty) $out.= ''."\n"; - $num = $this->db->num_rows($resql); + $num = $this->db->num_rows($resql); $i = 0; if ($num) { @@ -1109,7 +1115,7 @@ class Form $out.= ''; } - array_push($outarray, array('key'=>$obj->rowid, 'value'=>$obj->rowid, 'label'=>$label)); + array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label)); $i++; if (($i % 10) == 0) $out.="\n"; diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 09f89ba0c3f..b16792a0235 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -118,7 +118,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print ''; print $langs->trans("ThirdParty").'   '; print ''; - print $form->select_company($socid, 'socid', '', 1); + print $form->select_company($socid, 'socid', '', 'SelectThirdParty', 0, 0, null, 0); print ''; } diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index d2a244f9444..32f57f73c25 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -18,8 +18,8 @@ */ /** - * \file htdocs/product/ajax/company.php - * \brief File to return Ajax response on product list request + * \file htdocs/societe/ajax/company.php + * \brief File to return Ajax response on thirdparty list request */ if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal @@ -33,15 +33,11 @@ if (empty($_GET['keysearch']) && ! defined('NOREQUIREHTML')) define('NOREQUIREH require '../../main.inc.php'; $htmlname=GETPOST('htmlname','alpha'); -$socid=GETPOST('socid','int'); -$type=GETPOST('type','int'); -$mode=GETPOST('mode','int'); -$status=((GETPOST('status','int') >= 0) ? GETPOST('status','int') : -1); +$filter=GETPOST('filter','alpha'); $outjson=(GETPOST('outjson','int') ? GETPOST('outjson','int') : 0); -$price_level=GETPOST('price_level','int'); $action=GETPOST('action', 'alpha'); $id=GETPOST('id', 'int'); -$price_by_qty_rowid=GETPOST('pbq', 'int'); + /* * View @@ -49,7 +45,7 @@ $price_by_qty_rowid=GETPOST('pbq', 'int'); //print ''."\n"; -dol_syslog(join(',',$_GET)); +dol_syslog(join(',', $_GET)); //print_r($_GET); if (! empty($action) && $action == 'fetch' && ! empty($id)) @@ -63,8 +59,11 @@ if (! empty($action) && $action == 'fetch' && ! empty($id)) if ($ret > 0) { $outname=$object->name; - - $outjson = array('name'=>$outname); + $outlabel = ''; + $outdesc = ''; + $outtype = $object->type; + + $outjson = array('ref' => $outref,'name' => $outname,'desc' => $outdesc,'type' => $outtype); } echo json_encode($outjson); @@ -73,7 +72,7 @@ else { require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; - $langs->load("products"); + $langs->load("companies"); $langs->load("main"); top_httphead(); @@ -90,14 +89,7 @@ else $searchkey=(GETPOST($id)?GETPOST($id):(GETPOST($htmlname)?GETPOST($htmlname):'')); $form = new Form($db); - if (empty($mode) || $mode == 'customer') - { - $arrayresult=$form->select_company_html($socid,$htmlname,"client IN (1,3)",0,0,0,null,$searchkey,$outjson); - } - elseif ($mode == 'supplier') - { - $arrayresult=$form->select_company_html($socid,$htmlname,"fournisseur=1",0,0,0,null,$searchkey,$outjson); - } + $arrayresult=$form->select_thirdparty_list(0,$htmlname,$filter,1,0,0,null,$searchkey,$outjson); $db->close(); From 3bde8a575e251b8f14e7dc086169fc9cf59e3262 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 26 Mar 2017 05:48:31 +0200 Subject: [PATCH 229/410] Fix : Ref of expense report and date are inverted in list of expense report to bind --- htdocs/accountancy/expensereport/list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 693984432ae..50b96b5a38b 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014 Juanjo Menent s @@ -302,17 +302,17 @@ if ($result) { $expensereport_static->ref = $objp->ref; $expensereport_static->id = $objp->erid; - + print ''; // Line id print '' . $objp->rowid . ''; - print '' . dol_print_date($db->jdate($objp->date), 'day') . ''; - // Ref Expense report print '' . $expensereport_static->getNomUrl(1) . ''; + print '' . dol_print_date($db->jdate($objp->date), 'day') . ''; + // Fees label print ''; print $objp->fees_label; From 8f915bc59366f9df8cf145e6510273bf8f502943 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 26 Mar 2017 06:20:05 +0200 Subject: [PATCH 230/410] Fix : Problem with type_fees_label in accountancy module --- htdocs/accountancy/expensereport/card.php | 8 ++++---- htdocs/accountancy/expensereport/lines.php | 6 +++--- htdocs/accountancy/expensereport/list.php | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/accountancy/expensereport/card.php b/htdocs/accountancy/expensereport/card.php index 4819bd656ae..808214becce 100644 --- a/htdocs/accountancy/expensereport/card.php +++ b/htdocs/accountancy/expensereport/card.php @@ -1,7 +1,7 @@ * Copyright (C) 2005 Simon TOSSER - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2013-2014 Olivier Geffroy * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014 Juanjo Menent @@ -76,7 +76,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { /* * View */ -llxHeader("", "FicheVentilation"); +llxHeader("", $langs->trans(FicheVentilation)); if ($cancel == $langs->trans("Cancel")) { $action = ''; @@ -89,7 +89,7 @@ $formventilation = new FormVentilation($db); if (! empty($id)) { $sql = "SELECT er.ref, er.rowid as facid, erd.fk_c_type_fees, erd.comments, erd.rowid, erd.fk_code_ventilation,"; - $sql .= " f.id as fees_id, f.label as fees_label,"; + $sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label,"; $sql .= " aa.account_number, aa.label"; $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees"; @@ -132,7 +132,7 @@ if (! empty($id)) { print '' . stripslashes(nl2br($objp->comments)) . ''; print '' . $langs->trans("TypeFees") . ''; - print '' . dol_trunc($objp->fees_label, 24) . ''; + print '' . ($langs->trans($objp->type_fees_code) == $objp->type_fees_code ? $objp->type_fees_label : $langs->trans(($objp->type_fees_code))) . ''; print '' . $langs->trans("Account") . ''; print $formventilation->select_account($objp->fk_code_ventilation, 'codeventil', 1); diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index 049e1d44687..31b1ae6701c 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2013-2016 Florian Henry * Copyright (C) 2014 Juanjo Menent @@ -148,7 +148,7 @@ print ''; + + return $out; + } + /** * Return HTML to show the search and clear seach button * @@ -6168,31 +6219,10 @@ class Form */ function showFilterAndCheckAddButtons($addcheckuncheckall=0, $cssclass='checkforaction', $calljsfunction=0) { - global $conf, $langs; - - $out='
    '; - $out.=''; - $out.=''; - $out.='
    '; + $out.=$this->showFilterButtons(); if ($addcheckuncheckall) { - if (! empty($conf->use_javascript_ajax)) $out.=''; - $out.=''; + $out.=$this->showCheckAddButtons($cssclass, $calljsfunction); } return $out; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 51a5ab39889..b16d6d13790 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -584,7 +584,7 @@ div.myavailability { padding-bottom: 4px; } .checkallactions { - vertical-align: top; + vertical-align: text-bottom; margin-top: 6px; margin-left: 4px; } @@ -2505,7 +2505,6 @@ div.pagination li { div.pagination li.pagination a, div.pagination li.pagination span { padding: 6px 12px; - margin-left: -1px; line-height: 1.42857143; color: #000; text-decoration: none; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 4c1d32c31ad..d80630f0501 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -587,7 +587,7 @@ div.myavailability { padding-bottom: 4px; } .checkallactions { - vertical-align: top; + vertical-align: text-bottom; margin-top: 6px; margin-left: 4px; } @@ -2413,7 +2413,6 @@ div.pagination li { div.pagination li.pagination a, div.pagination li.pagination span { padding: 6px 12px; - margin-left: -1px; line-height: 1.42857143; color: #000; text-decoration: none; From e416ea275e0a808ebb46b686a05a7bce1902e26b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Mar 2017 18:42:23 +0200 Subject: [PATCH 249/410] Work on 6.0 look and feel --- htdocs/adherents/list.php | 93 ++++++++++--------- htdocs/adherents/subscription/list.php | 32 +++---- htdocs/comm/action/index.php | 12 +-- htdocs/comm/action/listactions.php | 8 +- htdocs/comm/action/peruser.php | 4 +- htdocs/compta/bank/annuel.php | 2 +- htdocs/compta/bank/bankentries.php | 74 ++++++++------- htdocs/compta/bank/card.php | 6 +- htdocs/compta/bank/class/account.class.php | 59 +++++++++++- htdocs/compta/bank/class/bankcateg.class.php | 5 +- htdocs/compta/bank/document.php | 2 +- htdocs/compta/bank/index.php | 64 +++++++------ htdocs/compta/bank/info.php | 24 +++-- htdocs/compta/bank/ligne.php | 15 ++- htdocs/compta/bank/treso.php | 2 +- htdocs/compta/facture/list.php | 82 ++++++++-------- htdocs/contrat/card.php | 38 ++++---- htdocs/contrat/contact.php | 2 +- htdocs/contrat/document.php | 2 +- htdocs/contrat/info.php | 20 ++-- htdocs/contrat/note.php | 2 +- htdocs/core/class/html.formactions.class.php | 2 +- htdocs/core/lib/agenda.lib.php | 2 +- htdocs/core/lib/bank.lib.php | 5 + htdocs/core/lib/functions.lib.php | 10 +- htdocs/core/tpl/objectline_create.tpl.php | 1 - htdocs/core/tpl/resource_add.tpl.php | 3 +- htdocs/core/tpl/resource_view.tpl.php | 8 +- htdocs/fichinter/list.php | 64 ++++++------- htdocs/fourn/commande/list.php | 83 +++++++++-------- htdocs/fourn/facture/list.php | 81 ++++++++-------- .../install/mysql/migration/5.0.0-6.0.0.sql | 2 + .../mysql/tables/llx_supplier_proposaldet.sql | 2 +- htdocs/projet/list.php | 70 +++++++------- htdocs/projet/tasks/list.php | 70 +++++++------- htdocs/resource/element_resource.php | 1 + htdocs/supplier_proposal/list.php | 29 +++--- htdocs/theme/eldy/style.css.php | 8 +- htdocs/theme/md/style.css.php | 5 +- 39 files changed, 550 insertions(+), 444 deletions(-) diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 28cd8773d53..8d00194993b 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -377,52 +377,10 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print ''."\n"; -print ''; -if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) -{ - print ''; -} -if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],'d.rowid','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.firstname']['checked'])) print_liste_field_titre($arrayfields['d.firstname']['label'],$_SERVER["PHP_SELF"],'d.firstname','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.lastname']['checked'])) print_liste_field_titre($arrayfields['d.lastname']['label'],$_SERVER["PHP_SELF"],'d.lastname','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.company']['checked'])) print_liste_field_titre($arrayfields['d.company']['label'],$_SERVER["PHP_SELF"],'d.societe','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.login']['checked'])) print_liste_field_titre($arrayfields['d.login']['label'],$_SERVER["PHP_SELF"],'d.login','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.morphy']['checked'])) print_liste_field_titre($arrayfields['d.morphy']['label'],$_SERVER["PHP_SELF"],'d.morphy','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['t.libelle']['checked'])) print_liste_field_titre($arrayfields['t.libelle']['label'],$_SERVER["PHP_SELF"],'t.libelle','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.address']['checked'])) print_liste_field_titre($arrayfields['d.address']['label'],$_SERVER["PHP_SELF"],'d.address','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.zip']['checked'])) print_liste_field_titre($arrayfields['d.zip']['label'],$_SERVER["PHP_SELF"],'d.zip','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.town']['checked'])) print_liste_field_titre($arrayfields['d.town']['label'],$_SERVER["PHP_SELF"],'d.town','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($langs->trans("StateShort"),$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($langs->trans("Country"),$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['d.phone']['checked'])) print_liste_field_titre($arrayfields['d.phone']['label'],$_SERVER["PHP_SELF"],'d.phone','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.phone_perso']['checked'])) print_liste_field_titre($arrayfields['d.phone_perso']['label'],$_SERVER["PHP_SELF"],'d.phone_perso','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.phone_mobile']['checked'])) print_liste_field_titre($arrayfields['d.phone_mobile']['label'],$_SERVER["PHP_SELF"],'d.phone_mobile','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['d.statut']['checked'])) print_liste_field_titre($arrayfields['d.statut']['label'],$_SERVER["PHP_SELF"],"d.statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; + // Line for filters fields -print ''; +print ''; // Line numbering if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) @@ -595,7 +553,50 @@ print ''; print "\n"; -$var=True; +print ''; +if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) +{ + print ''; +} +if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],'d.rowid','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.firstname']['checked'])) print_liste_field_titre($arrayfields['d.firstname']['label'],$_SERVER["PHP_SELF"],'d.firstname','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.lastname']['checked'])) print_liste_field_titre($arrayfields['d.lastname']['label'],$_SERVER["PHP_SELF"],'d.lastname','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.company']['checked'])) print_liste_field_titre($arrayfields['d.company']['label'],$_SERVER["PHP_SELF"],'d.societe','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.login']['checked'])) print_liste_field_titre($arrayfields['d.login']['label'],$_SERVER["PHP_SELF"],'d.login','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.morphy']['checked'])) print_liste_field_titre($arrayfields['d.morphy']['label'],$_SERVER["PHP_SELF"],'d.morphy','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['t.libelle']['checked'])) print_liste_field_titre($arrayfields['t.libelle']['label'],$_SERVER["PHP_SELF"],'t.libelle','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.address']['checked'])) print_liste_field_titre($arrayfields['d.address']['label'],$_SERVER["PHP_SELF"],'d.address','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.zip']['checked'])) print_liste_field_titre($arrayfields['d.zip']['label'],$_SERVER["PHP_SELF"],'d.zip','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.town']['checked'])) print_liste_field_titre($arrayfields['d.town']['label'],$_SERVER["PHP_SELF"],'d.town','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($langs->trans("StateShort"),$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($langs->trans("Country"),$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['d.phone']['checked'])) print_liste_field_titre($arrayfields['d.phone']['label'],$_SERVER["PHP_SELF"],'d.phone','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.phone_perso']['checked'])) print_liste_field_titre($arrayfields['d.phone_perso']['label'],$_SERVER["PHP_SELF"],'d.phone_perso','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.phone_mobile']['checked'])) print_liste_field_titre($arrayfields['d.phone_mobile']['label'],$_SERVER["PHP_SELF"],'d.phone_mobile','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['d.statut']['checked'])) print_liste_field_titre($arrayfields['d.statut']['label'],$_SERVER["PHP_SELF"],"d.statut","",$param,'align="right"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + $i = 0; while ($i < min($num, $limit)) { @@ -619,7 +620,7 @@ while ($i < min($num, $limit)) } $var=!$var; - print ""; + print ""; if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index d8116c79e94..0705a035ba0 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -159,22 +159,6 @@ if ($result) print '
    '; print '
    '.$langs->trans("NumberingShort").'
    '.$langs->trans("NumberingShort").'
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"c.rowid",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Login"),$_SERVER["PHP_SELF"],"d.login",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"c.note",$param,"",'align="left"',$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) - { - print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"b.fk_account",$pram,"","",$sortfield,$sortorder); - } - print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"c.dateadh",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"c.datef",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"c.subscription",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - - // Line for filters fields print ''; @@ -214,6 +198,22 @@ if ($result) print "\n"; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"c.rowid",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Login"),$_SERVER["PHP_SELF"],"d.login",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"c.note",$param,"",'align="left"',$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) + { + print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"b.fk_account",$pram,"","",$sortfield,$sortorder); + } + print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"c.dateadh",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"c.datef",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"c.subscription",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + + // Static objects $subscription=new Subscription($db); $adherent=new Adherent($db); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 25d410e7bdb..13fb3d9624f 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -306,28 +306,28 @@ $param.="&maxprint=".$maxprint; // Show navigation bar if (empty($action) || $action=='show_month') { - $nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; + $nav ="  \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$month,1,$year),"%b %Y"); $nav.=" \n"; - $nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; + $nav.="   \n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendar'; } if ($action=='show_week') { - $nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; + $nav ="trans("Previous"))."\">  \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("Week")." ".$week; $nav.=" \n"; - $nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; + $nav.="   trans("Next"))."\">\n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendarweek'; } if ($action=='show_day') { - $nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; + $nav ="  \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$month,$day,$year),"daytextshort"); $nav.=" \n"; - $nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; + $nav.="   \n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendarday'; } diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 0a08b6e55f1..8776984345b 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -29,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $langs->load("users"); $langs->load("companies"); @@ -147,6 +148,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP $form=new Form($db); $userstatic=new User($db); +$formactions=new FormActions($db); $nav=''; $nav.=$form->select_date($dateselect, 'dateselect', 0, 0, 1, '', 1, 0, 1); @@ -227,6 +229,7 @@ if ($type) $sql.= " AND c.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 == '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 ($search_title) $sql.=natural_search("a.label", $search_title); @@ -324,7 +327,6 @@ if ($resql) if ($optioncss != '') $nav.= ''; if ($actioncode) $nav.=''; if ($resourceid) $nav.=''; - if ($status || isset($_GET['status']) || isset($_POST['status'])) $nav.=''; if ($filter) $nav.=''; if ($filtert) $nav.=''; if ($socid) $nav.=''; @@ -368,7 +370,9 @@ if ($resql) print ''; print ''; print ''; - print ''; + print ''; // Action column print ''; } - if ($canedit) + if ($canedit && ! preg_match('/listaction/', $_SERVER["PHP_SELF"])) { // Status print ''; diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index 8e9fb7bc77a..ed13b736a7d 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -91,6 +91,11 @@ function bank_prepare_head(Account $object) // $this->tabs = array('entity:-tabname); to remove a tab complete_head_from_modules($conf, $langs, $object, $head, $h, 'bank'); + /*$head[$h][0] = DOL_URL_ROOT . "/compta/bank/info.php?id=" . $object->id; + $head[$h][1] = $langs->trans("Info"); + $head[$h][2] = 'info'; + $h++;*/ + complete_head_from_modules($conf, $langs, $object, $head, $h, 'bank', 'remove'); return $head; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 20186ebe28d..f9ba39f870e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2589,7 +2589,7 @@ function img_edit_remove($titlealt = 'default', $other='') * @param string $other Add more attributes on img * @return string Return tag img */ -function img_edit($titlealt = 'default', $float = 0, $other = '') +function img_edit($titlealt = 'default', $float = 0, $other = 'class="pictoedit"') { global $conf, $langs; @@ -2624,7 +2624,7 @@ function img_view($titlealt = 'default', $float = 0, $other = '') * @param string $other Add more attributes on img * @return string Retourne tag img */ -function img_delete($titlealt = 'default', $other = '') +function img_delete($titlealt = 'default', $other = 'class="pictodelete"') { global $conf, $langs; @@ -3450,8 +3450,7 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee } if ($page > 0) { - if (($conf->dol_use_jmobile != 4)) print ''; - else print '
  • '.$langs->trans("Previous").'
  • '; + print ''; } if ($betweenarrows) { @@ -3459,8 +3458,7 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee } if ($nextpage > 0) { - if (($conf->dol_use_jmobile != 4)) print ''; - else print '
  • '.$langs->trans("Next").'
  • '; + print ''; } if ($afterarrows) { diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 83725580db5..ed6bb2c9979 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -57,7 +57,6 @@ $nolinesbefore=(count($this->lines) == 0 || $forcetoshowtitlelines); if ($nolinesbefore) { ?> - diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index b521445701b..28c42c85b71 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -17,7 +17,8 @@ $out .= ''.$langs->trans("SelectResource").'
    '; +$out .= '
    '.$langs->trans("SelectResource").'
    '; +$out .= '
    '; $events=array(); $out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2); $out .= '
    '; diff --git a/htdocs/core/tpl/resource_view.tpl.php b/htdocs/core/tpl/resource_view.tpl.php index ecc9f32d837..cad54932c71 100644 --- a/htdocs/core/tpl/resource_view.tpl.php +++ b/htdocs/core/tpl/resource_view.tpl.php @@ -62,7 +62,7 @@ if( (array) $linked_resources && count($linked_resources) > 0) if ($linked_resource['rowid'] == GETPOST('lineid')) $style='style="background: orange;"'; - print '
    '; + print '
    '; print '
    '; print $object_resource->getNomUrl(1); @@ -90,19 +90,19 @@ if( (array) $linked_resources && count($linked_resources) > 0) print ''; print '
    '; - print '
    '; + print ''; } } } else { - print '
    '; + print '
    '; print '
    '.$langs->trans('NoResourceLinked').'
    '; print '
    '; print '
    '; print '
    '; print '
    '; - print '
    '; + print ''; } print '
    '; diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 563c57f5ad7..2ec1eb2af70 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -137,6 +137,8 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP $form = new Form($db); $formfile = new FormFile($db); $objectstatic=new Fichinter($db); +$companystatic=new Societe($db); + llxHeader('', $langs->trans("Intervention")); @@ -253,36 +255,8 @@ if ($result) print '
    '; print '
    '; + print $formactions->form_select_status_action('formaction',$status,1,'status',1,2); + print ''; $searchpitco=$form->showFilterAndCheckAddButtons(0); diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index f5de3fa6ca3..61bf98634c4 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -242,10 +242,10 @@ $max_day_in_month = date("t",dol_mktime(0,0,0,$month,1,$year)); $tmpday = $first_day; -$nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; +$nav ="trans("Previous"))."\">   \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("Week")." ".$week; $nav.=" \n"; -$nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; +$nav.="   trans("Next"))."\">\n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendarweek'; diff --git a/htdocs/compta/bank/annuel.php b/htdocs/compta/bank/annuel.php index af63247f48d..a81a0072302 100644 --- a/htdocs/compta/bank/annuel.php +++ b/htdocs/compta/bank/annuel.php @@ -144,7 +144,7 @@ else // Onglets $head=bank_prepare_head($object); -dol_fiche_head($head,'annual',$langs->trans("FinancialAccount"),0,'account'); +dol_fiche_head($head, 'annual', $langs->trans("FinancialAccount"), -1, 'account'); $title=$langs->trans("FinancialAccount")." : ".$object->label; $link=($year_start?"".img_previous('', 'class="valignbottom"')." ".$langs->trans("Year")." ".img_next('', 'class="valignbottom"')."":""); diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index 9af9b6f4707..c7596a0aee2 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -720,43 +720,8 @@ if ($resql) print '
    '; print ''."\n"; - - // Fields title - print ''; - if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'],$_SERVER['PHP_SELF'],'b.rowid','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'],$_SERVER['PHP_SELF'],'','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'],$_SERVER['PHP_SELF'],'b.dateo','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev, b.dateo, b.rowid','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.num_chq']['checked'])) print_liste_field_titre($arrayfields['b.num_chq']['label'],$_SERVER['PHP_SELF'],'b.num_chq','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['bu.label']['checked'])) print_liste_field_titre($arrayfields['bu.label']['label'],$_SERVER['PHP_SELF'],'bu.label','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['ba.ref']['checked'])) print_liste_field_titre($arrayfields['ba.ref']['label'],$_SERVER['PHP_SELF'],'ba.ref','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['b.debit']['checked'])) print_liste_field_titre($arrayfields['b.debit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['b.credit']['checked'])) print_liste_field_titre($arrayfields['b.credit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['b.num_releve']['checked'])) print_liste_field_titre($arrayfields['b.num_releve']['label'],$_SERVER['PHP_SELF'],'b.num_releve','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.conciliated']['checked'])) print_liste_field_titre($arrayfields['b.conciliated']['label'],$_SERVER['PHP_SELF'],'b.rappro','',$param,'align="center"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - print ''; + print ''; if (! empty($arrayfields['b.rowid']['checked'])) { print ''; print "\n"; + + // Fields title + print ''; + if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'],$_SERVER['PHP_SELF'],'b.rowid','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'],$_SERVER['PHP_SELF'],'','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'],$_SERVER['PHP_SELF'],'b.dateo','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev, b.dateo, b.rowid','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.num_chq']['checked'])) print_liste_field_titre($arrayfields['b.num_chq']['label'],$_SERVER['PHP_SELF'],'b.num_chq','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['bu.label']['checked'])) print_liste_field_titre($arrayfields['bu.label']['label'],$_SERVER['PHP_SELF'],'bu.label','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['ba.ref']['checked'])) print_liste_field_titre($arrayfields['ba.ref']['label'],$_SERVER['PHP_SELF'],'ba.ref','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['b.debit']['checked'])) print_liste_field_titre($arrayfields['b.debit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['b.credit']['checked'])) print_liste_field_titre($arrayfields['b.credit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['b.num_releve']['checked'])) print_liste_field_titre($arrayfields['b.num_releve']['label'],$_SERVER['PHP_SELF'],'b.num_releve','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.conciliated']['checked'])) print_liste_field_titre($arrayfields['b.conciliated']['label'],$_SERVER['PHP_SELF'],'b.rappro','',$param,'align="center"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $balance = 0; // For balance $balancecalculated = false; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index dcc0fc85ecc..0bb518662d6 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -713,7 +713,7 @@ else print '
    '; @@ -837,6 +802,43 @@ if ($resql) print '
    '; - print ''; + print ''; print ''; // Show fields of bank account @@ -957,7 +957,7 @@ else print '
    '; - print '
    '; + //print '
    '; print '
    '.$langs->trans("BankName").'
    '.$langs->trans("BankName").''.$object->bank.'
    '; @@ -991,7 +991,7 @@ else { print '
    '; - print '
    '; + //print '
    '; print '
    '; diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 1670ac2917c..8925a67d593 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1553,7 +1553,8 @@ class AccountLine extends CommonObject var $db; var $element='bank'; var $table_element='bank'; - + var $picto = 'generic'; + var $id; var $ref; var $datec; @@ -2040,5 +2041,61 @@ class AccountLine extends CommonObject return $result; } + + /** + * Return label of status (activity, closed) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long + * @return string Libelle + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Renvoi le libelle d'un statut donne + * + * @param int $statut Id statut + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Libelle du statut + */ + function LibStatut($statut,$mode=0) + { + global $langs; + //$langs->load('companies'); + /* + if ($mode == 0) + { + if ($statut==0) return $langs->trans("ActivityCeased"); + if ($statut==1) return $langs->trans("InActivity"); + } + if ($mode == 1) + { + if ($statut==0) return $langs->trans("ActivityCeased"); + if ($statut==1) return $langs->trans("InActivity"); + } + if ($mode == 2) + { + if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased"); + if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity"); + } + if ($mode == 3) + { + if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"'); + if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"'); + } + if ($mode == 4) + { + if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased"); + if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity"); + } + if ($mode == 5) + { + if ($statut==0) return $langs->trans("ActivityCeased").' '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"'); + if ($statut==1) return $langs->trans("InActivity").' '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"'); + }*/ + } + } diff --git a/htdocs/compta/bank/class/bankcateg.class.php b/htdocs/compta/bank/class/bankcateg.class.php index 073c28be1ca..176fdb626a5 100644 --- a/htdocs/compta/bank/class/bankcateg.class.php +++ b/htdocs/compta/bank/class/bankcateg.class.php @@ -30,10 +30,11 @@ class BankCateg // extends CommonObject { //public $element='bank_categ'; //!< Id that identify managed objects //public $table_element='bank_categ'; //!< Name of table without prefix where object is stored - + public $picto='generic'; + public $id; public $label; - + /** * Constructor diff --git a/htdocs/compta/bank/document.php b/htdocs/compta/bank/document.php index db70acc7373..084cddf51cd 100644 --- a/htdocs/compta/bank/document.php +++ b/htdocs/compta/bank/document.php @@ -107,7 +107,7 @@ if ($id > 0 || !empty($ref)) { // Onglets $head = bank_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans("FinancialAccount"), 0, 'account'); + dol_fiche_head($head, 'document', $langs->trans("FinancialAccount"), -1, 'account'); // Construit liste des fichiers diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 29877302104..71397f695d6 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -285,39 +285,7 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '."\n"; -// Fields title -print ''; -if (! empty($arrayfields['b.ref']['checked'])) print_liste_field_titre($arrayfields['b.ref']['label'],$_SERVER["PHP_SELF"],'b.ref','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['b.label']['checked'])) print_liste_field_titre($arrayfields['b.label']['label'],$_SERVER["PHP_SELF"],'b.label','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['accountype']['checked'])) print_liste_field_titre($arrayfields['accountype']['label'],$_SERVER["PHP_SELF"],'','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['b.number']['checked'])) print_liste_field_titre($arrayfields['b.number']['label'],$_SERVER["PHP_SELF"],'b.number','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['b.account_number']['checked'])) print_liste_field_titre($arrayfields['b.account_number']['label'],$_SERVER["PHP_SELF"],'b.account_number','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['toreconcile']['checked'])) print_liste_field_titre($arrayfields['toreconcile']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['b.datec']['checked'])) print_liste_field_titre($arrayfields['b.datec']['label'],$_SERVER["PHP_SELF"],"b.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['b.tms']['checked'])) print_liste_field_titre($arrayfields['b.tms']['label'],$_SERVER["PHP_SELF"],"b.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['b.clos']['checked'])) print_liste_field_titre($arrayfields['b.clos']['label'],$_SERVER["PHP_SELF"],'b.clos','',$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - - -print ''; +print ''; // Ref if (! empty($arrayfields['b.ref']['checked'])) { @@ -419,6 +387,36 @@ print $searchpitco; print ''; print ''; +// Fields title +print ''; +if (! empty($arrayfields['b.ref']['checked'])) print_liste_field_titre($arrayfields['b.ref']['label'],$_SERVER["PHP_SELF"],'b.ref','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.label']['checked'])) print_liste_field_titre($arrayfields['b.label']['label'],$_SERVER["PHP_SELF"],'b.label','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['accountype']['checked'])) print_liste_field_titre($arrayfields['accountype']['label'],$_SERVER["PHP_SELF"],'','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.number']['checked'])) print_liste_field_titre($arrayfields['b.number']['label'],$_SERVER["PHP_SELF"],'b.number','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.account_number']['checked'])) print_liste_field_titre($arrayfields['b.account_number']['label'],$_SERVER["PHP_SELF"],'b.account_number','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['toreconcile']['checked'])) print_liste_field_titre($arrayfields['toreconcile']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['b.datec']['checked'])) print_liste_field_titre($arrayfields['b.datec']['label'],$_SERVER["PHP_SELF"],"b.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['b.tms']['checked'])) print_liste_field_titre($arrayfields['b.tms']['label'],$_SERVER["PHP_SELF"],"b.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['b.clos']['checked'])) print_liste_field_titre($arrayfields['b.clos']['label'],$_SERVER["PHP_SELF"],'b.clos','',$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; $total = array(); $found = 0; $i=0; $lastcurrencycode=''; diff --git a/htdocs/compta/bank/info.php b/htdocs/compta/bank/info.php index a1952ab5957..15555e45338 100644 --- a/htdocs/compta/bank/info.php +++ b/htdocs/compta/bank/info.php @@ -30,6 +30,8 @@ $langs->load("banks"); $langs->load("categories"); $langs->load("companies"); +$id = GETPOST("rowid"); + /* * View @@ -37,27 +39,35 @@ $langs->load("companies"); llxHeader(); -$line = new AccountLine($db); -$line->fetch($_GET["rowid"]); -$line->info($_GET["rowid"]); +$object = new AccountLine($db); +$object->fetch($id); +$object->info($id); $h=0; -$head[$h][0] = DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$_GET["rowid"]; +$head[$h][0] = DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$id; $head[$h][1] = $langs->trans("Card"); $h++; -$head[$h][0] = DOL_URL_ROOT.'/compta/bank/info.php?rowid='.$_GET["rowid"]; +$head[$h][0] = DOL_URL_ROOT.'/compta/bank/info.php?rowid='.$id; $head[$h][1] = $langs->trans("Info"); $hselected = $h; $h++; -dol_fiche_head($head, $hselected, $langs->trans("LineRecord"),0,'account'); +dol_fiche_head($head, $hselected, $langs->trans("LineRecord"), -1, 'account'); + +$linkback = ''.$langs->trans("BackToList").''; + + +dol_banner_tab($object, 'rowid', $linkback); + +print '
    '; +print '
    '; print '
    '; -dol_print_object_info($line); +dol_print_object_info($object); print '
    '; print '
    '; diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 558f1b0c042..f403f676f07 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -269,22 +269,27 @@ if ($result) print ''; print ''; - print ''; - $linkback = ''.$langs->trans("BackToList").''; + + dol_banner_tab($bankline, 'rowid', $linkback); + + print '
    '; + print '
    '; + // Ref + /* print '"; print ''; print ''; - + */ + $i++; - // Bank account - print ""; + print ''; print ''; diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index e889b4dff19..5a42e516020 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -91,7 +91,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) // Onglets $head=bank_prepare_head($object); - dol_fiche_head($head,'cash',$langs->trans("FinancialAccount"),0,'account'); + dol_fiche_head($head, 'cash', $langs->trans("FinancialAccount"), -1, 'account'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 8ed52eddb97..eafd8900d37 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -742,48 +742,8 @@ if ($resql) print '
    '; print '
    '.$langs->trans("Ref")."'; print $form->showrefnav($bankline, 'rowid', $linkback, 1, 'rowid', 'rowid'); print '
    ".$langs->trans("Account")."
    '.$langs->trans("Account").''; print $acct->getNomUrl(1,'transactions'); print '
    '."\n"; - print ''; - if (! empty($arrayfields['f.facnumber']['checked'])) print_liste_field_titre($arrayfields['f.facnumber']['label'],$_SERVER['PHP_SELF'],'f.facnumber','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'],$_SERVER["PHP_SELF"],'f.ref_client','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'],$_SERVER["PHP_SELF"],'f.type','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'],$_SERVER['PHP_SELF'],'f.datef','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER['PHP_SELF'],'s.nom','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type,dynamount_payed","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Filters lines - print ''; + print ''; // Ref if (! empty($arrayfields['f.facnumber']['checked'])) { @@ -953,6 +913,46 @@ if ($resql) print ''; print "\n"; + print ''; + if (! empty($arrayfields['f.facnumber']['checked'])) print_liste_field_titre($arrayfields['f.facnumber']['label'],$_SERVER['PHP_SELF'],'f.facnumber','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'],$_SERVER["PHP_SELF"],'f.ref_client','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'],$_SERVER["PHP_SELF"],'f.type','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'],$_SERVER['PHP_SELF'],'f.datef','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER['PHP_SELF'],'s.nom','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type,dynamount_payed","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + if ($num > 0) { $i=0; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 34f44c4f690..dc3ea846eee 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1868,7 +1868,7 @@ else print ''; print ''; - print '
    '; + print '
    '; // Definie date debut et fin par defaut $dateactstart = $objp->date_debut; @@ -1887,23 +1887,25 @@ else } } - print ''; + print ''; print ''; - print ''; - - print ''; print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print '
    '.$langs->trans("DateServiceActivate").''; print $form->select_date($dateactstart,'',$usehm,$usehm,'',"active",1,0,1); print ''.$langs->trans("DateEndPlanned").''; print $form->select_date($dateactend,"end",$usehm,$usehm,'',"active",1,0,1); print ''; - print '
    '; - print ''; + print '
    '; print '
    '.$langs->trans("Comment").'
    '.$langs->trans("Comment").''; + print '   '; + print ''; + print '
    '; @@ -1913,13 +1915,13 @@ else if ($user->rights->contrat->activer && $action == 'unactivateline' && $object->lines[$cursorline-1]->id == GETPOST('ligne')) { /** - * Desactiver la ligne de contrat + * Disable a contract line */ print ''; print ''; - print ''; + print '
    '; // Definie date debut et fin par defaut $dateactstart = $objp->date_debut_reelle; @@ -1940,7 +1942,7 @@ else $now=dol_now(); if ($dateactend > $now) $dateactend=$now; - print ''; - - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '; + print '
    '; if ($objp->statut >= 4) { if ($objp->statut == 4) @@ -1950,13 +1952,17 @@ else } } print ''; - print '
    '; - print ''; + print '
    '; print '
    '.$langs->trans("Comment").'
    '.$langs->trans("Comment").''; + print '   '; + print ''; + print '
    '; print ''; diff --git a/htdocs/contrat/contact.php b/htdocs/contrat/contact.php index e6607729767..8510888cf35 100644 --- a/htdocs/contrat/contact.php +++ b/htdocs/contrat/contact.php @@ -130,7 +130,7 @@ if ($id > 0 || ! empty($ref)) $hselected=1; - dol_fiche_head($head, $hselected, $langs->trans("Contract"), 0, 'contract'); + dol_fiche_head($head, $hselected, $langs->trans("Contract"), -1, 'contract'); // Contract card diff --git a/htdocs/contrat/document.php b/htdocs/contrat/document.php index 289ec50b78b..35fbdf065b9 100644 --- a/htdocs/contrat/document.php +++ b/htdocs/contrat/document.php @@ -93,7 +93,7 @@ if ($object->id) { $head=contract_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("Contract"), 0, 'contract'); + dol_fiche_head($head, 'documents', $langs->trans("Contract"), -1, 'contract'); // Construit liste des fichiers diff --git a/htdocs/contrat/info.php b/htdocs/contrat/info.php index 7f20b21c888..35cca237b21 100644 --- a/htdocs/contrat/info.php +++ b/htdocs/contrat/info.php @@ -28,10 +28,14 @@ require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $langs->load("contracts"); +$action = GETPOST('action','alpha'); +$confirm = GETPOST('confirm','alpha'); +$id = GETPOST('id','int'); +$ref = GETPOST('ref','alpha'); + // Security check -$contratid = GETPOST("id",'int'); if ($user->societe_id) $socid=$user->societe_id; -$result = restrictedArea($user, 'contrat',$contratid,''); +$result = restrictedArea($user, 'contrat', $id, ''); /* @@ -41,13 +45,17 @@ $result = restrictedArea($user, 'contrat',$contratid,''); llxHeader('',$langs->trans("Contract"),""); $object = new Contrat($db); -$object->fetch($contratid); -$object->fetch_thirdparty(); -$object->info($contratid); +$object->fetch($id, $ref); +if ($object->id > 0) +{ + $object->fetch_thirdparty(); +} + +$object->info($object->id); $head = contract_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("Contract"), 0, 'contract'); +dol_fiche_head($head, 'info', $langs->trans("Contract"), -1, 'contract'); // Contract card diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php index 212fa465266..7d4927d19b8 100644 --- a/htdocs/contrat/note.php +++ b/htdocs/contrat/note.php @@ -70,7 +70,7 @@ if ($id > 0 || ! empty($ref)) $hselected = 2; - dol_fiche_head($head, 'note', $langs->trans("Contract"), 0, 'contract'); + dol_fiche_head($head, 'note', $langs->trans("Contract"), -1, 'contract'); // Contract card diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index b44f854087c..6050679631f 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -120,7 +120,7 @@ class FormActions { //var_dump($selected); if ($selected == 'done') $selected='100'; - print ''; if ($showempty) print ''; foreach($listofstatus as $key => $val) { diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 91c5d24f36c..6c6f2d2f1d8 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -135,7 +135,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print '
    global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>>
    trans('AddNewLine'); ?>trans("FreeZone"); ?>
    '."\n"; - print ''; - if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"f.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.description']['checked'])) print_liste_field_titre($langs->trans("Description"),$_SERVER["PHP_SELF"],"f.description","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['fd.description']['checked'])) print_liste_field_titre('',$_SERVER["PHP_SELF"],''); - if (! empty($arrayfields['fd.date']['checked'])) print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"fd.date","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['fd.duree']['checked'])) print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],"fd.duree","",$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - print ''; + print ''; if (! empty($arrayfields['f.ref']['checked'])) { print ''; print "\n"; - $companystatic=new Societe($db); - - $var=True; + print ''; + if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"f.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.description']['checked'])) print_liste_field_titre($langs->trans("Description"),$_SERVER["PHP_SELF"],"f.description","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['fd.description']['checked'])) print_liste_field_titre('',$_SERVER["PHP_SELF"],''); + if (! empty($arrayfields['fd.date']['checked'])) print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"fd.date","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['fd.duree']['checked'])) print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],"fd.duree","",$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $total = 0; $i = 0; $totalarray=array(); diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 49de2dac7a3..f8062cc70bc 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -494,47 +494,7 @@ if ($resql) print '
    '; print '
    '; @@ -367,9 +341,35 @@ if ($result) print '
    '."\n"; - print ''; - if (! empty($arrayfields['cf.ref']['checked'])) print_liste_field_titre($arrayfields['cf.ref']['label'],$_SERVER["PHP_SELF"],"cf.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['cf.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['cf.ref_supplier']['label'],$_SERVER["PHP_SELF"],"cf.ref_supplier","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['p.project_ref']['checked'])) print_liste_field_titre($arrayfields['p.project_ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($arrayfields['u.login']['label'],$_SERVER["PHP_SELF"],"u.login","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.fk_author']['checked'])) print_liste_field_titre($arrayfields['cf.fk_author']['label'],$_SERVER["PHP_SELF"],"cf.fk_author","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['cf.date_commande']['checked'])) print_liste_field_titre($arrayfields['cf.date_commande']['label'],$_SERVER["PHP_SELF"],"cf.date_commande","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.date_delivery']['checked'])) print_liste_field_titre($arrayfields['cf.date_delivery']['label'],$_SERVER["PHP_SELF"],'cf.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.total_ht']['label'],$_SERVER["PHP_SELF"],"cf.total_ht","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.total_vat']['label'],$_SERVER["PHP_SELF"],"cf.tva","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.total_ttc']['label'],$_SERVER["PHP_SELF"],"cf.total_ttc","",$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['cf.datec']['checked'])) print_liste_field_titre($arrayfields['cf.datec']['label'],$_SERVER["PHP_SELF"],"cf.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.tms']['checked'])) print_liste_field_titre($arrayfields['cf.tms']['label'],$_SERVER["PHP_SELF"],"cf.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.fk_statut']['checked'])) print_liste_field_titre($arrayfields['cf.fk_statut']['label'],$_SERVER["PHP_SELF"],"cf.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.billed']['checked'])) print_liste_field_titre($arrayfields['cf.billed']['label'],$_SERVER["PHP_SELF"],'cf.billed','',$param,'align="center"',$sortfield,$sortorder,''); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; // Ref if (! empty($arrayfields['cf.ref']['checked'])) { @@ -687,6 +647,47 @@ if ($resql) print "\n"; + print ''; + if (! empty($arrayfields['cf.ref']['checked'])) print_liste_field_titre($arrayfields['cf.ref']['label'],$_SERVER["PHP_SELF"],"cf.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['cf.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['cf.ref_supplier']['label'],$_SERVER["PHP_SELF"],"cf.ref_supplier","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['p.project_ref']['checked'])) print_liste_field_titre($arrayfields['p.project_ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($arrayfields['u.login']['label'],$_SERVER["PHP_SELF"],"u.login","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.fk_author']['checked'])) print_liste_field_titre($arrayfields['cf.fk_author']['label'],$_SERVER["PHP_SELF"],"cf.fk_author","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['cf.date_commande']['checked'])) print_liste_field_titre($arrayfields['cf.date_commande']['label'],$_SERVER["PHP_SELF"],"cf.date_commande","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.date_delivery']['checked'])) print_liste_field_titre($arrayfields['cf.date_delivery']['label'],$_SERVER["PHP_SELF"],'cf.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.total_ht']['label'],$_SERVER["PHP_SELF"],"cf.total_ht","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.total_vat']['label'],$_SERVER["PHP_SELF"],"cf.tva","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.total_ttc']['label'],$_SERVER["PHP_SELF"],"cf.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['cf.datec']['checked'])) print_liste_field_titre($arrayfields['cf.datec']['label'],$_SERVER["PHP_SELF"],"cf.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.tms']['checked'])) print_liste_field_titre($arrayfields['cf.tms']['label'],$_SERVER["PHP_SELF"],"cf.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.fk_statut']['checked'])) print_liste_field_titre($arrayfields['cf.fk_statut']['label'],$_SERVER["PHP_SELF"],"cf.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.billed']['checked'])) print_liste_field_titre($arrayfields['cf.billed']['label'],$_SERVER["PHP_SELF"],'cf.billed','',$param,'align="center"',$sortfield,$sortorder,''); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $total=0; $subtotal=0; $productstat_cache=array(); diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 3afb97c5fb1..dbfc9d8fd3c 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -490,48 +490,10 @@ if ($resql) print '
    '; print '
    '."\n"; - print ''; - if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'],$_SERVER['PHP_SELF'],'f.ref,f.rowid','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['f.ref_supplier']['label'],$_SERVER["PHP_SELF"],'f.ref_supplier','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.label']['checked'])) print_liste_field_titre($arrayfields['f.label']['label'],$_SERVER['PHP_SELF'],"f.libelle,f.rowid",'',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.datef']['checked'])) print_liste_field_titre($arrayfields['f.datef']['label'],$_SERVER['PHP_SELF'],'f.datef,f.rowid','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER['PHP_SELF'],"p.ref",'',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER['PHP_SELF'],'s.nom','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; + // Line for filters - - print ''; + print ''; // Ref if (! empty($arrayfields['f.ref']['checked'])) { @@ -690,6 +652,45 @@ if ($resql) print "\n"; + print ''; + if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'],$_SERVER['PHP_SELF'],'f.ref,f.rowid','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['f.ref_supplier']['label'],$_SERVER["PHP_SELF"],'f.ref_supplier','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.label']['checked'])) print_liste_field_titre($arrayfields['f.label']['label'],$_SERVER['PHP_SELF'],"f.libelle,f.rowid",'',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.datef']['checked'])) print_liste_field_titre($arrayfields['f.datef']['label'],$_SERVER['PHP_SELF'],'f.datef,f.rowid','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER['PHP_SELF'],"p.ref",'',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER['PHP_SELF'],'s.nom','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $facturestatic=new FactureFournisseur($db); $supplierstatic=new Fournisseur($db); $projectstatic=new Project($db); diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 6e098e4f59d..db85e68c8cd 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -25,6 +25,8 @@ -- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); +ALTER TABLE llx_supplier_proposaldet ADD COLUMN fk_unit integer DEFAULT NULL; + ALTER TABLE llx_ecm_files ADD COLUMN ref varchar(128) AFTER rowid; ALTER TABLE llx_ecm_files CHANGE COLUMN fullpath filepath varchar(255); ALTER TABLE llx_ecm_files CHANGE COLUMN filepath filepath varchar(255); diff --git a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql index ebe44b0f702..4b669f60ba3 100644 --- a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql +++ b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql @@ -52,5 +52,5 @@ CREATE TABLE llx_supplier_proposaldet ( multicurrency_total_ht double(24,8) DEFAULT 0, multicurrency_total_tva double(24,8) DEFAULT 0, multicurrency_total_ttc double(24,8) DEFAULT 0, - fk_unit integer DEFAULT NULL -- lien vers table des unités + fk_unit integer DEFAULT NULL ) ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 7126e454d5c..236671eea4c 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -453,42 +453,8 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '."\n"; - -print ''; -if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['commercial']['checked'])) print_liste_field_titre($arrayfields['commercial']['label'],$_SERVER["PHP_SELF"],"","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['p.dateo']['checked'])) print_liste_field_titre($arrayfields['p.dateo']['label'],$_SERVER["PHP_SELF"],"p.dateo","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['p.datee']['checked'])) print_liste_field_titre($arrayfields['p.datee']['label'],$_SERVER["PHP_SELF"],"p.datee","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['p.public']['checked'])) print_liste_field_titre($arrayfields['p.public']['label'],$_SERVER["PHP_SELF"],"p.public","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['p.opp_amount']['checked'])) print_liste_field_titre($arrayfields['p.opp_amount']['label'],$_SERVER["PHP_SELF"],'p.opp_amount',"",$param,'align="right"',$sortfield,$sortorder); -if (! empty($arrayfields['p.fk_opp_status']['checked'])) print_liste_field_titre($arrayfields['p.fk_opp_status']['label'],$_SERVER["PHP_SELF"],'p.fk_opp_status',"",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['p.opp_percent']['checked'])) print_liste_field_titre($arrayfields['p.opp_percent']['label'],$_SERVER["PHP_SELF"],'p.opp_percent',"",$param,'align="right"',$sortfield,$sortorder); -if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'],$_SERVER["PHP_SELF"],'p.budget_amount',"",$param,'align="right"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; -print ''; +print ''; if (! empty($arrayfields['p.ref']['checked'])) { print ''; print ''."\n"; +print ''; +if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['commercial']['checked'])) print_liste_field_titre($arrayfields['commercial']['label'],$_SERVER["PHP_SELF"],"","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['p.dateo']['checked'])) print_liste_field_titre($arrayfields['p.dateo']['label'],$_SERVER["PHP_SELF"],"p.dateo","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['p.datee']['checked'])) print_liste_field_titre($arrayfields['p.datee']['label'],$_SERVER["PHP_SELF"],"p.datee","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['p.public']['checked'])) print_liste_field_titre($arrayfields['p.public']['label'],$_SERVER["PHP_SELF"],"p.public","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['p.opp_amount']['checked'])) print_liste_field_titre($arrayfields['p.opp_amount']['label'],$_SERVER["PHP_SELF"],'p.opp_amount',"",$param,'align="right"',$sortfield,$sortorder); +if (! empty($arrayfields['p.fk_opp_status']['checked'])) print_liste_field_titre($arrayfields['p.fk_opp_status']['label'],$_SERVER["PHP_SELF"],'p.fk_opp_status',"",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['p.opp_percent']['checked'])) print_liste_field_titre($arrayfields['p.opp_percent']['label'],$_SERVER["PHP_SELF"],'p.opp_percent',"",$param,'align="right"',$sortfield,$sortorder); +if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'],$_SERVER["PHP_SELF"],'p.budget_amount',"",$param,'align="right"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + $i=0; $totalarray=array(); while ($i < min($num,$limit)) diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 7d5e4eea1ae..dd43fd61d93 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -446,41 +446,7 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '; @@ -617,6 +583,40 @@ print '
    '."\n"; -print ''; -if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['t.label']['checked'])) print_liste_field_titre($arrayfields['t.label']['label'],$_SERVER["PHP_SELF"],"t.label","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'],$_SERVER["PHP_SELF"],"t.dateo","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.datee']['checked'])) print_liste_field_titre($arrayfields['t.datee']['label'],$_SERVER["PHP_SELF"],"t.datee","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'],$_SERVER["PHP_SELF"],"t.planned_workload","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'],$_SERVER["PHP_SELF"],"t.duration_effective","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'],$_SERVER["PHP_SELF"],"","",$param,'align="center"'); -if (! empty($arrayfields['t.progress']['checked'])) print_liste_field_titre($arrayfields['t.progress']['label'],$_SERVER["PHP_SELF"],"t.progress","",$param,'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - -print ''; +print ''; if (! empty($arrayfields['t.ref']['checked'])) { print ''; print "\n"; +print ''; +if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['t.label']['checked'])) print_liste_field_titre($arrayfields['t.label']['label'],$_SERVER["PHP_SELF"],"t.label","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'],$_SERVER["PHP_SELF"],"t.dateo","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.datee']['checked'])) print_liste_field_titre($arrayfields['t.datee']['label'],$_SERVER["PHP_SELF"],"t.datee","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'],$_SERVER["PHP_SELF"],"t.planned_workload","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'],$_SERVER["PHP_SELF"],"t.duration_effective","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'],$_SERVER["PHP_SELF"],"","",$param,'align="center"'); +if (! empty($arrayfields['t.progress']['checked'])) print_liste_field_titre($arrayfields['t.progress']['label'],$_SERVER["PHP_SELF"],"t.progress","",$param,'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + $plannedworkloadoutputformat='allhourmin'; $timespentoutputformat='allhourmin'; diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index fbb75e021ff..fc6e9ecb743 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -39,6 +39,7 @@ if (! empty($conf->projet->enabled)) { // Load traductions files requiredby by page $langs->load("resource"); $langs->load("other"); +$langs->load("interventions"); /* $sortorder = GETPOST('sortorder','alpha'); diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index caf79597e53..09dd0eb240c 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -509,23 +509,12 @@ if ($result) $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); print '
    '; print '
    '; @@ -588,6 +554,40 @@ print $searchpitco; print '
    '; - // Fields title - print ''; - print_liste_field_titre($langs->trans('Ref'),$_SERVER["PHP_SELF"],'sp.ref','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Supplier'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'sp.date_valid','',$param, 'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('SupplierProposalDate'),$_SERVER["PHP_SELF"],'sp.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'sp.total_ht','',$param, 'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Author'),$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'sp.fk_statut','',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; print ''; @@ -564,12 +553,24 @@ if ($result) print ''; // Check boxes print ''; print "\n"; + // Fields title + print ''; + print_liste_field_titre($langs->trans('Ref'),$_SERVER["PHP_SELF"],'sp.ref','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Supplier'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'sp.date_valid','',$param, 'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('SupplierProposalDate'),$_SERVER["PHP_SELF"],'sp.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'sp.total_ht','',$param, 'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Author'),$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'sp.fk_statut','',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $now = dol_now(); $var=true; $total=0; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 8d3ea40cb14..9b90e92e30d 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -269,7 +269,7 @@ input.select2-input { border-bottom: solid 1px rgba(0,0,0,.2) !important; /* required to avoid to lose bottom line when focus is lost on select2. */ } -.liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { +.liste_titre input[name=monthvalid], .liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } input, input.flat, form.flat select, select, select.flat, .dataTables_length label select { @@ -1064,6 +1064,9 @@ div.nopadding { .pictowarning, .pictopreview { padding-: 3px; } +.pictoedit, .pictowarning, .pictopreview, .pictodelete { + vertical-align: text-bottom; +} .colorthumb { padding-left: 1px !important; padding-right: 1px; @@ -2729,7 +2732,6 @@ tr.liste_titre th, tr.liste_titre td, th.liste_titre /* border-bottom: 1px solid #; */ border-bottom: 1px solid #888; } -/* TODO Once title line is moved under title search, make border bottom of all th black and force to white when it's first tr */ tr.liste_titre:first-child th, tr:first-child th.liste_titre { border-bottom: 1px solid #ddd ! important; } @@ -2758,7 +2760,7 @@ tr.liste_titre_topborder td { background: transparent; } tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ - border-bottom: 1px solid rgb(); + border-bottom: 1px solid #ddd; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index d80630f0501..2ae5decbf96 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -281,7 +281,7 @@ textarea.cke_source:focus box-shadow: none; } -.liste_titre input[name=month], .liste_titre input[name=month_lim] { +.liste_titre input[name=monthvalid], .liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select { @@ -1109,6 +1109,9 @@ table.noborder tr.liste_titre td { .pictowarning, .pictopreview { padding-: 3px; } +.pictoedit, .pictowarning, .pictopreview, .pictodelete { + vertical-align: text-bottom; +} .colorthumb { padding-left: 1px !important; padding-right: 1px; From c84e20abaf246b51f32d7d269d0aa1b4c1e844ba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Mar 2017 21:05:11 +0200 Subject: [PATCH 250/410] Fix translation --- htdocs/langs/en_US/propal.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index f383af9f1af..aefe8e89cd2 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -28,7 +28,7 @@ ShowPropal=Show proposal PropalsDraft=Drafts PropalsOpened=Open PropalStatusDraft=Draft (needs to be validated) -PropalStatusValidated=Validated (proposal is open) +PropalStatusValidated=Validated (proposal is opened) PropalStatusSigned=Signed (needs billing) PropalStatusNotSigned=Not signed (closed) PropalStatusBilled=Billed From ad3b54b93a01348a5ec65a88b4ae137629a70353 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Mar 2017 21:09:15 +0200 Subject: [PATCH 251/410] Fix regression --- htdocs/accountancy/customer/card.php | 2 +- htdocs/accountancy/expensereport/card.php | 2 +- htdocs/accountancy/journal/bankjournal.php | 1 - htdocs/accountancy/supplier/card.php | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/accountancy/customer/card.php b/htdocs/accountancy/customer/card.php index 7ec2a1903c8..baa70bf51e8 100644 --- a/htdocs/accountancy/customer/card.php +++ b/htdocs/accountancy/customer/card.php @@ -73,7 +73,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { * View */ -llxHeader("", $langs->trans(FicheVentilation)); +llxHeader("", $langs->trans('FicheVentilation')); if ($cancel == $langs->trans("Cancel")) { $action = ''; diff --git a/htdocs/accountancy/expensereport/card.php b/htdocs/accountancy/expensereport/card.php index 808214becce..52440385e50 100644 --- a/htdocs/accountancy/expensereport/card.php +++ b/htdocs/accountancy/expensereport/card.php @@ -76,7 +76,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { /* * View */ -llxHeader("", $langs->trans(FicheVentilation)); +llxHeader("", $langs->trans('FicheVentilation')); if ($cancel == $langs->trans("Cancel")) { $action = ''; diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 012a773b875..dc18a3417e8 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -131,7 +131,6 @@ $chargestatic = new ChargeSociales($db); $paymentdonstatic = new PaymentDonation($db); $paymentvatstatic = new TVA($db); $paymentsalstatic = new PaymentSalary($db); -$paymentsalstatic = new PaymentSalary($db); $paymentexpensereportstatic = new PaymentExpenseReport($db); // Get code of finance journal diff --git a/htdocs/accountancy/supplier/card.php b/htdocs/accountancy/supplier/card.php index 02b7a6aee59..b7c5979aa7a 100644 --- a/htdocs/accountancy/supplier/card.php +++ b/htdocs/accountancy/supplier/card.php @@ -76,7 +76,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { /* * View */ -llxHeader("", $langs->trans(FicheVentilation)); +llxHeader("", $langs->trans('FicheVentilation')); if ($cancel == $langs->trans("Cancel")) { $action = ''; From 06c2f049270d69f00f1917590593d6e3f63656b1 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 29 Mar 2017 06:32:26 +0200 Subject: [PATCH 252/410] Finish work on multijournal admin part Need harmonization on rights --- htdocs/accountancy/admin/journals_card.php | 54 ++-- .../class/accountingjournal.class.php | 273 ++++++------------ htdocs/core/lib/accounting.lib.php | 29 ++ htdocs/langs/en_US/accountancy.lang | 4 + 4 files changed, 140 insertions(+), 220 deletions(-) diff --git a/htdocs/accountancy/admin/journals_card.php b/htdocs/accountancy/admin/journals_card.php index c9c45f9a4e5..9e04d75ce9f 100644 --- a/htdocs/accountancy/admin/journals_card.php +++ b/htdocs/accountancy/admin/journals_card.php @@ -122,6 +122,15 @@ else if ($action == 'update') { $object->label = GETPOST('label', 'alpha'); $object->nature = GETPOST('nature', 'int'); + if (empty($object->code)) { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Code")), null, 'errors'); + $error ++; + } + if (empty($object->label)) { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors'); + $error ++; + } + $result = $object->update($user); if ($result > 0) { @@ -161,15 +170,15 @@ if ($action == 'create') print '
    '; print ''; print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; // Code - print ''; + print ''; // Label - print ''; + print ''; // Nature print ''; - print ''; + print ''; print ''; @@ -188,10 +197,10 @@ if ($action == 'create') } else if ($id) { $result = $object->fetch($id); if ($result > 0) { - $head = fiscalyear_prepare_head($object); + $head = accounting_journal_prepare_head($object); if ($action == 'edit') { - dol_fiche_head($head, 'card', $langs->trans("Fiscalyear"), 0, 'cron'); + dol_fiche_head($head, 'card', $langs->trans("AccountingJournal"), 0, 'cron'); print '' . "\n"; print ''; @@ -200,10 +209,10 @@ if ($action == 'create') print '
    ' . $langs->trans("Code") . '
    ' . $langs->trans("Code") . '
    ' . $langs->trans("Label") . '
    ' . $langs->trans("Label") . '
    ' . $langs->trans("Status") . '' . $langs->trans("Type") . ''; print $form->selectarray('nature', $type2label, GETPOST('nature')); print '
    '; - // Ref + // Code print ""; - print ''; // Label @@ -211,20 +220,9 @@ if ($action == 'create') print ''; print ''; - // Date start - print ''; - - // Date end - print ''; - // Nature print ''; print '
    ' . $langs->trans("Ref") . ''; - print $object->ref; + print '' . $langs->trans("Code") . ''; + print ''; print '
    ' . $langs->trans("DateStart") . ''; - print $form->select_date($object->date_start ? $object->date_start : - 1, 'fiscalyear'); - print '
    ' . $langs->trans("DateEnd") . ''; - print $form->select_date($object->date_end ? $object->date_end : - 1, 'fiscalyearend'); - print '
    ' . $langs->trans("Type") . ''; - // print $form->selectarray('statut', $statut2label, $object->statut); - print $object->getLibStatut(4); + print $form->selectarray('nature', $type2label, $object->nature); print '
    '; @@ -246,15 +244,15 @@ if ($action == 'create') print $form->formconfirm($_SERVER["PHP_SELF"] . "?id=" . $id, $langs->trans("DeleteFiscalYear"), $langs->trans("ConfirmDeleteFiscalYear"), "confirm_delete"); } - dol_fiche_head($head, 'card', $langs->trans("Fiscalyear"), 0, 'cron'); + dol_fiche_head($head, 'card', $langs->trans("AccountingJournal"), 0, 'cron'); print ''; - $linkback = '' . $langs->trans("BackToList") . ''; + $linkback = '' . $langs->trans("BackToList") . ''; // Ref - print ''; @@ -267,7 +265,7 @@ if ($action == 'create') print ""; // Nature - print ''; + print ''; print "
    ' . $langs->trans("Ref") . ''; - print $object->ref; + print '
    ' . $langs->trans("Code") . ''; + print $object->code; print ''; print $linkback; print '
    ' . $langs->trans("Type") . '' . $object->getLibType(0) . '
    ' . $langs->trans("Type") . '' . $object->getLibType(0) . '
    "; @@ -281,9 +279,9 @@ if ($action == 'create') print ''; } } diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 7b34c4171d8..d7cc61d6418 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -26,24 +26,18 @@ */ class AccountingJournal extends CommonObject { - var $db; - var $error; - var $errors; - var $id; + public $element='accounting_journal'; + public $table_element='accounting_journal'; + public $fk_element = ''; + protected $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + var $rowid; - var $datec; // Creation date - var $fk_pcg_version; - var $pcg_type; - var $pcg_subtype; - var $account_number; - var $account_parent; - var $account_category; + + var $code; var $label; - var $fk_user_author; - var $fk_user_modif; - var $active; // duplicate with status - var $status; - + var $nature; // 0:various operations, 1:sale, 2:purchase, 3:bank, 9: has-new + var $active; + /** * Constructor * @@ -54,133 +48,75 @@ class AccountingJournal extends CommonObject } /** - * Load record in memory - * - * @param int $rowid Id - * @param string $account_number Account number - * @param int $limittocurrentchart 1=Do not load record if it is into another accounting system - * @return int <0 if KO, Id of record if OK and found - */ - function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0) { - global $conf; - - if ($rowid || $account_number) { - $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.pcg_subtype, a.account_number, a.account_parent, a.label, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active"; - $sql .= ", ca.label as category_label"; - $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as a"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid"; - $sql .= " WHERE"; - if ($rowid) { - $sql .= " a.rowid = '" . $rowid . "'"; - } elseif ($account_number) { - $sql .= " a.account_number = '" . $account_number . "'"; - } - if (! empty($limittocurrentchart)) { - $sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS . ')'; - } + * Load an object from database + * + * @param int $id Id of record to load + * @return int <0 if KO, >0 if OK + */ + function fetch($id) + { + $sql = "SELECT rowid, code, label, nature, active"; + $sql.= " FROM ".MAIN_DB_PREFIX."accounting_journal"; + $sql.= " WHERE rowid = ".$id; - dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $obj = $this->db->fetch_object($result); - - if ($obj) { - $this->id = $obj->rowid; - $this->rowid = $obj->rowid; - $this->datec = $obj->datec; - $this->tms = $obj->tms; - $this->fk_pcg_version = $obj->fk_pcg_version; - $this->pcg_type = $obj->pcg_type; - $this->pcg_subtype = $obj->pcg_subtype; - $this->account_number = $obj->account_number; - $this->account_parent = $obj->account_parent; - $this->label = $obj->label; - $this->account_category = $obj->fk_accounting_category; - $this->account_category_label = $obj->category_label; - $this->fk_user_author = $obj->fk_user_author; - $this->fk_user_modif = $obj->fk_user_modif; - $this->active = $obj->active; - $this->status = $obj->active; - - return $this->id; - } else { - return 0; - } - } else { - $this->error = "Error " . $this->db->lasterror(); - $this->errors[] = "Error " . $this->db->lasterror(); - } + dol_syslog(get_class($this)."::fetch sql=" . $sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ( $result ) + { + $obj = $this->db->fetch_object($result); + + $this->id = $obj->rowid; + + $this->code = $obj->code; + $this->ref = $obj->code; + $this->label = $obj->label; + $this->nature = $obj->nature; + $this->active = $obj->active; + + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; } - return - 1; } /** - * Insert new accounting account in chart of accounts + * Insert journal in database * - * @param User $user Use making action - * @param int $notrigger Disable triggers - * @return int <0 if KO, >0 if OK + * @param User $user Use making action + * @param int $notrigger Disable triggers + * @return int <0 if KO, >0 if OK */ - function create($user, $notrigger = 0) { + function create($user, $notrigger = 0) + { global $conf; $error = 0; $now = dol_now(); // Clean parameters - if (isset($this->fk_pcg_version)) - $this->fk_pcg_version = trim($this->fk_pcg_version); - if (isset($this->pcg_type)) - $this->pcg_type = trim($this->pcg_type); - if (isset($this->pcg_subtype)) - $this->pcg_subtype = trim($this->pcg_subtype); - if (isset($this->account_number)) - $this->account_number = trim($this->account_number); - if (isset($this->account_parent)) - $this->account_parent = trim($this->account_parent); + if (isset($this->code)) + $this->code = trim($this->code); if (isset($this->label)) $this->label = trim($this->label); - if (isset($this->account_category)) - $this->account_category = trim($this->account_category); - if (isset($this->fk_user_author)) - $this->fk_user_author = trim($this->fk_user_author); - if (isset($this->active)) - $this->active = trim($this->active); - - if (empty($this->pcg_type) || $this->pcg_type == '-1') - { - $this->pcg_type = 'XXXXXX'; - } - if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') - { - $this->pcg_subtype = 'XXXXXX'; - } + // Check parameters - // Put here code to add control on parameters values - + if (empty($this->nature) || $this->nature == '-1') + { + $this->nature = '0'; + } + // Insert request - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account("; - $sql .= "datec"; - $sql .= ", entity"; - $sql .= ", fk_pcg_version"; - $sql .= ", pcg_type"; - $sql .= ", pcg_subtype"; - $sql .= ", account_number"; - $sql .= ", account_parent"; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_journal("; + $sql .= "code"; $sql .= ", label"; - $sql .= ", fk_accounting_category"; - $sql .= ", fk_user_author"; + $sql .= ", nature"; $sql .= ", active"; $sql .= ") VALUES ("; - $sql .= " '" . $this->db->idate($now) . "'"; - $sql .= ", " . $conf->entity; - $sql .= ", " . (empty($this->fk_pcg_version) ? 'NULL' : "'" . $this->db->escape($this->fk_pcg_version) . "'"); - $sql .= ", " . (empty($this->pcg_type) ? 'NULL' : "'" . $this->db->escape($this->pcg_type) . "'"); - $sql .= ", " . (empty($this->pcg_subtype) ? 'NULL' : "'" . $this->pcg_subtype . "'"); - $sql .= ", " . (empty($this->account_number) ? 'NULL' : "'" . $this->account_number . "'"); - $sql .= ", " . (empty($this->account_parent) ? 'NULL' : "'" . $this->db->escape($this->account_parent) . "'"); + $sql .= " " . (empty($this->code) ? 'NULL' : "'" . $this->db->escape($this->code) . "'"); $sql .= ", " . (empty($this->label) ? 'NULL' : "'" . $this->db->escape($this->label) . "'"); - $sql .= ", " . (empty($this->account_category) ? 'NULL' : "'" . $this->db->escape($this->account_category) . "'"); - $sql .= ", " . $user->id; + $sql .= ", " . (empty($this->nature) ? '0' : "'" . $this->db->escape($this->nature) . "'"); $sql .= ", " . (! isset($this->active) ? 'NULL' : $this->db->escape($this->active)); $sql .= ")"; @@ -194,7 +130,7 @@ class AccountingJournal extends CommonObject } if (! $error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account"); + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_journal"); // if (! $notrigger) { // Uncomment this and change MYOBJECT to your own tag if you @@ -232,26 +168,17 @@ class AccountingJournal extends CommonObject function update($user) { // Check parameters - if (empty($this->pcg_type) || $this->pcg_type == '-1') + if (empty($this->nature) || $this->nature == '-1') { - $this->pcg_type = 'XXXXXX'; + $this->nature = '0'; } - if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') - { - $this->pcg_subtype = 'XXXXXX'; - } - + $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; - $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null"); - $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null"); - $sql .= " , pcg_subtype = " . ($this->pcg_subtype ? "'" . $this->db->escape($this->pcg_subtype) . "'" : "null"); - $sql .= " , account_number = '" . $this->account_number . "'"; - $sql .= " , account_parent = '" . $this->account_parent . "'"; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_journal "; + $sql .= " SET code = " . ($this->code ? "'" . $this->db->escape($this->code) . "'" : "null"); $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "null"); - $sql .= " , fk_accounting_category = '" . $this->account_category . "'"; - $sql .= " , fk_user_modif = " . $user->id; + $sql .= " , nature = " . ($this->nature ? "'" . $this->db->escape($this->nature) . "'" : "0"); $sql .= " , active = '" . $this->active . "'"; $sql .= " WHERE rowid = " . $this->id; @@ -268,7 +195,7 @@ class AccountingJournal extends CommonObject } /** - * Check usage of accounting code + * Check usage of accounting journal * * @return int <0 if KO, >0 if OK */ @@ -287,7 +214,7 @@ class AccountingJournal extends CommonObject if ($resql) { $num = $this->db->num_rows($resql); if ($num > 0) { - $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse'); + $this->error = $langs->trans('ErrorAccountingJournalIsAlreadyUse'); return 0; } else { return 1; @@ -329,7 +256,7 @@ class AccountingJournal extends CommonObject // } if (! $error) { - $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account"; + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_journal"; $sql .= " WHERE rowid=" . $this->id; dol_syslog(get_class($this) . "::delete sql=" . $sql); @@ -360,85 +287,47 @@ class AccountingJournal extends CommonObject /** * Return clicable name (with picto eventually) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @return string Chaine avec URL + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @return string Chaine avec URL */ function getNomUrl($withpicto = 0) { global $langs; $result = ''; - $link = ''; + $link = ''; $linkend = ''; $picto = 'billr'; - $label = $langs->trans("Show") . ': ' . $this->account_number . ' - ' . $this->label; + $label = $langs->trans("Show") . ': ' . $this->code . ' - ' . $this->label; if ($withpicto) $result .= ($link . img_object($label, $picto) . $linkend); if ($withpicto && $withpicto != 2) $result .= ' '; if ($withpicto != 2) - require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; - $result .= $link . length_accountg($this->account_number) . ' - ' . $this->label . $linkend; + $result .= $link . $this->code . ' - ' . $this->label . $linkend; return $result; } /** - * Information on record - * - * @param int $id of record - * @return void - */ - function info($id) { - $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms'; - $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a'; - $sql .= ' WHERE a.rowid = ' . $id; - - dol_syslog(get_class($this) . '::info sql=' . $sql); - $result = $this->db->query($sql); - - if ($result) { - if ($this->db->num_rows($result)) { - $obj = $this->db->fetch_object($result); - $this->id = $obj->rowid; - if ($obj->fk_user_author) { - $cuser = new User($this->db); - $cuser->fetch($obj->fk_user_author); - $this->user_creation = $cuser; - } - if ($obj->fk_user_modif) { - $muser = new User($this->db); - $muser->fetch($obj->fk_user_modif); - $this->user_modification = $muser; - } - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_modification = $this->db->jdate($obj->tms); - } - $this->db->free($result); - } else { - dol_print_error($this->db); - } - } - - /** - * Account desactivate + * Deactivate journal * * @param int $id Id * @return int <0 if KO, >0 if OK */ - function account_desactivate($id) { + function journal_deactivate($id) { $result = $this->checkUsage(); if ($result > 0) { $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_journal "; $sql .= "SET active = '0'"; $sql .= " WHERE rowid = " . $this->db->escape($id); - dol_syslog(get_class($this) . "::desactivate sql=" . $sql, LOG_DEBUG); + dol_syslog(get_class($this) . "::deactivate sql=" . $sql, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { @@ -455,15 +344,15 @@ class AccountingJournal extends CommonObject } /** - * Account activate + * Activate journal * * @param int $id Id * @return int <0 if KO, >0 if OK */ - function account_activate($id) { + function journal_activate($id) { $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_journal "; $sql .= "SET active = '1'"; $sql .= " WHERE rowid = " . $this->db->escape($id); diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 205acb9ba80..56fdc8e6de9 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -91,6 +91,35 @@ function accounting_prepare_head(AccountingAccount $object) return $head; } +/** + * Prepare array with list of tabs + * + * @param AccountingAccount $object Accounting account + * @return array Array of tabs to show + */ +function accounting_journal_prepare_head(AccountingJournal $object) +{ + global $langs, $conf; + + $h = 0; + $head = array (); + + $head[$h][0] = DOL_URL_ROOT.'/accountancy/admin/journals_card.php?id=' . $object->id; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $h ++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab + // $this->tabs = array('entity:-tabname); to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_journal'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_journal', 'remove'); + + return $head; +} + /** * Return accounting account without zero on the right * diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index f35b61055ad..42c5c519d2c 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -199,13 +199,17 @@ ApplyMassCategories=Apply mass categories AddAccountFromBookKeepingWithNoCategories=Add acccount already used with no categories CategoryDeleted=Category for the accounting account has been removed AccountingJournals=Accounting journals +AccountingJournal=Accounting journal NewAccountingJournal=New accounting journal ShowAccoutingJournal=Show accounting journal +Code=Code +Nature=Nature AccountingJournalTypeVariousOperation=Various operation AccountingJournalTypeSale=Sale AccountingJournalTypePurchase=Purchase AccountingJournalTypeBank=Bank AccountingJournalTypeHasNew=Has-new +ErrorAccountingJournalIsAlreadyUse=This journal is already use ## Export Exports=Exports From 4fa5448aaba62721831283922f62683037efc760 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 10:34:33 +0200 Subject: [PATCH 253/410] FIX Detection of color brightness --- htdocs/core/class/html.formother.class.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 4ae2d81539d..270deb2134e 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -604,10 +604,22 @@ class FormOther $textcolor='FFF'; if ($color) { - $hex=$color; - $r = hexdec($hex[0].$hex[1]); - $g = hexdec($hex[2].$hex[3]); - $b = hexdec($hex[4].$hex[5]); + $tmp=explode(',', $color); + if (count($tmp) > 1) // This is a comma RGB ('255','255','255') + { + $r = $tmp[0]; + $g = $tmp[1]; + $b = $tmp[2]; + } + else + { + $hexr=$color[0].$color[1]; + $hexg=$color[2].$color[3]; + $hexb=$color[4].$color[5]; + $r = hexdec($hexr); + $g = hexdec($hexg); + $b = hexdec($hexb); + } $bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0; // HSL algorithm if ($bright > 0.6) $textcolor='000'; } From 54b03a35522b0d4b2171c0bad41de0e641def478 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 11:03:13 +0200 Subject: [PATCH 254/410] Work on 6.0 new look and feel --- htdocs/admin/ihm.php | 40 +++++++------- htdocs/comm/propal/list.php | 2 +- htdocs/commande/list.php | 3 +- htdocs/contact/list.php | 6 +-- htdocs/contrat/list.php | 2 +- htdocs/core/boxes/modules_boxes.php | 2 +- htdocs/core/lib/usergroups.lib.php | 2 +- htdocs/product/list.php | 83 ++++++++++++++--------------- htdocs/projet/list.php | 2 +- htdocs/projet/tasks/list.php | 2 +- htdocs/societe/list.php | 6 +-- htdocs/theme/eldy/style.css.php | 25 +++------ htdocs/theme/md/style.css.php | 7 ++- 13 files changed, 87 insertions(+), 95 deletions(-) diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 03fab048962..83f6701e2a1 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -165,14 +165,14 @@ if ($action == 'edit') // Edit print ''; // Default language - print ''.$langs->trans("DefaultLanguage").''; + print ''.$langs->trans("DefaultLanguage").''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'main_lang_default', 1, 0, 0, 0, 0, 'minwidth300'); print ''; print ' '; print ''; // Multilingual GUI - print ''.$langs->trans("EnableMultilangInterface").''; + print ''.$langs->trans("EnableMultilangInterface").''; print $form->selectyesno('main_multilangs',$conf->global->MAIN_MULTILANGS,1); print ''; print ' '; @@ -348,7 +348,7 @@ else // Show print ''; print ''; - print ''; print ""; - print ''; + print ''; print ''; print ""; @@ -378,7 +378,7 @@ else // Show foreach ($searchform as $key => $value) { - print ''; + print ''; print ''; @@ -391,11 +391,11 @@ else // Show print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").' 
    '.$langs->trans("DefaultLanguage").''; + print '
    '.$langs->trans("DefaultLanguage").''; $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); print ($s?$s.' ':''); print ($conf->global->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); @@ -358,7 +358,7 @@ else // Show print '
    '.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . '
    '.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . ' 
    '.$searchformtitle[$key].''.yn($searchformconst[$key]).'
    '.$searchformtitle[$key].''.yn($searchformconst[$key]).''; if (! empty($searchformmodule[$key])) print $langs->trans("IfModuleEnabled",$langs->transnoentitiesnoconv($searchformmodule[$key])); print '
    '; print ''; - print ''; + print ''; print ''; print ""; - print ''; + print ''; print ''; print ""; @@ -407,7 +407,7 @@ else // Show */ // Disable javascript/ajax - print '"; print ''; print ""; @@ -416,35 +416,35 @@ else // Show if (class_exists("Imagick")) { - print '"; print ''; print ""; } // First day for weeks - print ''; print ''; print ''; // DefaultWorkingDays - print ''; print ''; print ''; // DefaultWorkingHours - print ''; print ''; print ''; // Firstname / Name position - print ''; @@ -452,12 +452,12 @@ else // Show print ''; // Hide unauthorized button - print ''; // Show logo - print ''; + print ''; print ''; print ""; @@ -471,29 +471,29 @@ else // Show */ // Show bugtrack link - print '"; print ''; print ""; // Link to wiki help - print ''; // Link to help center - print ''; // Message login - print ''."\n"; // Message of the day - print ''."\n"; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 0ff70fe9107..fdcbdde5ca8 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -751,7 +751,7 @@ if ($resql) $objectstatic->id=$obj->rowid; $objectstatic->ref=$obj->ref; - print ''; + print ''; if (! empty($arrayfields['p.ref']['checked'])) { diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 03b9cfce56a..37170e0af84 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1048,7 +1048,8 @@ if ($resql) while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); - print ''; + + print ''; $notshippable=0; $warning = 0; diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 80649ef4e06..4e7a9c6f190 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -651,7 +651,7 @@ while ($i < min($num,$limit)) { $obj = $db->fetch_object($result); - print ""; + print ''; $contactstatic->lastname=$obj->lastname; $contactstatic->firstname=''; @@ -669,8 +669,8 @@ while ($i < min($num,$limit)) if (! empty($arrayfields['p.lastname']['checked'])) { print ''; + print $contactstatic->getNomUrl(1,'',0); + print ''; } // Firstname if (! empty($arrayfields['p.firstname']['checked'])) diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index c382bfc7612..0224da7d88c 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -563,7 +563,7 @@ if ($resql) $contracttmp->ref_customer=$obj->ref_customer; $contracttmp->ref_supplier=$obj->ref_supplier; - print ''; + print ''; if (! empty($arrayfields['c.ref']['checked'])) { print ''; + $out.= ''; $out.= ' 0) { $out.= ' colspan="'.$nbcol.'"'; } $out.= '>'; diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 0c735a97c2f..6e6e0c7b511 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -589,7 +589,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) { print $formother->showColor($conf->global->THEME_ELDY_BACKTITLE1, $langs->trans("Default")); } - print '   ('.$langs->trans("Default").': e6e6e6) '; + print '   ('.$langs->trans("Default").': f0f0f0) '; // $colorbacktitle1 in CSS print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); print ''; diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 85b63077a05..69108a893d9 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -473,45 +473,9 @@ else print '
    '; print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '
    '.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . ' 
    '.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '
    '.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . ' 
    '.$langs->trans("DisableJavascript").''; + print '
    '.$langs->trans("DisableJavascript").''; print yn($conf->global->MAIN_DISABLE_JAVASCRIPT)." 
    '.$langs->trans("UsePreviewTabs").''; + print '
    '.$langs->trans("UsePreviewTabs").''; print yn(isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0)." 
    '.$langs->trans("WeekStartOnDay").''; + print '
    '.$langs->trans("WeekStartOnDay").''; print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); print ' 
    '.$langs->trans("DefaultWorkingDays").''; + print '
    '.$langs->trans("DefaultWorkingDays").''; print isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5'; print ' 
    '.$langs->trans("DefaultWorkingHours").''; + print '
    '.$langs->trans("DefaultWorkingHours").''; print isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18'; print ' 
    '.$langs->trans("FirstnameNamePosition").''; + print '
    '.$langs->trans("FirstnameNamePosition").''; if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print $langs->trans("Firstname").' '.$langs->trans("Lastname"); } else { print $langs->trans("Lastname").' '.$langs->trans("Firstname"); } print '
    '.$langs->trans("ButtonHideUnauthorized").''; + print '
    '.$langs->trans("ButtonHideUnauthorized").''; print yn((isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0),1); print '
    '.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . '
    '.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . ' 
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; + print '
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; print yn($conf->global->MAIN_BUGTRACK_ENABLELINK)." 
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + print '
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); print '
    '.$langs->trans("DisableLinkToHelpCenter").''; + print '
    '.$langs->trans("DisableLinkToHelpCenter").''; print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); print '
    '.$langs->trans("MessageLogin").''; + print '
    '.$langs->trans("MessageLogin").''; if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); else print ' '; print '
    '.$langs->trans("MessageOfDay").''; + print '
    '.$langs->trans("MessageOfDay").''; if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); else print ' '; print '
    '; - print $contactstatic->getNomUrl(1,'',0); - print '
    '; diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 26ee34bdca0..c016741cb39 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -234,7 +234,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" // Show box title if (! empty($head['text']) || ! empty($head['sublink']) || ! empty($head['subpicto'])) { - $out.= '
    '."\n"; - print ''; - if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['pfp.ref_fourn']['checked'])) print_liste_field_titre($arrayfields['pfp.ref_fourn']['label'], $_SERVER["PHP_SELF"],"pfp.ref_fourn","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['p.label']['checked'])) print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"],"p.label","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['p.barcode']['checked'])) print_liste_field_titre($arrayfields['p.barcode']['label'], $_SERVER["PHP_SELF"],"p.barcode","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['p.duration']['checked'])) print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"],"p.duration","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['p.sellprice']['checked'])) print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.minbuyprice']['checked'])) print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.seuil_stock_alerte']['checked'])) print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.desiredstock']['checked'])) print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.stock']['checked'])) print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['stock_virtual']['checked'])) print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder); - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['p.tosell']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.tobuy']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - + // Lines with input filters - print ''; + print ''; if (! empty($arrayfields['p.ref']['checked'])) { print ''; - + print ''; + if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['pfp.ref_fourn']['checked'])) print_liste_field_titre($arrayfields['pfp.ref_fourn']['label'], $_SERVER["PHP_SELF"],"pfp.ref_fourn","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['p.label']['checked'])) print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"],"p.label","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['p.barcode']['checked'])) print_liste_field_titre($arrayfields['p.barcode']['label'], $_SERVER["PHP_SELF"],"p.barcode","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['p.duration']['checked'])) print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"],"p.duration","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['p.sellprice']['checked'])) print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.minbuyprice']['checked'])) print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.seuil_stock_alerte']['checked'])) print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.desiredstock']['checked'])) print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.stock']['checked'])) print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['stock_virtual']['checked'])) print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder); + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['p.tosell']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.tobuy']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $product_static=new Product($db); $product_fourn =new ProductFournisseur($db); - $var=true; $i = 0; while ($i < min($num,$limit)) { @@ -669,8 +669,7 @@ else } - $var=!$var; - print ''; + print ''; // Ref if (! empty($arrayfields['p.ref']['checked'])) diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 236671eea4c..c8335676700 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -634,7 +634,7 @@ while ($i < min($num,$limit)) $userAccess = $projectstatic->restrictedProjectArea($user); // why this ? if ($userAccess >= 0) { - print ""; + print ''; // Project url if (! empty($arrayfields['p.ref']['checked'])) diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index dd43fd61d93..a6a4c855474 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -619,7 +619,7 @@ while ($i < min($num,$limit)) $userAccess = $projectstatic->restrictedProjectArea($user); // why this ? if ($userAccess >= 0) { - print ""; + print ''; // Ref if (! empty($arrayfields['t.ref']['checked'])) diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index c4412660ea7..1a9980bbf12 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -907,10 +907,10 @@ while ($i < min($num, $limit)) $companystatic->code_compta_client=$obj->code_compta; $companystatic->code_compta_fournisseur=$obj->code_compta_fournisseur; - $companystatic->fk_prospectlevel=$obj->fk_prospectlevel; - $companystatic->name_alias=$obj->name_alias; + $companystatic->fk_prospectlevel=$obj->fk_prospectlevel; + $companystatic->name_alias=$obj->name_alias; - print ""; + print ''; if (! empty($arrayfields['s.nom']['checked'])) { print '';\n"; + } + } + $targetcontent=preg_replace('/LIST_OF_TD_TITLE_SEARCH/', $varprop, $targetcontent); + + // Substitute where for + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $varprop.="if (! empty(\$arrayfields['t.".$prop['field']."']['checked'])) print '';\n"; + } + } + $targetcontent=preg_replace('/'.preg_quote("if (! empty(\$arrayfields['t.field1']['checked'])) print '';",'/').'/', $varprop, $targetcontent); + $targetcontent=preg_replace('/'.preg_quote("if (! empty(\$arrayfields['t.field2']['checked'])) print '';",'/').'/', '', $targetcontent); + + // LIST_OF_TD_LABEL_FIELDS_CREATE - List of td for card view + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $varprop.="print '';\n"; + } + } + $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_CREATE/', $varprop, $targetcontent); + + // LIST_OF_TD_LABEL_FIELDS_EDIT - List of td for card view + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $baseString = 'print "";'; + $varprop.= sprintf("\t ".$baseString." \n", $prop['field'], $prop['field'], $prop['field']); + } + } + $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_EDIT/', $varprop, $targetcontent); + + // LIST_OF_TD_LABEL_FIELDS_VIEW - List of td for card view + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $varprop.=sprintf("\t print '';\n",$prop['field'],$prop['field']); + } + } + $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_VIEW/', $varprop, $targetcontent); + + + // LIST_OF_TD_FIELDS_LIST + + + + // Build file + $fp=fopen($outfile,"w"); + if ($fp) + { + fputs($fp, $targetcontent); + fclose($fp); + print "File '".$outfile."' has been built in current directory.\n"; + } + else $error++; +} + + +// -------------------- END OF BUILD_CLASS_FROM_TABLE SCRIPT -------------------- + +print "You can now move generated files to store them into directory /yourmodule/class (for .class.php file) or /yourmodule.\n"; +return $error; diff --git a/htdocs/modulebuilder/skeletons/build_webservice_from_class.php b/htdocs/modulebuilder/skeletons/build_webservice_from_class.php new file mode 100755 index 00000000000..c91347a424d --- /dev/null +++ b/htdocs/modulebuilder/skeletons/build_webservice_from_class.php @@ -0,0 +1,179 @@ +#!/usr/bin/env php + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/build_webservice_from_class.php + * \ingroup core + * \brief Create a complete webservice file from CRUD functions of a PHP class + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit; +} + +// Include Dolibarr environment +require_once($path."../../htdocs/master.inc.php"); +// After this $db is a defined handler to database. + +// Main +$version='1.8'; +@set_time_limit(0); +$error=0; + +$langs->load("main"); + + +print "***** $script_file ($version) *****\n"; + + +// -------------------- START OF BUILD_CLASS_FROM_TABLE SCRIPT -------------------- + +// Check parameters +if (! isset($argv[1]) && ! isset($argv[2])) +{ + print "Usage: $script_file phpClassFile phpClassName\n"; + exit; +} + +// Show parameters +print 'Classfile='.$argv[1]."\n"; +print 'Classname='.$argv[2]."\n"; + +$classfile=$argv[1]; +$classname=$argv[2]; +$classmin=strtolower($classname); +$property=array(); +$targetcontent=''; + +// Load the class and read properties +require_once($classfile); + +$property=array(); +$class = new $classname($db); +$values=get_class_vars($classname); + +unset($values['db']); +unset($values['error']); +unset($values['errors']); +unset($values['element']); +unset($values['table_element']); +unset($values['table_element_line']); +unset($values['fk_element']); +unset($values['ismultientitymanaged']); + +$properties=array_keys($values); + +// Read skeleton_class.class.php file +$skeletonfile='skeleton_webservice_server.php'; +$sourcecontent=file_get_contents($skeletonfile); +if (! $sourcecontent) +{ + print "\n"; + print "Error: Failed to read skeleton sample '".$skeletonfile."'\n"; + print "Try to run script from skeletons directory.\n"; + exit; +} + +// Define output variables +$outfile='out.server_'.$classmin.'.php'; +$targetcontent=$sourcecontent; + + + +// Substitute class name +$targetcontent=preg_replace('/Skeleton/', $classname, $targetcontent); +$targetcontent=preg_replace('/skeleton/', $classmin, $targetcontent); + +// Substitute declaration parameters +$varprop="\n"; +$cleanparam=''; +$i=0; + +while($i array('name'=>'".$properties[$i]."','type'=>'xsd:string')"; + $i++; + + if ($i == count($properties)) + $varprop.="\n"; + else + $varprop.=",\n"; +} + +$targetcontent=preg_replace('/\'prop1\'=>\'xxx\',/', $varprop, $targetcontent); +$targetcontent=preg_replace('/\'prop2\'=>\'xxx\',/', '', $targetcontent); +// Substitute get method parameters +$varprop="\n"; +$cleanparam=''; +$i=0; + +while($i $".$classmin."->".$properties[$i]; + + $i++; + if ($i == count($properties)) + $varprop.="\n"; + else + $varprop.=",\n"; +} + +$targetcontent=preg_replace('/\'prop1\'=>\$'.$classmin.'->prop1,/', $varprop, $targetcontent); +$targetcontent=preg_replace('/\'prop2\'=>\$'.$classmin.'->prop2,/', '', $targetcontent); + +// Substitute get method parameters +$varprop="\n\t\t"; +$cleanparam=''; +$i=0; + +while($i'.$properties[$i].';'; + + $i++; + if ($i == count($properties)) + $varprop.="\n"; + else + $varprop.="\n\t\t"; +} +$targetcontent=preg_replace('/\$newobject->prop1=\$'.$classmin.'->prop1;/', $varprop, $targetcontent); +$targetcontent=preg_replace('/\$newobject->prop2=\$'.$classmin.'->prop2;/', '', $targetcontent); + + + +// Build file +$fp=fopen($outfile,"w"); +if ($fp) +{ + fputs($fp, $targetcontent); + fclose($fp); + print "File '".$outfile."' has been built in current directory.\n"; +} +else $error++; + +// -------------------- END OF BUILD_CLASS_FROM_TABLE SCRIPT -------------------- + +print "You must rename files by removing the 'out.' prefix in their name.\n"; +return $error; diff --git a/htdocs/modulebuilder/skeletons/modMyModule.class.php b/htdocs/modulebuilder/skeletons/modMyModule.class.php new file mode 100644 index 00000000000..4f994c7c654 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/modMyModule.class.php @@ -0,0 +1,291 @@ + + * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2005-2016 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \defgroup mymodule Module MyModule + * \brief Example of a module descriptor. + * Such a file must be copied into htdocs/mymodule/core/modules directory. + * \file htdocs/mymodule/core/modules/modMyModule.class.php + * \ingroup mymodule + * \brief Description and activation file for module MyModule + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + + +/** + * Description and activation class for module MyModule + */ +class modMyModule extends DolibarrModules +{ + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $langs,$conf; + + $this->db = $db; + + // Id for module (must be unique). + // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id). + $this->numero = 500000; // TODO Go on page http://wiki.dolibarr.org/index.php/List_of_modules_id to reserve id number for your module + // Key text used to identify module (for permissions, menus, etc...) + $this->rights_class = 'mymodule'; + + // Family can be 'crm','financial','hr','projects','products','ecm','technic','interface','other' + // It is used to group modules by family in module setup page + $this->family = "other"; + // Module position in the family + $this->module_position = 500; + // Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this) + //$this->familyinfo = array('myownfamily' => array('position' => '001', 'label' => $langs->trans("MyOwnFamily"))); + + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) + $this->description = "Description of module MyModule"; + $this->descriptionlong = "A very long description. Can be a full HTML content"; + $this->editor_name = 'Editor name'; + $this->editor_url = 'https://www.dolibarr.org'; + + // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' + $this->version = '1.0'; + // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Name of image file used for this module. + // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' + // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' + $this->picto='generic'; + + // Defined all module parts (triggers, login, substitutions, menus, css, etc...) + // for default path (eg: /mymodule/core/xxxxx) (0=disable, 1=enable) + // for specific path of parts (eg: /mymodule/core/modules/barcode) + // for specific css file (eg: /mymodule/css/mymodule.css.php) + //$this->module_parts = array( + // 'triggers' => 0, // Set this to 1 if module has its own trigger directory (core/triggers) + // 'login' => 0, // Set this to 1 if module has its own login method directory (core/login) + // 'substitutions' => 0, // Set this to 1 if module has its own substitution function file (core/substitutions) + // 'menus' => 0, // Set this to 1 if module has its own menus handler directory (core/menus) + // 'theme' => 0, // Set this to 1 if module has its own theme directory (theme) + // 'tpl' => 0, // Set this to 1 if module overwrite template dir (core/tpl) + // 'barcode' => 0, // Set this to 1 if module has its own barcode directory (core/modules/barcode) + // 'models' => 0, // Set this to 1 if module has its own models directory (core/modules/xxx) + // 'css' => array('/mymodule/css/mymodule.css.php'), // Set this to relative path of css file if module has its own css file + // 'js' => array('/mymodule/js/mymodule.js'), // Set this to relative path of js file if module must load a js on all pages + // 'hooks' => array('hookcontext1','hookcontext2',...) // Set here all hooks context managed by module. You can also set hook context 'all' + // 'dir' => array('output' => 'othermodulename'), // To force the default directories names + // 'workflow' => array('WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2'=>array('enabled'=>'! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', 'picto'=>'yourpicto@mymodule')) // Set here all workflow context managed by module + // ); + $this->module_parts = array(); + + // Data directories to create when module is enabled. + // Example: this->dirs = array("/mymodule/temp"); + $this->dirs = array(); + + // Config pages. Put here list of php page, stored into mymodule/admin directory, to use to setup module. + $this->config_page_url = array("mysetuppage.php@mymodule"); + + // Dependencies + $this->hidden = false; // A condition to hide module + $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled + $this->requiredby = array(); // List of module ids to disable if this one is disabled + $this->conflictwith = array(); // List of module class names as string this module is in conflict with + $this->phpmin = array(5,0); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,0); // Minimum version of Dolibarr required by module + $this->langfiles = array("mylangfile@mymodule"); + + // Constants + // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive) + // Example: $this->const=array(0=>array('MYMODULE_MYNEWCONST1','chaine','myvalue','This is a constant to add',1), + // 1=>array('MYMODULE_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1) + // ); + $this->const = array(); + + // Array to add new pages in new tabs + // Example: $this->tabs = array('objecttype:+tabname1:Title1:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mynewtab1.php?id=__ID__', // To add a new tab identified by code tabname1 + // 'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@mymodule:$user->rights->othermodule->read:/mymodule/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key. + // 'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname + // where objecttype can be + // 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member) + // 'contact' to add a tab in contact view + // 'contract' to add a tab in contract view + // 'group' to add a tab in group view + // 'intervention' to add a tab in intervention view + // 'invoice' to add a tab in customer invoice view + // 'invoice_supplier' to add a tab in supplier invoice view + // 'member' to add a tab in fundation member view + // 'opensurveypoll' to add a tab in opensurvey poll view + // 'order' to add a tab in customer order view + // 'order_supplier' to add a tab in supplier order view + // 'payment' to add a tab in payment view + // 'payment_supplier' to add a tab in supplier payment view + // 'product' to add a tab in product view + // 'propal' to add a tab in propal view + // 'project' to add a tab in project view + // 'stock' to add a tab in stock view + // 'thirdparty' to add a tab in third party view + // 'user' to add a tab in user view + $this->tabs = array(); + + if (! isset($conf->mymodule) || ! isset($conf->mymodule->enabled)) + { + $conf->mymodule=new stdClass(); + $conf->mymodule->enabled=0; + } + + // Dictionaries + $this->dictionaries=array(); + /* Example: + $this->dictionaries=array( + 'langs'=>'mylangfile@mymodule', + 'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"), // List of tables we want to see into dictonnary editor + 'tablib'=>array("Table1","Table2","Table3"), // Label of tables + 'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'), // Request to select fields + 'tabsqlsort'=>array("label ASC","label ASC","label ASC"), // Sort order + 'tabfield'=>array("code,label","code,label","code,label"), // List of fields (result of select to show dictionary) + 'tabfieldvalue'=>array("code,label","code,label","code,label"), // List of fields (list of fields to edit a record) + 'tabfieldinsert'=>array("code,label","code,label","code,label"), // List of fields (list of fields for insert) + 'tabrowid'=>array("rowid","rowid","rowid"), // Name of columns with primary key (try to always name it 'rowid') + 'tabcond'=>array($conf->mymodule->enabled,$conf->mymodule->enabled,$conf->mymodule->enabled) // Condition to show each dictionary + ); + */ + + // Boxes + // Add here list of php file(s) stored in core/boxes that contains class to show a box. + $this->boxes = array(); // List of boxes + // Example: + //$this->boxes=array( + // 0=>array('file'=>'myboxa.php@mymodule','note'=>'','enabledbydefaulton'=>'Home'), + // 1=>array('file'=>'myboxb.php@mymodule','note'=>''), + // 2=>array('file'=>'myboxc.php@mymodule','note'=>'') + //); + + // Cronjobs + $this->cronjobs = array(); // List of cron jobs entries to add + // Example: $this->cronjobs=array(0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'test'=>true), + // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'test'=>true) + // ); + + // Permissions + $this->rights = array(); // Permission array used by this module + $r=0; + + // Add here list of permission defined by an id, a label, a boolean and two constant strings. + // Example: + // $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + // $this->rights[$r][1] = 'Permision label'; // Permission label + // $this->rights[$r][3] = 1; // Permission by default for new user (0/1) + // $this->rights[$r][4] = 'level1'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + // $this->rights[$r][5] = 'level2'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + // $r++; + + // Main menu entries + $this->menu = array(); // List of menus to add + $r=0; + + // Add here entries to declare new menus + // + // Example to declare a new Top Menu entry and its Left menu entry: + // $this->menu[$r]=array( 'fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + // 'type'=>'top', // This is a Top menu entry + // 'titre'=>'MyModule top menu', + // 'mainmenu'=>'mymodule', + // 'leftmenu'=>'mymodule', + // 'url'=>'/mymodule/pagetop.php', + // 'langs'=>'mylangfile@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + // 'position'=>100, + // 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + // 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + // 'target'=>'', + // 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + // $r++; + // + // Example to declare a Left Menu entry into an existing Top menu entry: + // $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=xxx', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + // 'type'=>'left', // This is a Left menu entry + // 'titre'=>'MyModule left menu', + // 'mainmenu'=>'xxx', + // 'leftmenu'=>'mymodule', + // 'url'=>'/mymodule/pagelevel2.php', + // 'langs'=>'mylangfile@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + // 'position'=>100, + // 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + // 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + // 'target'=>'', + // 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + // $r++; + + + // Exports + $r=1; + + // Example: + // $this->export_code[$r]=$this->rights_class.'_'.$r; + // $this->export_label[$r]='MyModule'; // Translation key (used only if key ExportDataset_xxx_z not found) + // $this->export_enabled[$r]='1'; // Condition to show export in list (ie: '$user->id==3'). Set to 1 to always show when module is enabled. + // $this->export_icon[$r]='generic:MyModule'; // Put here code of icon then string for translation key of module name + // $this->export_permission[$r]=array(array("mymodule","level1","level2")); + // $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','s.fk_pays'=>'Country','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note'=>"InvoiceNote",'fd.rowid'=>'LineId','fd.description'=>"LineDescription",'fd.price'=>"LineUnitPrice",'fd.tva_tx'=>"LineVATRate",'fd.qty'=>"LineQty",'fd.total_ht'=>"LineTotalHT",'fd.total_tva'=>"LineTotalTVA",'fd.total_ttc'=>"LineTotalTTC",'fd.date_start'=>"DateStart",'fd.date_end'=>"DateEnd",'fd.fk_product'=>'ProductId','p.ref'=>'ProductRef'); + // $this->export_TypeFields_array[$r]=array('t.date'=>'Date', 't.qte'=>'Numeric', 't.poids'=>'Numeric', 't.fad'=>'Numeric', 't.paq'=>'Numeric', 't.stockage'=>'Numeric', 't.fadparliv'=>'Numeric', 't.livau100'=>'Numeric', 't.forfait'=>'Numeric', 's.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Numeric",'f.total_ttc'=>"Numeric",'f.tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'fd.description'=>"Text",'fd.subprice'=>"Numeric",'fd.tva_tx'=>"Numeric",'fd.qty'=>"Numeric",'fd.total_ht'=>"Numeric",'fd.total_tva'=>"Numeric",'fd.total_ttc'=>"Numeric",'fd.date_start'=>"Date",'fd.date_end'=>"Date",'fd.special_code'=>'Numeric','fd.product_type'=>"Numeric",'fd.fk_product'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text','p.accountancy_code_sell'=>'Text'); + // $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note'=>"invoice",'fd.rowid'=>'invoice_line','fd.description'=>"invoice_line",'fd.price'=>"invoice_line",'fd.total_ht'=>"invoice_line",'fd.total_tva'=>"invoice_line",'fd.total_ttc'=>"invoice_line",'fd.tva_tx'=>"invoice_line",'fd.qty'=>"invoice_line",'fd.date_start'=>"invoice_line",'fd.date_end'=>"invoice_line",'fd.fk_product'=>'product','p.ref'=>'product'); + // $this->export_dependencies_array[$r]=array('invoice_line'=>'fd.rowid','product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + // $this->export_sql_start[$r]='SELECT DISTINCT '; + // $this->export_sql_end[$r] =' FROM ('.MAIN_DB_PREFIX.'facture as f, '.MAIN_DB_PREFIX.'facturedet as fd, '.MAIN_DB_PREFIX.'societe as s)'; + // $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)'; + // $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture'; + // $this->export_sql_order[$r] .=' ORDER BY s.nom'; + // $r++; + } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + public function init($options='') + { + $sql = array(); + + //$this->_load_tables('/mymodule/sql/'); + + return $this->_init($sql, $options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + public function remove($options = '') + { + $sql = array(); + + return $this->_remove($sql, $options); + } + +} + diff --git a/htdocs/modulebuilder/skeletons/skeleton_api_class.class.php b/htdocs/modulebuilder/skeletons/skeleton_api_class.class.php new file mode 100644 index 00000000000..a40b00af72c --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_api_class.class.php @@ -0,0 +1,289 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + use Luracast\Restler\RestException; + + +/** + * API class for skeleton object + * + * @smart-auto-routing false + * @access protected + * @class DolibarrApiAccess {@requires user,external} + * + * + */ +class SkeletonApi extends DolibarrApi +{ + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'name' + ); + + /** + * @var Skeleton $skeleton {@type Skeleton} + */ + public $skeleton; + + /** + * Constructor + * + * @url GET skeleton/ + * + */ + function __construct() + { + global $db, $conf; + $this->db = $db; + $this->skeleton = new Skeleton($this->db); + } + + /** + * Get properties of a skeleton object + * + * Return an array with skeleton informations + * + * @param int $id ID of skeleton + * @return array|mixed data without useless information + * + * @url GET skeleton/{id} + * @throws RestException + */ + function get($id) + { + if(! DolibarrApiAccess::$user->rights->skeleton->read) { + throw new RestException(401); + } + + $result = $this->skeleton->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Skeleton not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('skeleton',$this->skeleton->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->skeleton); + } + + /** + * List skeletons + * + * Get a list of skeletons + * + * @param int $mode Use this param to filter list + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101') or (t.import_key:=:'20160101')" + * @return array Array of skeleton objects + * + * @url GET /skeletons/ + */ + function index($mode, $sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') { + global $db, $conf; + + $obj_ret = array(); + + $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; + + // If the internal user must only see his customers, force searching by him + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT s.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql.= " FROM ".MAIN_DB_PREFIX."skeleton as s"; + + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + $sql.= ", ".MAIN_DB_PREFIX."c_stcomm as st"; + $sql.= " WHERE s.fk_stcomm = st.id"; + + // Example of use $mode + //if ($mode == 1) $sql.= " AND s.client IN (1, 3)"; + //if ($mode == 2) $sql.= " AND s.client IN (2, 3)"; + + $sql.= ' AND s.entity IN ('.getEntity('skeleton', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc"; + if ($socid) $sql.= " AND s.fk_soc = ".$socid; + if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + while ($i < $num) + { + $obj = $db->fetch_object($result); + $skeleton_static = new Skeleton($db); + if($skeleton_static->fetch($obj->rowid)) { + $obj_ret[] = parent::_cleanObjectDatas($skeleton_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve skeleton list'); + } + if( ! count($obj_ret)) { + throw new RestException(404, 'No skeleton found'); + } + return $obj_ret; + } + + /** + * Create skeleton object + * + * @param array $request_data Request datas + * @return int ID of skeleton + * + * @url POST skeleton/ + */ + function post($request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->skeleton->create) { + throw new RestException(401); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach($request_data as $field => $value) { + $this->skeleton->$field = $value; + } + if( ! $this->skeleton->create(DolibarrApiAccess::$user)) { + throw new RestException(500); + } + return $this->skeleton->id; + } + + /** + * Update skeleton + * + * @param int $id Id of skeleton to update + * @param array $request_data Datas + * @return int + * + * @url PUT skeleton/{id} + */ + function put($id, $request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->skeleton->create) { + throw new RestException(401); + } + + $result = $this->skeleton->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Skeleton not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('skeleton',$this->skeleton->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + foreach($request_data as $field => $value) { + $this->skeleton->$field = $value; + } + + if($this->skeleton->update($id, DolibarrApiAccess::$user)) + return $this->get ($id); + + return false; + } + + /** + * Delete skeleton + * + * @param int $id Skeleton ID + * @return array + * + * @url DELETE skeleton/{id} + */ + function delete($id) + { + if(! DolibarrApiAccess::$user->rights->skeleton->supprimer) { + throw new RestException(401); + } + $result = $this->skeleton->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Skeleton not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('skeleton',$this->skeleton->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if( !$this->skeleton->delete($id)) + { + throw new RestException(500); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Skeleton deleted' + ) + ); + + } + + /** + * Validate fields before create or update object + * + * @param array $data Data to validate + * @return array + * + * @throws RestException + */ + function _validate($data) + { + $skeleton = array(); + foreach (SkeletonApi::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $skeleton[$field] = $data[$field]; + } + return $skeleton; + } +} diff --git a/htdocs/modulebuilder/skeletons/skeleton_card.php b/htdocs/modulebuilder/skeletons/skeleton_card.php new file mode 100644 index 00000000000..f0a9dd23c26 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_card.php @@ -0,0 +1,351 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/skeleton_card.php + * \ingroup mymodule othermodule1 othermodule2 + * \brief This file is an example of a php page + * Put here some comments + */ + +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) + +// Change this following line to use the correct relative path (../, ../../, etc) +$res=0; +if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory +if (! $res && file_exists("../../main.inc.php")) $res=@include '../../main.inc.php'; // to work if your module directory is into a subdir of root htdocs directory +if (! $res && file_exists("../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res) die("Include of main fails"); +// Change this following line to use the correct relative path from htdocs +include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +dol_include_once('/mymodule/class/skeleton_class.class.php'); + +// Load traductions files requiredby by page +$langs->load("mymodule"); +$langs->load("other"); + +// Get parameters +$id = GETPOST('id','int'); +$action = GETPOST('action','alpha'); +$cancel = GETPOST('cancel'); +$backtopage = GETPOST('backtopage'); +$myparam = GETPOST('myparam','alpha'); + +$search_field1=GETPOST("search_field1"); +$search_field2=GETPOST("search_field2"); + +if (empty($action) && empty($id) && empty($ref)) $action='view'; + +// Protection if external user +if ($user->societe_id > 0) +{ + //accessforbidden(); +} +//$result = restrictedArea($user, 'mymodule', $id); + + +$object = new Skeleton_Class($db); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals + +// Initialize technical object to manage hooks of modules. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('skeleton')); + + + +/******************************************************************* +* ACTIONS +* +* Put here all code to do according to value of "action" parameter +********************************************************************/ + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if ($cancel) + { + if ($action != 'addlink') + { + $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1); + header("Location: ".$urltogo); + exit; + } + if ($id > 0 || ! empty($ref)) $ret = $object->fetch($id,$ref); + $action=''; + } + + // Action to add record + if ($action == 'add') + { + if (GETPOST('cancel')) + { + $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1); + header("Location: ".$urltogo); + exit; + } + + $error=0; + + /* object_prop_getpost_prop */ + $object->prop1=GETPOST("field1"); + $object->prop2=GETPOST("field2"); + + if (empty($object->ref)) + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + } + + if (! $error) + { + $result=$object->create($user); + if ($result > 0) + { + // Creation OK + $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1); + header("Location: ".$urltogo); + exit; + } + { + // Creation KO + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + $action='create'; + } + } + else + { + $action='create'; + } + } + + // Action to update record + if ($action == 'update') + { + $error=0; + + $object->prop1=GETPOST("field1"); + $object->prop2=GETPOST("field2"); + + if (empty($object->ref)) + { + $error++; + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + } + + if (! $error) + { + $result=$object->update($user); + if ($result > 0) + { + $action='view'; + } + else + { + // Creation KO + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + $action='edit'; + } + } + else + { + $action='edit'; + } + } + + // Action to delete + if ($action == 'confirm_delete') + { + $result=$object->delete($user); + if ($result > 0) + { + // Delete OK + setEventMessages("RecordDeleted", null, 'mesgs'); + header("Location: ".dol_buildpath('/mymodule/list.php',1)); + exit; + } + else + { + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + } + } +} + + + + +/*************************************************** +* VIEW +* +* Put here all code to build page +****************************************************/ + +llxHeader('','MyPageName',''); + +$form=new Form($db); + + +// Put here content of your page + +// Example : Adding jquery code +print ''; + + +// Part to create +if ($action == 'create') +{ + print load_fiche_titre($langs->trans("NewMyModule")); + + print ''; + print ''; + print ''; + + dol_fiche_head(); + + print '
    '; @@ -624,11 +588,47 @@ else print '
    '; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 9b90e92e30d..49c17a749f0 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -82,7 +82,7 @@ $dol_no_mouse_hover=$conf->dol_no_mouse_hover; $colorbackhmenu1='110,120,160'; // topmenu $colorbackvmenu1='255,255,255'; // vmenu $colortopbordertitle1='120,120,120'; // top border of title -$colorbacktitle1='230,230,230'; // title of tables,list +$colorbacktitle1='240,240,240'; // title of tables,list $colorbacktabcard1='255,255,255'; // card $colorbacktabactive='234,234,234'; $colorbacklineimpair1='255,255,255'; // line impair @@ -98,7 +98,6 @@ $colortextlink='0,0,120'; $fontsize='13'; $fontsizesmaller='12'; $usegradienttop=(isset($conf->global->THEME_ELDY_TOPMENU_BACK1)?0:1); -$usegradienttitle=(isset($conf->global->THEME_ELDY_BACKTITLE1)?0:1); $useboldtitle=(isset($conf->global->THEME_ELDY_USEBOLDTITLE)?$conf->global->THEME_ELDY_USEBOLDTITLE:1); $borderwith=2; @@ -2399,8 +2398,11 @@ table.paddingtopbottomonly tr td { padding-top: 1px; padding-bottom: 2px; } +.liste_titre_filter { + background: rgb() !important; +} tr.liste_titre_filter td.liste_titre { - border-bottom: 1px solid #eee; + border-bottom: 1px solid #ddd; } .liste_titre_add td, .liste_titre_add th, .liste_titre_add .tagtd { @@ -2715,11 +2717,7 @@ tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, tabl } div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr { - background: linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: rgb(); font-weight: ; border-bottom: 1px solid #ddd; @@ -2987,16 +2985,7 @@ tr.box_titre { color: #000 !important;*/ /* TO MATCH ELDY */ - - background-image: -o-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: -ms-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - - background: rgb(); - - + background: rgb() color: rgb(); font-family: , sans-serif; font-weight: ; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 2ae5decbf96..1908fcfef4a 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -82,7 +82,7 @@ $dol_no_mouse_hover=$conf->dol_no_mouse_hover; $colorbackhmenu1='90,50,120'; // topmenu $colorbackvmenu1='255,255,255'; // vmenu $colortopbordertitle1=''; // top border of tables-lists title. not defined = default to colorbackhmenu1 -$colorbacktitle1='230,230,230'; // title of tables-lists +$colorbacktitle1='240,240,240'; // title of tables-lists $colorbacktabcard1='255,255,255'; // card $colorbacktabactive='234,234,234'; $colorbacklineimpair1='255,255,255'; // line impair @@ -2304,8 +2304,11 @@ table.paddingtopbottomonly tr td { padding-bottom: 2px; } +.liste_titre_filter { + background: rgb() !important; +} tr.liste_titre_filter td.liste_titre { - border-bottom: 1px solid #eee; + border-bottom: 1px solid #FDFFFF; } .liste_titre_add td, .liste_titre_add th, .liste_titre_add .tagtd { From e3d3d32b4a55cfbab14bb45ba2e7563164067b0c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 11:11:37 +0200 Subject: [PATCH 255/410] Translation --- htdocs/langs/en_US/products.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index b38b714ddfb..046521e398e 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -303,7 +303,7 @@ ErrorDeletingGeneratedProducts=There was an error while trying to delete existin NbOfDifferentValues=Nb of different values NbProducts=Nb. of products ParentProduct=Parent product -HideChildProducts=Hide child products +HideChildProducts=Hide variant products ConfirmCloneProductCombinations=Would you like to copy all the product variant to the product with the given reference? CloneDestinationReference=Destination product reference ErrorCopyProductCombinations=There was an error while copying the product variants From 527fa27fb786c3df0325fd63276b823c5d970e85 Mon Sep 17 00:00:00 2001 From: fappels Date: Wed, 29 Mar 2017 11:18:03 +0200 Subject: [PATCH 256/410] Add jquery-migrate to handle jquery 3.0 removes --- htdocs/includes/jquery/js/jquery-migrate.js | 540 ++++++++++++++++++ .../includes/jquery/js/jquery-migrate.min.js | 2 + htdocs/main.inc.php | 2 + htdocs/public/test/test_arrays.php | 2 + 4 files changed, 546 insertions(+) create mode 100644 htdocs/includes/jquery/js/jquery-migrate.js create mode 100644 htdocs/includes/jquery/js/jquery-migrate.min.js diff --git a/htdocs/includes/jquery/js/jquery-migrate.js b/htdocs/includes/jquery/js/jquery-migrate.js new file mode 100644 index 00000000000..350b79958d1 --- /dev/null +++ b/htdocs/includes/jquery/js/jquery-migrate.js @@ -0,0 +1,540 @@ +/*! + * jQuery Migrate - v3.0.0 - 2016-06-09 + * Copyright jQuery Foundation and other contributors + */ +(function( jQuery, window ) { +"use strict"; + + +jQuery.migrateVersion = "3.0.0"; + + +( function() { + + // Support: IE9 only + // IE9 only creates console object when dev tools are first opened + // Also, avoid Function#bind here to simplify PhantomJS usage + var log = window.console && window.console.log && + function() { window.console.log.apply( window.console, arguments ); }, + rbadVersions = /^[12]\./; + + if ( !log ) { + return; + } + + // Need jQuery 3.0.0+ and no older Migrate loaded + if ( !jQuery || rbadVersions.test( jQuery.fn.jquery ) ) { + log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" ); + } + if ( jQuery.migrateWarnings ) { + log( "JQMIGRATE: Migrate plugin loaded multiple times" ); + } + + // Show a message on the console so devs know we're active + log( "JQMIGRATE: Migrate is installed" + + ( jQuery.migrateMute ? "" : " with logging active" ) + + ", version " + jQuery.migrateVersion ); + +} )(); + +var warnedAbout = {}; + +// List of warnings already given; public read only +jQuery.migrateWarnings = []; + +// Set to false to disable traces that appear with warnings +if ( jQuery.migrateTrace === undefined ) { + jQuery.migrateTrace = true; +} + +// Forget any warnings we've already given; public +jQuery.migrateReset = function() { + warnedAbout = {}; + jQuery.migrateWarnings.length = 0; +}; + +function migrateWarn( msg ) { + var console = window.console; + if ( !warnedAbout[ msg ] ) { + warnedAbout[ msg ] = true; + jQuery.migrateWarnings.push( msg ); + if ( console && console.warn && !jQuery.migrateMute ) { + console.warn( "JQMIGRATE: " + msg ); + if ( jQuery.migrateTrace && console.trace ) { + console.trace(); + } + } + } +} + +function migrateWarnProp( obj, prop, value, msg ) { + Object.defineProperty( obj, prop, { + configurable: true, + enumerable: true, + get: function() { + migrateWarn( msg ); + return value; + } + } ); +} + +if ( document.compatMode === "BackCompat" ) { + + // JQuery has never supported or tested Quirks Mode + migrateWarn( "jQuery is not compatible with Quirks Mode" ); +} + + +var oldInit = jQuery.fn.init, + oldIsNumeric = jQuery.isNumeric, + oldFind = jQuery.find, + rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, + rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; + +jQuery.fn.init = function( arg1 ) { + var args = Array.prototype.slice.call( arguments ); + + if ( typeof arg1 === "string" && arg1 === "#" ) { + + // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0 + migrateWarn( "jQuery( '#' ) is not a valid selector" ); + args[ 0 ] = []; + } + + return oldInit.apply( this, args ); +}; +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.find = function( selector ) { + var args = Array.prototype.slice.call( arguments ); + + // Support: PhantomJS 1.x + // String#match fails to match when used with a //g RegExp, only on some strings + if ( typeof selector === "string" && rattrHashTest.test( selector ) ) { + + // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0 + // First see if qS thinks it's a valid selector, if so avoid a false positive + try { + document.querySelector( selector ); + } catch ( err1 ) { + + // Didn't *look* valid to qSA, warn and try quoting what we think is the value + selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) { + return "[" + attr + op + "\"" + value + "\"]"; + } ); + + // If the regexp *may* have created an invalid selector, don't update it + // Note that there may be false alarms if selector uses jQuery extensions + try { + document.querySelector( selector ); + migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] ); + args[ 0 ] = selector; + } catch ( err2 ) { + migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] ); + } + } + } + + return oldFind.apply( this, args ); +}; + +// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) +var findProp; +for ( findProp in oldFind ) { + if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { + jQuery.find[ findProp ] = oldFind[ findProp ]; + } +} + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" ); + return this.length; +}; + +jQuery.parseJSON = function() { + migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" ); + return JSON.parse.apply( null, arguments ); +}; + +jQuery.isNumeric = function( val ) { + + // The jQuery 2.2.3 implementation of isNumeric + function isNumeric2( obj ) { + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + } + + var newValue = oldIsNumeric( val ), + oldValue = isNumeric2( val ); + + if ( newValue !== oldValue ) { + migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" ); + } + + return oldValue; +}; + +migrateWarnProp( jQuery, "unique", jQuery.uniqueSort, + "jQuery.unique is deprecated, use jQuery.uniqueSort" ); + +// Now jQuery.expr.pseudos is the standard incantation +migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, + "jQuery.expr.filters is now jQuery.expr.pseudos" ); +migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, + "jQuery.expr[\":\"] is now jQuery.expr.pseudos" ); + + +var oldAjax = jQuery.ajax; + +jQuery.ajax = function( ) { + var jQXHR = oldAjax.apply( this, arguments ); + + // Be sure we got a jQXHR (e.g., not sync) + if ( jQXHR.promise ) { + migrateWarnProp( jQXHR, "success", jQXHR.done, + "jQXHR.success is deprecated and removed" ); + migrateWarnProp( jQXHR, "error", jQXHR.fail, + "jQXHR.error is deprecated and removed" ); + migrateWarnProp( jQXHR, "complete", jQXHR.always, + "jQXHR.complete is deprecated and removed" ); + } + + return jQXHR; +}; + + +var oldRemoveAttr = jQuery.fn.removeAttr, + oldToggleClass = jQuery.fn.toggleClass, + rmatchNonSpace = /\S+/g; + +jQuery.fn.removeAttr = function( name ) { + var self = this; + + jQuery.each( name.match( rmatchNonSpace ), function( i, attr ) { + if ( jQuery.expr.match.bool.test( attr ) ) { + migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr ); + self.prop( attr, false ); + } + } ); + + return oldRemoveAttr.apply( this, arguments ); +}; + +jQuery.fn.toggleClass = function( state ) { + + // Only deprecating no-args or single boolean arg + if ( state !== undefined && typeof state !== "boolean" ) { + return oldToggleClass.apply( this, arguments ); + } + + migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" ); + + // Toggle entire class name of each element + return this.each( function() { + var className = this.getAttribute && this.getAttribute( "class" ) || ""; + + if ( className ) { + jQuery.data( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || state === false ? + "" : + jQuery.data( this, "__className__" ) || "" + ); + } + } ); +}; + + +var internalSwapCall = false; + +// If this version of jQuery has .swap(), don't false-alarm on internal uses +if ( jQuery.swap ) { + jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) { + var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get; + + if ( oldHook ) { + jQuery.cssHooks[ name ].get = function() { + var ret; + + internalSwapCall = true; + ret = oldHook.apply( this, arguments ); + internalSwapCall = false; + return ret; + }; + } + } ); +} + +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + if ( !internalSwapCall ) { + migrateWarn( "jQuery.swap() is undocumented and deprecated" ); + } + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + +var oldData = jQuery.data; + +jQuery.data = function( elem, name, value ) { + var curData; + + // If the name is transformed, look for the un-transformed name in the data object + if ( name && name !== jQuery.camelCase( name ) ) { + curData = jQuery.hasData( elem ) && oldData.call( this, elem ); + if ( curData && name in curData ) { + migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name ); + if ( arguments.length > 2 ) { + curData[ name ] = value; + } + return curData[ name ]; + } + } + + return oldData.apply( this, arguments ); +}; + +var oldTweenRun = jQuery.Tween.prototype.run; + +jQuery.Tween.prototype.run = function( percent ) { + if ( jQuery.easing[ this.easing ].length > 1 ) { + migrateWarn( + "easing function " + + "\"jQuery.easing." + this.easing.toString() + + "\" should use only first argument" + ); + + jQuery.easing[ this.easing ] = jQuery.easing[ this.easing ].bind( + jQuery.easing, + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } + + oldTweenRun.apply( this, arguments ); +}; + +var oldLoad = jQuery.fn.load, + originalFix = jQuery.event.fix; + +jQuery.event.props = []; +jQuery.event.fixHooks = {}; + +jQuery.event.fix = function( originalEvent ) { + var event, + type = originalEvent.type, + fixHook = this.fixHooks[ type ], + props = jQuery.event.props; + + if ( props.length ) { + migrateWarn( "jQuery.event.props are deprecated and removed: " + props.join() ); + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + + if ( fixHook && !fixHook._migrated_ ) { + fixHook._migrated_ = true; + migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type ); + if ( ( props = fixHook.props ) && props.length ) { + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + } + + event = originalFix.call( this, originalEvent ); + + return fixHook && fixHook.filter ? fixHook.filter( event, originalEvent ) : event; +}; + +jQuery.each( [ "load", "unload", "error" ], function( _, name ) { + + jQuery.fn[ name ] = function() { + var args = Array.prototype.slice.call( arguments, 0 ); + + // If this is an ajax load() the first arg should be the string URL; + // technically this could also be the "Anything" arg of the event .load() + // which just goes to show why this dumb signature has been deprecated! + // jQuery custom builds that exclude the Ajax module justifiably die here. + if ( name === "load" && typeof args[ 0 ] === "string" ) { + return oldLoad.apply( this, args ); + } + + migrateWarn( "jQuery.fn." + name + "() is deprecated" ); + + args.splice( 0, 0, name ); + if ( arguments.length ) { + return this.on.apply( this, args ); + } + + // Use .triggerHandler here because: + // - load and unload events don't need to bubble, only applied to window or image + // - error event should not bubble to window, although it does pre-1.7 + // See http://bugs.jquery.com/ticket/11820 + this.triggerHandler.apply( this, args ); + return this; + }; + +} ); + +// Trigger "ready" event only once, on document ready +jQuery( function() { + jQuery( document ).triggerHandler( "ready" ); +} ); + +jQuery.event.special.ready = { + setup: function() { + if ( this === document ) { + migrateWarn( "'ready' event is deprecated" ); + } + } +}; + +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + migrateWarn( "jQuery.fn.bind() is deprecated" ); + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + migrateWarn( "jQuery.fn.unbind() is deprecated" ); + return this.off( types, null, fn ); + }, + delegate: function( selector, types, data, fn ) { + migrateWarn( "jQuery.fn.delegate() is deprecated" ); + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + migrateWarn( "jQuery.fn.undelegate() is deprecated" ); + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + } +} ); + + +var oldOffset = jQuery.fn.offset; + +jQuery.fn.offset = function() { + var docElem, + elem = this[ 0 ], + origin = { top: 0, left: 0 }; + + if ( !elem || !elem.nodeType ) { + migrateWarn( "jQuery.fn.offset() requires a valid DOM element" ); + return origin; + } + + docElem = ( elem.ownerDocument || document ).documentElement; + if ( !jQuery.contains( docElem, elem ) ) { + migrateWarn( "jQuery.fn.offset() requires an element connected to a document" ); + return origin; + } + + return oldOffset.apply( this, arguments ); +}; + + +var oldParam = jQuery.param; + +jQuery.param = function( data, traditional ) { + var ajaxTraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + + if ( traditional === undefined && ajaxTraditional ) { + + migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" ); + traditional = ajaxTraditional; + } + + return oldParam.call( this, data, traditional ); +}; + +var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack; + +jQuery.fn.andSelf = function() { + migrateWarn( "jQuery.fn.andSelf() replaced by jQuery.fn.addBack()" ); + return oldSelf.apply( this, arguments ); +}; + + +var oldDeferred = jQuery.Deferred, + tuples = [ + + // Action, add listener, callbacks, .then handlers, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ) ] + ]; + +jQuery.Deferred = function( func ) { + var deferred = oldDeferred(), + promise = deferred.promise(); + + deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + migrateWarn( "deferred.pipe() is deprecated" ); + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // Deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + + }; + + if ( func ) { + func.call( deferred, deferred ); + } + + return deferred; +}; + + + +})( jQuery, window ); \ No newline at end of file diff --git a/htdocs/includes/jquery/js/jquery-migrate.min.js b/htdocs/includes/jquery/js/jquery-migrate.min.js new file mode 100644 index 00000000000..a2813c5d2d8 --- /dev/null +++ b/htdocs/includes/jquery/js/jquery-migrate.min.js @@ -0,0 +1,2 @@ +/*! jQuery Migrate v3.0.0 | (c) jQuery Foundation and other contributors | jquery.org/license */ +"undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(a,b){"use strict";function c(c){var d=b.console;e[c]||(e[c]=!0,a.migrateWarnings.push(c),d&&d.warn&&!a.migrateMute&&(d.warn("JQMIGRATE: "+c),a.migrateTrace&&d.trace&&d.trace()))}function d(a,b,d,e){Object.defineProperty(a,b,{configurable:!0,enumerable:!0,get:function(){return c(e),d}})}a.migrateVersion="3.0.0",function(){var c=b.console&&b.console.log&&function(){b.console.log.apply(b.console,arguments)},d=/^[12]\./;c&&(a&&!d.test(a.fn.jquery)||c("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),a.migrateWarnings&&c("JQMIGRATE: Migrate plugin loaded multiple times"),c("JQMIGRATE: Migrate is installed"+(a.migrateMute?"":" with logging active")+", version "+a.migrateVersion))}();var e={};a.migrateWarnings=[],void 0===a.migrateTrace&&(a.migrateTrace=!0),a.migrateReset=function(){e={},a.migrateWarnings.length=0},"BackCompat"===document.compatMode&&c("jQuery is not compatible with Quirks Mode");var f=a.fn.init,g=a.isNumeric,h=a.find,i=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,j=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g;a.fn.init=function(a){var b=Array.prototype.slice.call(arguments);return"string"==typeof a&&"#"===a&&(c("jQuery( '#' ) is not a valid selector"),b[0]=[]),f.apply(this,b)},a.fn.init.prototype=a.fn,a.find=function(a){var b=Array.prototype.slice.call(arguments);if("string"==typeof a&&i.test(a))try{document.querySelector(a)}catch(d){a=a.replace(j,function(a,b,c,d){return"["+b+c+'"'+d+'"]'});try{document.querySelector(a),c("Attribute selector with '#' must be quoted: "+b[0]),b[0]=a}catch(e){c("Attribute selector with '#' was not fixed: "+b[0])}}return h.apply(this,b)};var k;for(k in h)Object.prototype.hasOwnProperty.call(h,k)&&(a.find[k]=h[k]);a.fn.size=function(){return c("jQuery.fn.size() is deprecated; use the .length property"),this.length},a.parseJSON=function(){return c("jQuery.parseJSON is deprecated; use JSON.parse"),JSON.parse.apply(null,arguments)},a.isNumeric=function(b){function d(b){var c=b&&b.toString();return!a.isArray(b)&&c-parseFloat(c)+1>=0}var e=g(b),f=d(b);return e!==f&&c("jQuery.isNumeric() should not be called on constructed objects"),f},d(a,"unique",a.uniqueSort,"jQuery.unique is deprecated, use jQuery.uniqueSort"),d(a.expr,"filters",a.expr.pseudos,"jQuery.expr.filters is now jQuery.expr.pseudos"),d(a.expr,":",a.expr.pseudos,'jQuery.expr[":"] is now jQuery.expr.pseudos');var l=a.ajax;a.ajax=function(){var a=l.apply(this,arguments);return a.promise&&(d(a,"success",a.done,"jQXHR.success is deprecated and removed"),d(a,"error",a.fail,"jQXHR.error is deprecated and removed"),d(a,"complete",a.always,"jQXHR.complete is deprecated and removed")),a};var m=a.fn.removeAttr,n=a.fn.toggleClass,o=/\S+/g;a.fn.removeAttr=function(b){var d=this;return a.each(b.match(o),function(b,e){a.expr.match.bool.test(e)&&(c("jQuery.fn.removeAttr no longer sets boolean properties: "+e),d.prop(e,!1))}),m.apply(this,arguments)},a.fn.toggleClass=function(b){return void 0!==b&&"boolean"!=typeof b?n.apply(this,arguments):(c("jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var c=this.getAttribute&&this.getAttribute("class")||"";c&&a.data(this,"__className__",c),this.setAttribute&&this.setAttribute("class",c||b===!1?"":a.data(this,"__className__")||"")}))};var p=!1;a.swap&&a.each(["height","width","reliableMarginRight"],function(b,c){var d=a.cssHooks[c]&&a.cssHooks[c].get;d&&(a.cssHooks[c].get=function(){var a;return p=!0,a=d.apply(this,arguments),p=!1,a})}),a.swap=function(a,b,d,e){var f,g,h={};p||c("jQuery.swap() is undocumented and deprecated");for(g in b)h[g]=a.style[g],a.style[g]=b[g];f=d.apply(a,e||[]);for(g in b)a.style[g]=h[g];return f};var q=a.data;a.data=function(b,d,e){var f;return d&&d!==a.camelCase(d)&&(f=a.hasData(b)&&q.call(this,b),f&&d in f)?(c("jQuery.data() always sets/gets camelCased names: "+d),arguments.length>2&&(f[d]=e),f[d]):q.apply(this,arguments)};var r=a.Tween.prototype.run;a.Tween.prototype.run=function(b){a.easing[this.easing].length>1&&(c('easing function "jQuery.easing.'+this.easing.toString()+'" should use only first argument'),a.easing[this.easing]=a.easing[this.easing].bind(a.easing,b,this.options.duration*b,0,1,this.options.duration)),r.apply(this,arguments)};var s=a.fn.load,t=a.event.fix;a.event.props=[],a.event.fixHooks={},a.event.fix=function(b){var d,e=b.type,f=this.fixHooks[e],g=a.event.props;if(g.length)for(c("jQuery.event.props are deprecated and removed: "+g.join());g.length;)a.event.addProp(g.pop());if(f&&!f._migrated_&&(f._migrated_=!0,c("jQuery.event.fixHooks are deprecated and removed: "+e),(g=f.props)&&g.length))for(;g.length;)a.event.addProp(g.pop());return d=t.call(this,b),f&&f.filter?f.filter(d,b):d},a.each(["load","unload","error"],function(b,d){a.fn[d]=function(){var a=Array.prototype.slice.call(arguments,0);return"load"===d&&"string"==typeof a[0]?s.apply(this,a):(c("jQuery.fn."+d+"() is deprecated"),a.splice(0,0,d),arguments.length?this.on.apply(this,a):(this.triggerHandler.apply(this,a),this))}}),a(function(){a(document).triggerHandler("ready")}),a.event.special.ready={setup:function(){this===document&&c("'ready' event is deprecated")}},a.fn.extend({bind:function(a,b,d){return c("jQuery.fn.bind() is deprecated"),this.on(a,null,b,d)},unbind:function(a,b){return c("jQuery.fn.unbind() is deprecated"),this.off(a,null,b)},delegate:function(a,b,d,e){return c("jQuery.fn.delegate() is deprecated"),this.on(b,a,d,e)},undelegate:function(a,b,d){return c("jQuery.fn.undelegate() is deprecated"),1===arguments.length?this.off(a,"**"):this.off(b,a||"**",d)}});var u=a.fn.offset;a.fn.offset=function(){var b,d=this[0],e={top:0,left:0};return d&&d.nodeType?(b=(d.ownerDocument||document).documentElement,a.contains(b,d)?u.apply(this,arguments):(c("jQuery.fn.offset() requires an element connected to a document"),e)):(c("jQuery.fn.offset() requires a valid DOM element"),e)};var v=a.param;a.param=function(b,d){var e=a.ajaxSettings&&a.ajaxSettings.traditional;return void 0===d&&e&&(c("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),d=e),v.call(this,b,d)};var w=a.fn.andSelf||a.fn.addBack;a.fn.andSelf=function(){return c("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()"),w.apply(this,arguments)};var x=a.Deferred,y=[["resolve","done",a.Callbacks("once memory"),a.Callbacks("once memory"),"resolved"],["reject","fail",a.Callbacks("once memory"),a.Callbacks("once memory"),"rejected"],["notify","progress",a.Callbacks("memory"),a.Callbacks("memory")]];a.Deferred=function(b){var d=x(),e=d.promise();return d.pipe=e.pipe=function(){var b=arguments;return c("deferred.pipe() is deprecated"),a.Deferred(function(c){a.each(y,function(f,g){var h=a.isFunction(b[f])&&b[f];d[g[1]](function(){var b=h&&h.apply(this,arguments);b&&a.isFunction(b.promise)?b.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[g[0]+"With"](this===e?c.promise():this,h?[b]:arguments)})}),b=null}).promise()},b&&b.call(d,d),d}}(jQuery,window); \ No newline at end of file diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 9c0a98cbcfb..3a6ec46d61f 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1146,6 +1146,8 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; if (constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; + if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; + else print ''."\n"; if (constant('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; diff --git a/htdocs/public/test/test_arrays.php b/htdocs/public/test/test_arrays.php index 3de7196a696..0776c36f74a 100644 --- a/htdocs/public/test/test_arrays.php +++ b/htdocs/public/test/test_arrays.php @@ -38,6 +38,8 @@ if (empty($usedolheader)) " /> + + From 1d6e760fc8a2a1395bfa3c493dcabf39639c84db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 11:44:14 +0200 Subject: [PATCH 257/410] FIX Notification sending was broken. --- .../interface_50_modNotification_Notification.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index d9952d441f4..d55a1a776a0 100644 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -66,7 +66,7 @@ class InterfaceNotification extends DolibarrTriggers require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify = new Notify($this->db); - if (! in_array($notifcode, $notify->arrayofnotifsupported)) return 0; + if (! in_array($action, $notify->arrayofnotifsupported)) return 0; dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); From fbca800246e66df7870f546abcc6da71d938c952 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 10:34:33 +0200 Subject: [PATCH 258/410] FIX Detection of color brightness --- htdocs/core/class/html.formother.class.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 4ac3eb99c50..7e78f7bbe4d 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -604,10 +604,22 @@ class FormOther $textcolor='FFF'; if ($color) { - $hex=$color; - $r = hexdec($hex[0].$hex[1]); - $g = hexdec($hex[2].$hex[3]); - $b = hexdec($hex[4].$hex[5]); + $tmp=explode(',', $color); + if (count($tmp) > 1) // This is a comma RGB ('255','255','255') + { + $r = $tmp[0]; + $g = $tmp[1]; + $b = $tmp[2]; + } + else + { + $hexr=$color[0].$color[1]; + $hexg=$color[2].$color[3]; + $hexb=$color[4].$color[5]; + $r = hexdec($hexr); + $g = hexdec($hexg); + $b = hexdec($hexb); + } $bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0; // HSL algorithm if ($bright > 0.6) $textcolor='000'; } From a76ddc8b3ff6b96f7bc2e2dcfefc7fc588421f4f Mon Sep 17 00:00:00 2001 From: Thomas Raschbacher Date: Wed, 29 Mar 2017 15:33:32 +0200 Subject: [PATCH 259/410] Add phone phone numbers to project contacts Add phone number(s) for project contacts to be used in odt --- .../doc/doc_generic_project_odt.modules.php | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) 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 06b188496a5..32be29b082c 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 @@ -186,6 +186,25 @@ class doc_generic_project_odt extends ModelePDFProjects { global $conf; + // adding phone numbers if external + $phone_pro = ''; + $phone_perso = ''; + $phone_mobile = ''; + + $ct = new Contact($this->db); + if ($contact['source']=='external') { + $ct = new Contact($this->db); + $ct->fetch($contact['id']); + $phone_pro = $ct->phone_pro; + $phone_perso = $ct->phone_perso; + $phone_mobile = $ct->phone_mobile; + } elseif ($contact['source']=='internal') { + $ct = new User($this->db); + $ct->fetch($contact['id']); + $phone_pro = $ct->office_phone; + $phone_mobile = $ct->user_mobile; + } + return array( 'projcontacts_id'=>$contact['id'], 'projcontacts_rowid'=>$contact['rowid'], @@ -194,7 +213,10 @@ class doc_generic_project_odt extends ModelePDFProjects 'projcontacts_firstname'=>$contact['firstname'], 'projcontacts_fullcivname'=>$contact['fullname'], 'projcontacts_socname'=>$contact['socname'], - 'projcontacts_email'=>$contact['email'] + 'projcontacts_email'=>$contact['email'], + 'projcontacts_phone_pro'=>$phone_pro, + 'projcontacts_phone_perso'=>$phone_perso, + 'projcontacts_phone_mobile'=>$phone_mobile ); } From 2dc721c53812968f8b4fd7492998d02c240c2fc3 Mon Sep 17 00:00:00 2001 From: phf Date: Wed, 29 Mar 2017 16:10:59 +0200 Subject: [PATCH 260/410] Fix picture with jpeg extension are not visible --- htdocs/categories/class/categorie.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 122d62b1d76..c58b3261c5f 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1489,14 +1489,14 @@ class Categorie extends CommonObject { while (($file = readdir($handle)) !== false) { - if (dol_is_file($dir.$file) && preg_match('/(\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$dir.$file)) + if (dol_is_file($dir.$file) && preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$dir.$file)) { $nbphoto++; $photo = $file; // On determine nom du fichier vignette $photo_vignette=''; - if (preg_match('/(\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$photo,$regs)) + if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$photo,$regs)) { $photo_vignette=preg_replace('/'.$regs[0].'/i','',$photo).'_small'.$regs[0]; } @@ -1539,7 +1539,7 @@ class Categorie extends CommonObject dol_delete_file($file,1); // Si elle existe, on efface la vignette - if (preg_match('/(\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$filename,$regs)) + if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$filename,$regs)) { $photo_vignette=preg_replace('/'.$regs[0].'/i','',$filename).'_small'.$regs[0]; if (file_exists($dirthumb.$photo_vignette)) From 4df8dcf9800d81225265fd534ea1cef35869fb63 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 21:36:50 +0200 Subject: [PATCH 261/410] Work on module modBlockedLog and modModuleBuilder --- htdocs/admin/menus.php | 2 +- htdocs/admin/menus/index.php | 2 +- htdocs/admin/menus/other.php | 2 +- htdocs/admin/modules.php | 3 +- htdocs/core/modules/modBlockedLog.class.php | 2 +- .../core/modules/modModuleBuilder.class.php | 89 +++ htdocs/cron/card.php | 8 +- htdocs/cron/class/cronjob.class.php | 57 +- htdocs/langs/en_US/modulebuilder.lang | 3 + htdocs/main.inc.php | 36 +- htdocs/modulebuilder/index.php | 91 +++ htdocs/modulebuilder/skeletons/.gitignore | 2 + htdocs/modulebuilder/skeletons/README | 34 + .../skeletons/build_api_class.php | 123 ++++ .../skeletons/build_class_from_table.php | 677 ++++++++++++++++++ .../skeletons/build_webservice_from_class.php | 179 +++++ .../skeletons/modMyModule.class.php | 291 ++++++++ .../skeletons/skeleton_api_class.class.php | 289 ++++++++ .../modulebuilder/skeletons/skeleton_card.php | 351 +++++++++ .../skeletons/skeleton_class.class.php | 593 +++++++++++++++ .../modulebuilder/skeletons/skeleton_list.php | 569 +++++++++++++++ .../skeletons/skeleton_script.php | 166 +++++ .../skeletons/skeleton_webservice_server.php | 272 +++++++ htdocs/theme/eldy/style.css.php | 4 + htdocs/theme/md/style.css.php | 4 + htdocs/user/class/user.class.php | 2 +- 26 files changed, 3828 insertions(+), 23 deletions(-) create mode 100644 htdocs/core/modules/modModuleBuilder.class.php create mode 100644 htdocs/langs/en_US/modulebuilder.lang create mode 100644 htdocs/modulebuilder/index.php create mode 100644 htdocs/modulebuilder/skeletons/.gitignore create mode 100644 htdocs/modulebuilder/skeletons/README create mode 100755 htdocs/modulebuilder/skeletons/build_api_class.php create mode 100755 htdocs/modulebuilder/skeletons/build_class_from_table.php create mode 100755 htdocs/modulebuilder/skeletons/build_webservice_from_class.php create mode 100644 htdocs/modulebuilder/skeletons/modMyModule.class.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_api_class.class.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_card.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_class.class.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_list.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_script.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_webservice_server.php diff --git a/htdocs/admin/menus.php b/htdocs/admin/menus.php index f8b89c515aa..0d6ff4d34a0 100644 --- a/htdocs/admin/menus.php +++ b/htdocs/admin/menus.php @@ -155,7 +155,7 @@ print ''; print ''; print ''; -dol_fiche_head($head, 'handler', $langs->trans("Menus")); +dol_fiche_head($head, 'handler', $langs->trans("Menus"), -1); print $langs->trans("MenusDesc")."
    \n"; print "
    \n"; diff --git a/htdocs/admin/menus/index.php b/htdocs/admin/menus/index.php index acfa9d2dccd..ed5f56954c0 100644 --- a/htdocs/admin/menus/index.php +++ b/htdocs/admin/menus/index.php @@ -234,7 +234,7 @@ $head[$h][1] = $langs->trans("Miscellaneous"); $head[$h][2] = 'misc'; $h++; -dol_fiche_head($head, 'editor', $langs->trans("Menus")); +dol_fiche_head($head, 'editor', $langs->trans("Menus"), -1); print $langs->trans("MenusEditorDesc")."
    \n"; print "
    \n"; diff --git a/htdocs/admin/menus/other.php b/htdocs/admin/menus/other.php index 471edf58e79..0a3cb6b99bc 100644 --- a/htdocs/admin/menus/other.php +++ b/htdocs/admin/menus/other.php @@ -77,7 +77,7 @@ $head[$h][1] = $langs->trans("Miscellaneous"); $head[$h][2] = 'misc'; $h++; -dol_fiche_head($head, 'misc', $langs->trans("Menus")); +dol_fiche_head($head, 'misc', $langs->trans("Menus"), -1); // Other Options diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index bfaeabf67d4..ddaf940492f 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -278,13 +278,12 @@ foreach ($modulesdir as $dir) try { - $res=include_once $dir.$file; + $res=include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error. if (class_exists($modName)) { try { $objMod = new $modName($db); $modNameLoaded[$modName]=$dir; - if (! $objMod->numero > 0 && $modName != 'modUser') { dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR); diff --git a/htdocs/core/modules/modBlockedLog.class.php b/htdocs/core/modules/modBlockedLog.class.php index 30e4734e843..c3e2cb6345a 100644 --- a/htdocs/core/modules/modBlockedLog.class.php +++ b/htdocs/core/modules/modBlockedLog.class.php @@ -25,7 +25,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Class to describe a Cron module + * Class to describe a BlockedLog module */ class modBlockedLog extends DolibarrModules { diff --git a/htdocs/core/modules/modModuleBuilder.class.php b/htdocs/core/modules/modModuleBuilder.class.php new file mode 100644 index 00000000000..b68148377c3 --- /dev/null +++ b/htdocs/core/modules/modModuleBuilder.class.php @@ -0,0 +1,89 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \defgroup modulebuilder Module ModuleBuilder + * \brief Add a log into a block chain for some actions. + * \file htdocs/core/modules/modBlockedLog.class.php + * \ingroup blockedlog + * \brief Description and activation file for module ModuleBuilder + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + +/** + * Class to describe a ModuleBuilder module + */ +class modModuleBuilder extends DolibarrModules +{ + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $langs,$conf; + + $this->db = $db; + $this->numero = 3300; + + // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' + // It is used to group modules in module setup page + $this->family = "technic"; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + $this->description = "A tool to help developers to build their own module."; + $this->version = 'development'; // 'development', 'experimental' or 'dolibarr' or version + // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) + $this->special = 1; + // Name of image file used for this module. + $this->picto='technic'; + + // Data directories to create when module is enabled + $this->dirs = array(); + + // Config pages + //------------- + $this->config_page_url = array(); + + // Dependancies + //------------- + $this->hidden = false; // A condition to disable module + $this->depends = array(); // List of modules id that must be enabled if this module is enabled + $this->requiredby = array(); // List of modules id to disable if this one is disabled + $this->conflictwith = array(); // List of modules id this module is in conflict with + $this->langfiles = array(); + + // Constants + //----------- + + + // New pages on tabs + // ----------------- + $this->tabs = array(); + + // Boxes + //------ + $this->boxes = array(); + + // Main menu entries + //------------------ + $this->menu = array(); + } +} diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index 5e2bc435e56..fc89f6eb3cf 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -321,8 +321,8 @@ if (($action=="create") || ($action=="edit")) print ''."\n"; } - - dol_fiche_head(''); + if ($action=="edit") dol_fiche_head($head, 'card', $langs->trans("CronTask"), 0, 'cron'); + else dol_fiche_head(''); print ''; @@ -558,6 +558,8 @@ else dol_fiche_head($head, 'card', $langs->trans("CronTask"), -1, 'cron'); $linkback = '' . $langs->trans("BackToList") . ''; + + // TODO Use dol_banner // box add_jobs_box print '
    '; @@ -616,7 +618,7 @@ else print '
    "; print '
    '; print $langs->trans('Active').""; - print yn($object->status); + print $object->getLibStatut(4); print "
    '; diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 2f9ad12a57f..789e3bafcec 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1199,8 +1199,63 @@ class Cronjob extends CommonObject } return 1; - } + + /** + * Return label of status of user (active, inactive) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Renvoi le libelle d'un statut donne + * + * @param int $status Id statut + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function LibStatut($status,$mode=0) + { + global $langs; + $langs->load('users'); + + if ($mode == 0) + { + $prefix=''; + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 1) + { + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 2) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled'); + } + if ($mode == 3) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"'); + } + if ($mode == 4) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled'); + } + if ($mode == 5) + { + if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"'); + if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"'); + } + } } diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang new file mode 100644 index 00000000000..6605a7b6a63 --- /dev/null +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -0,0 +1,3 @@ +# Dolibarr language file - Source file is en_US - loan +ModuleBuilder=Module Builder +ModuleBuilderDesc=This tools give you utilites to build your own module. Your modules will be generated into the first alternative directory: %s. diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 8d1138e5758..fe1ed01a68f 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1377,8 +1377,6 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $menumanager->showmenu('top', array('searchform'=>$searchform, 'bookmarks'=>$bookmarks)); // This contains a \n print "\n"; - //$form=new Form($db); - // Define link to login card $appli=constant('DOL_APPLICATION_TITLE'); if (! empty($conf->global->MAIN_APPLICATION_TITLE)) @@ -1403,7 +1401,8 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $logouthtmltext.=$langs->trans("Logout").'
    '; $logouttext .=''; - $logouttext .= img_picto($langs->trans('Logout').":".$langs->trans('Logout'), 'logout_top.png', 'class="login"', 0, 0, 1); + //$logouttext .= img_picto($langs->trans('Logout').":".$langs->trans('Logout'), 'logout_top.png', 'class="login"', 0, 0, 1); + $logouttext .=''; $logouttext .=''; } else @@ -1427,6 +1426,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $toprightmenu.=''; $toprightmenu.='
    .fieldx.'.\$obj->".$prop['field'].".''.\$obj->field1.''.\$obj->field2.'
    '.\$langs->trans(\"Field".$prop['field']."\").'
    ".\$langs->trans("Field%s")."%s."\">
    '.\$langs->trans(\"Field%s\").''.\$object->%s.'
    '."\n"; + // print ''; + // LIST_OF_TD_LABEL_FIELDS_CREATE + print '
    '.$langs->trans("Label").'
    '."\n"; + + dol_fiche_end(); + + print '
     
    '; + + print ''; +} + + + +// Part to edit record +if (($id || $ref) && $action == 'edit') +{ + print load_fiche_titre($langs->trans("MyModule")); + + print '
    '; + print ''; + print ''; + print ''; + + dol_fiche_head(); + + print ''."\n"; + // print ''; + // LIST_OF_TD_LABEL_FIELDS_EDIT + print '
    '.$langs->trans("Label").'
    '; + + dol_fiche_end(); + + print '
    '; + print '   '; + print '
    '; + + print '
    '; +} + + + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) +{ + $res = $object->fetch_optionals($object->id, $extralabels); + + $head = commande_prepare_head($object); + dol_fiche_head($head, 'order', $langs->trans("CustomerOrder"), 0, 'order'); + + print load_fiche_titre($langs->trans("MyModule")); + + dol_fiche_head(); + + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteMyOjbect'), $langs->trans('ConfirmDeleteMyObject'), 'confirm_delete', '', 0, 1); + print $formconfirm; + } + + print ''."\n"; + // print ''; + // LIST_OF_TD_LABEL_FIELDS_VIEW + print '
    '.$langs->trans("Label").''.$object->label.'
    '; + + dol_fiche_end(); + + + // Buttons + print '
    '."\n"; + $parameters=array(); + $reshook=$hookmanager->executeHooks('addMoreActionsButtons',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + if (empty($reshook)) + { + if ($user->rights->mymodule->write) + { + print ''."\n"; + } + + if ($user->rights->mymodule->delete) + { + print ''."\n"; + } + } + print '
    '."\n"; + + + // Example 2 : Adding links to objects + // Show links to link elements + //$linktoelem = $form->showLinkToObjectBlock($object, null, array('skeleton')); + //$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + +} + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/modulebuilder/skeletons/skeleton_class.class.php b/htdocs/modulebuilder/skeletons/skeleton_class.class.php new file mode 100644 index 00000000000..01b48c35f75 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_class.class.php @@ -0,0 +1,593 @@ + + * Copyright (C) 2014-2016 Juanjo Menent + * Copyright (C) 2015 Florian Henry + * Copyright (C) 2015 Raphaël Doursenaud + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/skeleton_class.class.php + * \ingroup mymodule othermodule1 othermodule2 + * \brief This file is an example for a CRUD class file (Create/Read/Update/Delete) + * Put some comments here + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class Skeleton_Class + * + * Put here description of your class + * + * @see CommonObject + */ +class Skeleton_Class extends CommonObject +{ + /** + * @var string Id to identify managed objects + */ + public $element = 'skeleton'; + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'skeleton'; + + /** + * @var Skeleton_ClassLine[] Lines + */ + public $lines = array(); + + /** + * @var mixed Sample property 1 + */ + public $prop1; + /** + * @var mixed Sample property 2 + */ + public $prop2; + //... + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $error = 0; + + // Clean parameters + if (isset($this->prop1)) { + $this->prop1 = trim($this->prop1); + } + if (isset($this->prop2)) { + $this->prop2 = trim($this->prop2); + } + //... + + // Check parameters + // Put here code to add control on parameters values + + // Insert request + $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; + $sql .= ' field1,'; + $sql .= ' field2'; + //... + $sql .= ') VALUES ('; + $sql .= ' \'' . $this->prop1 . '\','; + $sql .= ' \'' . $this->prop2 . '\''; + //... + $sql .= ')'; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + if (!$error) { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); + + if (!$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action to call a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_CREATE',$user); + //if ($result < 0) $error++; + //// End call triggers + } + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return $this->id; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + $sql .= ' t.field1,'; + $sql .= ' t.field2'; + //... + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t'; + $sql.= ' WHERE 1 = 1'; + if (! empty($conf->multicompany->enabled)) { + $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; + } + if (null !== $ref) { + $sql .= ' AND t.ref = ' . '\'' . $ref . '\''; + } else { + $sql .= ' AND t.rowid = ' . $id; + } + + $resql = $this->db->query($sql); + if ($resql) { + $numrows = $this->db->num_rows($resql); + if ($numrows) { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + $this->prop1 = $obj->field1; + $this->prop2 = $obj->field2; + //... + } + + // Retrieve all extrafields for invoice + // fetch optionals attributes and labels + /* + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); + */ + + // $this->fetch_lines(); + + $this->db->free($resql); + + if ($numrows) { + return 1; + } else { + return 0; + } + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Load object in memory from the database + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit offset limit + * @param int $offset offset limit + * @param array $filter filter array + * @param string $filtermode filter mode (AND or OR) + * + * @return int <0 if KO, >0 if OK + */ + public function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + $sql .= ' t.field1,'; + $sql .= ' t.field2'; + //... + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t'; + + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\''; + } + } + $sql.= ' WHERE 1 = 1'; + if (! empty($conf->multicompany->enabled)) { + $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ' . implode(' '.$filtermode.' ', $sqlwhere); + } + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield,$sortorder); + } + if (!empty($limit)) { + $sql .= ' ' . $this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + + while ($obj = $this->db->fetch_object($resql)) { + $line = new self($this->db); + + $line->id = $obj->rowid; + $line->prop1 = $obj->field1; + $line->prop2 = $obj->field2; + //... + } + $this->db->free($resql); + + return $num; + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + // Clean parameters + if (isset($this->prop1)) { + $this->prop1 = trim($this->prop1); + } + if (isset($this->prop2)) { + $this->prop2 = trim($this->prop2); + } + //... + + // Check parameters + // Put here code to add a control on parameters values + + // Update request + $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; + $sql .= " field1=".(isset($this->field1)?"'".$this->db->escape($this->field1)."'":"null").","; + $sql .= " field2=".(isset($this->field2)?"'".$this->db->escape($this->field2)."'":"null").""; + //... + $sql .= ' WHERE rowid=' . $this->id; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + if (!$error && !$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_MODIFY',$user); + //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + //// End call triggers + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $error = 0; + + $this->db->begin(); + + if (!$error) { + if (!$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_DELETE',$user); + //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + //// End call triggers + } + } + + // If you need to delete child tables to, you can insert them here + + if (!$error) { + $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element; + $sql .= ' WHERE rowid=' . $this->id; + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Load an object from its id and create a new one in database + * + * @param int $fromid Id of object to clone + * + * @return int New id of clone + */ + public function createFromClone($fromid) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + global $user; + $error = 0; + $object = new Skeleton_Class($this->db); + + $this->db->begin(); + + // Load source object + $object->fetch($fromid); + // Reset object + $object->id = 0; + + // Clear fields + // ... + + // Create clone + $result = $object->create($user); + + // Other options + if ($result < 0) { + $error ++; + $this->errors = $object->errors; + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + // End + if (!$error) { + $this->db->commit(); + + return $object->id; + } else { + $this->db->rollback(); + + return - 1; + } + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to + * @param int $notooltip 1=Disable tooltip + * @param int $maxlen Max length of visible user name + * @param string $morecss Add more css on link + * @return string String with URL + */ + function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') + { + global $db, $conf, $langs; + global $dolibarr_main_authentication, $dolibarr_main_demo; + global $menumanager; + + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + + $result = ''; + $companylink = ''; + + $label = '' . $langs->trans("MyModule") . ''; + $label.= '
    '; + $label.= '' . $langs->trans('Ref') . ': ' . $this->ref; + + $url = DOL_URL_ROOT.'/mymodule/'.$this->table_name.'_card.php?id='.$this->id; + + $linkclose=''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowProject"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } + else $linkclose = ($morecss?' class="'.$morecss.'"':''); + + $linkstart = ''; + $linkend=''; + + if ($withpicto) + { + $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); + if ($withpicto != 2) $result.=' '; + } + $result.= $linkstart . $this->ref . $linkend; + return $result; + } + + /** + * Retourne le libelle du status d'un user (actif, inactif) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 5=Long label + Picto + * @return string Label of status + */ + static function LibStatut($status,$mode=0) + { + global $langs; + + if ($mode == 0) + { + $prefix=''; + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 1) + { + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 2) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); + } + if ($mode == 3) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5'); + } + if ($mode == 4) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); + } + if ($mode == 5) + { + if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5'); + } + if ($mode == 6) + { + if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5'); + } + } + + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->id = 0; + $this->prop1 = 'prop1'; + $this->prop2 = 'prop2'; + } + +} + +/** + * Class Skeleton_ClassLine + */ +class Skeleton_ClassLine +{ + /** + * @var int ID + */ + public $id; + /** + * @var mixed Sample line property 1 + */ + public $prop1; + /** + * @var mixed Sample line property 2 + */ + public $prop2; +} diff --git a/htdocs/modulebuilder/skeletons/skeleton_list.php b/htdocs/modulebuilder/skeletons/skeleton_list.php new file mode 100644 index 00000000000..77485c6d638 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_list.php @@ -0,0 +1,569 @@ + + * Copyright (C) 2014-2016 Juanjo Menent + * Copyright (C) 2016 Jean-François Ferry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/skeleton_list.php + * \ingroup mymodule othermodule1 othermodule2 + * \brief This file is an example of a php page + * Put here some comments + */ + +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) + +// Change this following line to use the correct relative path (../, ../../, etc) +$res=0; +if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory +if (! $res && file_exists("../../main.inc.php")) $res=@include '../../main.inc.php'; // to work if your module directory is into a subdir of root htdocs directory +if (! $res && file_exists("../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res) die("Include of main fails"); +// Change this following line to use the correct relative path from htdocs +require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +dol_include_once('/mymodule/class/skeleton_class.class.php'); + +// Load traductions files requiredby by page +$langs->load("mymodule"); +$langs->load("other"); + +$action=GETPOST('action','alpha'); +$massaction=GETPOST('massaction','alpha'); +$show_files=GETPOST('show_files','int'); +$confirm=GETPOST('confirm','alpha'); +$toselect = GETPOST('toselect', 'array'); + +$id = GETPOST('id','int'); +$backtopage = GETPOST('backtopage'); +$myparam = GETPOST('myparam','alpha'); + +$search_all=trim(GETPOST("sall")); +$search_field1=GETPOST("search_field1"); +$search_field2=GETPOST("search_field2"); +$search_myfield=GETPOST('search_myfield'); +$optioncss = GETPOST('optioncss','alpha'); + +// Load variable for pagination +$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 = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortfield) $sortfield="t.rowid"; // Set here default search field +if (! $sortorder) $sortorder="ASC"; + +// Protection if external user +$socid=0; +if ($user->societe_id > 0) +{ + $socid = $user->societe_id; + //accessforbidden(); +} + +// Initialize technical object to manage context to save list fields +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'mymodulelist'; + +// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('mymodulelist')); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('mymodule'); +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); + +// List of fields to search into when doing a "search in all" +$fieldstosearchall = array( + 't.ref'=>'Ref', + 't.note_public'=>'NotePublic', +); +if (empty($user->socid)) $fieldstosearchall["t.note_private"]="NotePrivate"; + +// Definition of fields for list +$arrayfields=array( + 't.field1'=>array('label'=>$langs->trans("Field1"), 'checked'=>1), + 't.field2'=>array('label'=>$langs->trans("Field2"), 'checked'=>1), + //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), + 't.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), + 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), + //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), +); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } +} + + +// Load object if id or ref is provided as parameter +$object=new Skeleton_Class($db); +if (($id > 0 || ! empty($ref)) && $action != 'add') +{ + $result=$object->fetch($id,$ref); + if ($result < 0) dol_print_error($db); +} + + + + +/******************************************************************* +* ACTIONS +* +* Put here all code to do according to value of "action" parameter +********************************************************************/ + +if (GETPOST('cancel')) { $action='list'; $massaction=''; } +if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; } + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // Purge search criteria + if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") ||GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers + { + $search_field1=''; + $search_field2=''; + $search_date_creation=''; + $search_date_update=''; + $toselect=''; + $search_array_options=array(); + } + + // Mass actions + $objectclass='Skeleton'; + $objectlabel='Skeleton'; + $permtoread = $user->rights->skeleton->read; + $permtodelete = $user->rights->skeleton->delete; + $uploaddir = $conf->skeleton->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/*************************************************** +* VIEW +* +* Put here all code to build page +****************************************************/ + +$now=dol_now(); + +$form=new Form($db); + +//$help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; +$help_url=''; +$title = $langs->trans('MyModuleListTitle'); + +// Put here content of your page + +// Example : Adding jquery code +print ''; + + +$sql = "SELECT"; +$sql.= " t.rowid,"; +$sql.= " t.field1,"; +$sql.= " t.field2"; +// Add fields from extrafields +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); +// Add fields from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +$sql.= " FROM ".MAIN_DB_PREFIX."mytable as t"; +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."mytable_extrafields as ef on (t.rowid = ef.fk_object)"; +$sql.= " WHERE 1 = 1"; +//$sql.= " WHERE u.entity IN (".getEntity('mytable',1).")"; +if ($search_field1) $sql.= natural_search("field1",$search_field1); +if ($search_field2) $sql.= natural_search("field2",$search_field2); +if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); +// Add where from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode=0; + if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric + if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); + } +} +// Add where from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +$sql.=$db->order($sortfield,$sortorder); +//$sql.= $db->plimit($conf->liste_limit+1, $offset); + +// Count total nb of records +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} + +$sql.= $db->plimit($limit+1, $offset); + +dol_syslog($script_file, LOG_DEBUG); +$resql=$db->query($sql); +if (! $resql) +{ + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + +// Direct jump if only one record found +if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) +{ + $obj = $db->fetch_object($resql); + $id = $obj->rowid; + header("Location: ".DOL_URL_ROOT.'/skeleton/card.php?id='.$id); + exit; +} + +llxHeader('', $title, $help_url); + +$arrayofselected=is_array($toselect)?$toselect:array(); + +$param=''; +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; +if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; +if ($search_field1 != '') $param.= '&search_field1='.urlencode($search_field1); +if ($search_field2 != '') $param.= '&search_field2='.urlencode($search_field2); +if ($optioncss != '') $param.='&optioncss='.$optioncss; +// Add $param from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); +} + +$arrayofmassactions = array( + 'presend'=>$langs->trans("SendByMail"), + 'builddoc'=>$langs->trans("PDFMerge"), +); +if ($user->rights->mymodule->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); +if ($massaction == 'presend') $arrayofmassactions=array(); +$massactionbutton=$form->selectMassAction('', $arrayofmassactions); + +print '
    '; +if ($optioncss != '') print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); + +if ($sall) +{ + foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); + print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall); +} + +$moreforfilter = ''; +$moreforfilter.='
    '; +$moreforfilter.= $langs->trans('MyFilter') . ': '; +$moreforfilter.= '
    '; + +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook +if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; +else $moreforfilter = $hookmanager->resPrint; + +if (! empty($moreforfilter)) +{ + print '
    '; + print $moreforfilter; + print '
    '; +} + +$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; +$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + +print '
    '; +print ''."\n"; + +// Fields title +print ''; +// LIST_OF_TD_TITLE_FIELDS +//if (! empty($arrayfields['t.field1']['checked'])) print_liste_field_titre($arrayfields['t.field1']['label'],$_SERVER['PHP_SELF'],'t.field1','',$param,'',$sortfield,$sortorder); +//if (! empty($arrayfields['t.field2']['checked'])) print_liste_field_titre($arrayfields['t.field2']['label'],$_SERVER['PHP_SELF'],'t.field2','',$param,'',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +//if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print ''."\n"; + +// Fields title search +print ''; +// LIST_OF_TD_TITLE_SEARCH +//if (! empty($arrayfields['t.field1']['checked'])) print ''; +//if (! empty($arrayfields['t.field2']['checked'])) print ''; +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } +} +// Fields from hook +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['t.datec']['checked'])) +{ + // Date creation + print ''; +} +if (! empty($arrayfields['t.tms']['checked'])) +{ + // Date modification + print ''; +} +/*if (! empty($arrayfields['u.statut']['checked'])) +{ + // Status + print ''; +}*/ +// Action column +print ''; +print ''."\n"; + + +$i=0; +$var=true; +$totalarray=array(); +while ($i < min($num, $limit)) +{ + $obj = $db->fetch_object($resql); + if ($obj) + { + $var = !$var; + + // Show here line of result + print ''; + // LIST_OF_TD_FIELDS_LIST + /* + if (! empty($arrayfields['t.field1']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['t.field2']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + }*/ + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print 'getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print ''; + if (! $i) $totalarray['nbfield']++; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Date creation + if (! empty($arrayfields['t.datec']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Date modification + if (! empty($arrayfields['t.tms']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Status + /* + if (! empty($arrayfields['u.statut']['checked'])) + { + $userstatic->statut=$obj->statut; + print ''; + }*/ + + // Action column + print ''; + if (! $i) $totalarray['nbfield']++; + + print ''; + } + $i++; +} + +// Show total line +if (isset($totalarray['totalhtfield'])) +{ + print ''; + $i=0; + while ($i < $totalarray['nbfield']) + { + $i++; + if ($i == 1) + { + if ($num < $limit) print ''; + else print ''; + } + elseif ($totalarray['totalhtfield'] == $i) print ''; + elseif ($totalarray['totalvatfield'] == $i) print ''; + elseif ($totalarray['totalttcfield'] == $i) print ''; + else print ''; + } + print ''; +} + +$db->free($resql); + +$parameters=array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook=$hookmanager->executeHooks('printFieldListFooter',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print '
    '; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); + print ''; +$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); +print $searchpitco; +print '
    '.$obj->field1.''.$obj->field2.''; + print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); + print ''; + print dol_print_date($db->jdate($obj->date_update), 'dayhour'); + print ''.$userstatic->getLibStatut(3).''; + if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected=0; + if (in_array($obj->rowid, $arrayofselected)) $selected=1; + print ''; + } + print '
    '.$langs->trans("Total").''.$langs->trans("Totalforthispage").''.price($totalarray['totalht']).''.price($totalarray['totalvat']).''.price($totalarray['totalttc']).'
    '."\n"; +print '
    '."\n"; + +print '
    '."\n"; + + +if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) +{ + // Show list of available documents + $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; + $urlsource.=str_replace('&','&',$param); + + $filedir=$diroutputmassaction; + $genallowed=$user->rights->facture->lire; + $delallowed=$user->rights->facture->lire; + + print $formfile->showdocuments('massfilesarea_mymodule','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,''); +} +else +{ + print '
    '.$langs->trans("ShowTempMassFilesArea").''; +} + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/modulebuilder/skeletons/skeleton_script.php b/htdocs/modulebuilder/skeletons/skeleton_script.php new file mode 100644 index 00000000000..5eb1565d4a3 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_script.php @@ -0,0 +1,166 @@ +#!/usr/bin/env php + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/skeleton_script.php + * \ingroup mymodule + * \brief This file is an example for a command line script + * Put here some comments + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +// Global variables +$version='1.0'; +$error=0; + + +// -------------------- START OF YOUR CODE HERE -------------------- +@set_time_limit(0); // No timeout for this script +define('EVEN_IF_ONLY_LOGIN_ALLOWED',1); // Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only". + +// Include and load Dolibarr environment variables +require_once($path."../../htdocs/master.inc.php"); +// After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file). +// $user is created but empty. + +//$langs->setDefaultLang('en_US'); // To change default language of $langs +$langs->load("main"); // To load language file for default language + +// Load user and its permissions +$result=$user->fetch('','admin'); // Load user for login 'admin'. Comment line to run as anonymous user. +if (! $result > 0) { dol_print_error('',$user->error); exit; } +$user->getrights(); + + +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +if (! isset($argv[1])) { // Check parameters + print "Usage: ".$script_file." param1 param2 ...\n"; + exit(-1); +} +print '--- start'."\n"; +print 'Argument 1='.$argv[1]."\n"; +print 'Argument 2='.$argv[2]."\n"; + + +// Start of transaction +$db->begin(); + + +// Examples for manipulating class skeleton_class +require_once(DOL_DOCUMENT_ROOT."/../dev/skeletons/skeleton_class.class.php"); +$myobject=new Skeleton_Class($db); + +// Example for inserting creating object in database +/* +dol_syslog($script_file." CREATE", LOG_DEBUG); +$myobject->prop1='value_prop1'; +$myobject->prop2='value_prop2'; +$id=$myobject->create($user); +if ($id < 0) { $error++; dol_print_error($db,$myobject->error); } +else print "Object created with id=".$id."\n"; +*/ + +// Example for reading object from database +/* +dol_syslog($script_file." FETCH", LOG_DEBUG); +$result=$myobject->fetch($id); +if ($result < 0) { $error; dol_print_error($db,$myobject->error); } +else print "Object with id=".$id." loaded\n"; +*/ + +// Example for updating object in database ($myobject must have been loaded by a fetch before) +/* +dol_syslog($script_file." UPDATE", LOG_DEBUG); +$myobject->prop1='newvalue_prop1'; +$myobject->prop2='newvalue_prop2'; +$result=$myobject->update($user); +if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } +else print "Object with id ".$myobject->id." updated\n"; +*/ + +// Example for deleting object in database ($myobject must have been loaded by a fetch before) +/* +dol_syslog($script_file." DELETE", LOG_DEBUG); +$result=$myobject->delete($user); +if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } +else print "Object with id ".$myobject->id." deleted\n"; +*/ + + +// An example of a direct SQL read without using the fetch method +/* +$sql = "SELECT field1, field2"; +$sql.= " FROM ".MAIN_DB_PREFIX."skeleton"; +$sql.= " WHERE field3 = 'xxx'"; +$sql.= " ORDER BY field1 ASC"; + +dol_syslog($script_file, LOG_DEBUG); +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + if ($num) + { + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + // You can use here results + print $obj->field1; + print $obj->field2; + } + $i++; + } + } +} +else +{ + $error++; + dol_print_error($db); +} +*/ + + +// -------------------- END OF YOUR CODE -------------------- + +if (! $error) +{ + $db->commit(); + print '--- end ok'."\n"; +} +else +{ + print '--- end error code='.$error."\n"; + $db->rollback(); +} + +$db->close(); // Close $db database opened handler + +exit($error); diff --git a/htdocs/modulebuilder/skeletons/skeleton_webservice_server.php b/htdocs/modulebuilder/skeletons/skeleton_webservice_server.php new file mode 100644 index 00000000000..54a050ff9da --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_webservice_server.php @@ -0,0 +1,272 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/webservices/server_skeleton.php + * \brief File that is entry point to call Dolibarr WebServices + * \version $Id: server_skeleton.php,v 1.7 2010/12/19 11:49:37 eldy Exp $ + */ + +// This is to make Dolibarr working with Plesk +set_include_path($_SERVER['DOCUMENT_ROOT'].'/htdocs'); + +require_once("../master.inc.php"); +require_once(NUSOAP_PATH.'/nusoap.php'); // Include SOAP +require_once(DOL_DOCUMENT_ROOT."/core/lib/ws.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/skeleton/class/skeleton.class.php"); + + +dol_syslog("Call Skeleton webservices interfaces"); + +// Enable and test if module web services is enabled +if (empty($conf->global->MAIN_MODULE_WEBSERVICES)) +{ + $langs->load("admin"); + dol_syslog("Call Dolibarr webservices interfaces with module webservices disabled"); + print $langs->trans("WarningModuleNotActive",'WebServices').'.

    '; + print $langs->trans("ToActivateModule"); + exit; +} + +// Create the soap Object +$server = new nusoap_server(); +$server->soap_defencoding='UTF-8'; +$server->decode_utf8=false; +$ns='http://www.dolibarr.org/ns/'; +$server->configureWSDL('WebServicesDolibarrSkeleton',$ns); +$server->wsdl->schemaTargetNamespace=$ns; + + +// Define WSDL Authentication object +$server->wsdl->addComplexType( + 'authentication', + 'complexType', + 'struct', + 'all', + '', + array( + 'dolibarrkey' => array('name'=>'dolibarrkey','type'=>'xsd:string'), + 'sourceapplication' => array('name'=>'sourceapplication','type'=>'xsd:string'), + 'login' => array('name'=>'login','type'=>'xsd:string'), + 'password' => array('name'=>'password','type'=>'xsd:string'), + 'entity' => array('name'=>'entity','type'=>'xsd:string'), + ) +); + +// Define WSDL Return object +$server->wsdl->addComplexType( + 'result', + 'complexType', + 'struct', + 'all', + '', + array( + 'result_code' => array('name'=>'result_code','type'=>'xsd:string'), + 'result_label' => array('name'=>'result_label','type'=>'xsd:string'), + ) +); + +// Define other specific objects +$server->wsdl->addComplexType( + 'skeleton', + 'complexType', + 'struct', + 'all', + '', + array( + 'prop1'=>'xxx', + 'prop2'=>'xxx', + //... + ) +); + + + +// 5 styles: RPC/encoded, RPC/literal, Document/encoded (not WS-I compliant), Document/literal, Document/literal wrapped +// Style merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model. +// http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/ +$styledoc='rpc'; // rpc/document (document is an extend into SOAP 1.0 to support unstructured messages) +$styleuse='encoded'; // encoded/literal/literal wrapped +// Better choice is document/literal wrapped but literal wrapped not supported by nusoap. + + +// Register WSDL +$server->register( + 'getSkeleton', + // Entry values + array('authentication'=>'tns:authentication','id'=>'xsd:string','ref'=>'xsd:string','ref_ext'=>'xsd:string'), + // Exit values + array('result'=>'tns:result','skeleton'=>'tns:skeleton'), + $ns, + $ns.'#getSkeleton', + $styledoc, + $styleuse, + 'WS to get skeleton' +); + +// Register WSDL +$server->register( + 'createSkeleton', + // Entry values + array('authentication'=>'tns:authentication','skeleton'=>'tns:skeleton'), + // Exit values + array('result'=>'tns:result','id'=>'xsd:string'), + $ns, + $ns.'#createSkeleton', + $styledoc, + $styleuse, + 'WS to create a skeleton' +); + + + + +/** + * Get Skeleton + * + * @param array $authentication Array of authentication information + * @param int $id Id of object + * @param string $ref Ref of object + * @param string $ref_ext Ref external of object + * @return mixed + */ +function getSkeleton($authentication,$id,$ref='',$ref_ext='') +{ + global $db,$conf,$langs; + + dol_syslog("Function: getSkeleton login=".$authentication['login']." id=".$id." ref=".$ref." ref_ext=".$ref_ext); + + if ($authentication['entity']) $conf->entity=$authentication['entity']; + + // Init and check authentication + $objectresp=array(); + $errorcode='';$errorlabel=''; + $error=0; + $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + // Check parameters + if (! $error && (($id && $ref) || ($id && $ref_ext) || ($ref && $ref_ext))) + { + $error++; + $errorcode='BAD_PARAMETERS'; $errorlabel="Parameter id, ref and ref_ext can't be both provided. You must choose one or other but not both."; + } + + if (! $error) + { + $fuser->getrights(); + + if ($fuser->rights->skeleton->read) + { + $skeleton=new Skeleton($db); + $result=$skeleton->fetch($id,$ref,$ref_ext); + if ($result > 0) + { + // Create + $objectresp = array( + 'result'=>array('result_code'=>'OK', 'result_label'=>''), + 'skeleton'=>array( + 'prop1'=>$skeleton->prop1, + 'prop2'=>$skeleton->prop2, + //... + ) + ); + } + else + { + $error++; + $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext; + } + } + else + { + $error++; + $errorcode='PERMISSION_DENIED'; $errorlabel='User does not have permission for this request'; + } + } + + if ($error) + { + $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); + } + + return $objectresp; +} + + +/** + * Create Skeleton + * + * @param array $authentication Array of authentication information + * @param Skeleton $skeleton $skeleton + * @return array Array result + */ +function createSkeleton($authentication,$skeleton) +{ + global $db,$conf,$langs; + + $now=dol_now(); + + dol_syslog("Function: createSkeleton login=".$authentication['login']); + + if ($authentication['entity']) $conf->entity=$authentication['entity']; + + // Init and check authentication + $objectresp=array(); + $errorcode='';$errorlabel=''; + $error=0; + $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + // Check parameters + + + if (! $error) + { + $newobject=new Skeleton($db); + $newobject->prop1=$skeleton->prop1; + $newobject->prop2=$skeleton->prop2; + //... + + $db->begin(); + + $result=$newobject->create($fuser); + if ($result <= 0) + { + $error++; + } + + if (! $error) + { + $db->commit(); + $objectresp=array('result'=>array('result_code'=>'OK', 'result_label'=>''),'id'=>$newobject->id,'ref'=>$newobject->ref); + } + else + { + $db->rollback(); + $error++; + $errorcode='KO'; + $errorlabel=$newobject->error; + } + } + + if ($error) + { + $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); + } + + return $objectresp; +} + +// Return the results. +$server->service(file_get_contents("php://input")); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 49c17a749f0..f7cb1c0bb5a 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1642,6 +1642,10 @@ div.login_block_other { padding-top: 3px; text-align: right; } .alogin:hover, .atoplogin:hover { text-decoration:underline !important; } +span.fa.atoplogin, span.fa.atoplogin:hover { + font-size: 16px; + text-decoration: none !important; +} img.login, img.printer, img.entity { /* padding: 0px 0px 0px 4px; */ /* margin: 0px 0px 0px 8px; */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 1908fcfef4a..f83d5df0d50 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1675,6 +1675,10 @@ div.login_block_other { padding-top: 3px; } .alogin:hover, .atoplogin:hover { text-decoration:underline !important; } +span.fa.atoplogin, span.fa.atoplogin:hover { + font-size: 16px; + text-decoration: none !important; +} img.login, img.printer, img.entity { /* padding: 0px 0px 0px 4px; */ /* margin: 0px 0px 0px 8px; */ diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 4b9c1c9960c..26af6c659ff 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2118,7 +2118,7 @@ class User extends CommonObject } /** - * Retourne le libelle du statut d'un user (actif, inactif) + * Return label of status of user (active, inactive) * * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto * @return string Label of status From 1489847a7412bd70bbcf530cfce9bcfa125e0986 Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Thu, 30 Mar 2017 09:49:34 +0200 Subject: [PATCH 262/410] Display mobile icon Display a specific icon when mobile --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b79c72e6336..e6a5b5d6b92 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -495,7 +495,7 @@ abstract class CommonObject $out.=dol_print_phone($this->phone_pro,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePro")); $outdone++; } if (! empty($this->phone_mobile)) { - $out.=dol_print_phone($this->phone_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhoneMobile")); $outdone++; + $out.=dol_print_phone($this->phone_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','mobile',$langs->trans("PhoneMobile")); $outdone++; } if (! empty($this->phone_perso)) { $out.=dol_print_phone($this->phone_perso,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePerso")); $outdone++; @@ -507,7 +507,7 @@ abstract class CommonObject $out.=dol_print_phone($this->office_phone,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePro")); $outdone++; } if (! empty($this->user_mobile)) { - $out.=dol_print_phone($this->user_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhoneMobile")); $outdone++; + $out.=dol_print_phone($this->user_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','mobile',$langs->trans("PhoneMobile")); $outdone++; } if (! empty($this->office_fax)) { $out.=dol_print_phone($this->fax,$this->country_code,$contactid,$thirdpartyid,'AC_FAX',' ','fax',$langs->trans("Fax")); $outdone++; From 78cc976e9f6d6f2d835ec8cf517e54ee120b9010 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 10:40:15 +0200 Subject: [PATCH 263/410] Work on module builder --- htdocs/core/modules/modCron.class.php | 2 +- htdocs/core/modules/modModuleBuilder.class.php | 14 ++++++++++++++ htdocs/core/modules/modPrinting.class.php | 2 +- htdocs/langs/en_US/admin.lang | 2 +- htdocs/langs/en_US/main.lang | 1 + htdocs/langs/en_US/modulebuilder.lang | 1 - htdocs/main.inc.php | 2 +- 7 files changed, 19 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 88b154f891e..7f949501023 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -138,7 +138,7 @@ class modCron extends DolibarrModules 'url'=>'/cron/list.php?status=-2&leftmenu=admintools', 'langs'=>'cron', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>200, - 'enabled'=>'($leftmenu==\'admintools\' || $leftmenu==\'admintools_info\')', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->cron->enabled && preg_match(\'/^admintools/\', $leftmenu)', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'$user->rights->cron->read', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both diff --git a/htdocs/core/modules/modModuleBuilder.class.php b/htdocs/core/modules/modModuleBuilder.class.php index b68148377c3..dce442720a3 100644 --- a/htdocs/core/modules/modModuleBuilder.class.php +++ b/htdocs/core/modules/modModuleBuilder.class.php @@ -85,5 +85,19 @@ class modModuleBuilder extends DolibarrModules // Main menu entries //------------------ $this->menu = array(); + + $this->menu[$r]=array('fk_menu'=>'fk_mainmenu=home,fk_leftmenu=admintools', + 'type'=>'left', + 'titre'=>'ModuleBuilder', + 'mainmenu'=>'home', + 'leftmenu'=>'admintools_modulebuilder', + 'url'=>'/modulebuilder/index.php?mainmenu=home&leftmenu=admintools_modulebuilder', + 'langs'=>'modulebuilder', + 'position'=>100, + 'perms'=>'1', + 'enabled'=>'$conf->modulebuilder->enabled && preg_match(\'/^admintools/\',$leftmenu) && ($user->admin || $conf->global->MODULEBUILDER_FOREVERYONE)', + 'target'=>'_modulebuilder', + 'user'=>0); + } } diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php index fd101615809..89bf6115dae 100644 --- a/htdocs/core/modules/modPrinting.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -111,7 +111,7 @@ class modPrinting extends DolibarrModules 'url'=>'/printing/index.php?mainmenu=home&leftmenu=admintools', 'langs'=>'printing', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, - 'enabled'=>'$conf->printing->enabled && ($leftmenu==\'admintools\' || $leftmenu==\'admintools_info\')', + 'enabled'=>'$conf->printing->enabled && preg_match(\'/^admintools/\', $leftmenu)', 'perms'=>'$user->rights->printing->read', // Use 'perms'=>'1' if you want your menu with no permission rules 'target'=>'', 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 3831fb49007..b3f43698843 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1664,7 +1664,7 @@ UserHasNoPermissions=This user has no permission defined TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "Nb of days")
    Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days)
    Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days") BaseCurrency=Reference currency of the company (go into setup of company to change this) WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016). -WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activate an external module only if it does not alterate negatively the behavior required by your country laws (%s). If the module bring a non legal feature, you are the only responsible for the use of a non-compliant software. +WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activating an external module means you trust the editor 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. ##### Resource #### ResourceSetup=Configuration du module Resource UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list). diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 53d727d9965..918f46a44b7 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -763,6 +763,7 @@ DirectDownloadLink=Direct download link Download=Download ActualizeCurrency=Update currency rate Fiscalyear=Fiscal year +ModuleBuilder=Module Builder # Week day Monday=Monday Tuesday=Tuesday diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 6605a7b6a63..9979760bc4f 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -1,3 +1,2 @@ # Dolibarr language file - Source file is en_US - loan -ModuleBuilder=Module Builder ModuleBuilderDesc=This tools give you utilites to build your own module. Your modules will be generated into the first alternative directory: %s. diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index fe1ed01a68f..88e2760ecb4 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1440,7 +1440,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a // Link to module builder if (! empty($conf->modulebuilder->enabled)) { - $text =''; + $text =''; //$text.= img_picto(":".$langs->trans("ModuleBuilder"), 'printer_top.png', 'class="printer"'); $text.=''; $text.=''; From f01815519a1fcdc59f883de3969c7eba5e6d1131 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 11:25:28 +0200 Subject: [PATCH 264/410] Fix trigger of automatic events --- htdocs/adherents/agenda.php | 4 +-- htdocs/core/lib/company.lib.php | 7 ++++-- ...terface_50_modAgenda_ActionsAuto.class.php | 24 ++++++++++++++---- .../mysql/data/llx_c_action_trigger.sql | 25 +++++++++++-------- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index 74f9e8234ad..ecb0b672250 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -167,10 +167,10 @@ if ($object->id > 0) print load_fiche_titre($langs->trans("ActionsOnMember"),$out,''); // List of todo actions - show_actions_todo($conf,$langs,$db,$object); + //show_actions_todo($conf,$langs,$db,$object); // List of done actions - show_actions_done($conf,$langs,$db,$object); + show_actions_done($conf,$langs,$db,$object,null,0,'',''); } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index b010f8143b4..4e52f2d8f01 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -960,7 +960,7 @@ function show_actions_todo($conf,$langs,$db,$filterobj,$objcon='',$noprint=0,$ac * @param Contact $objcon Object contact * @param int $noprint Return string but does not output it * @param string $actioncode Filter on actioncode - * @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter. + * @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter (all). * @param array $filters Filter on other fields * @param string $sortfield Sort field * @param string $sortorder Sort order @@ -1181,7 +1181,10 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= { $out.=''; if (get_class($filterobj) == 'Societe') $out.=''; - $out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort"); + $out.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); + $out.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); + $out.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); + //$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort"); if (get_class($filterobj) == 'Societe') $out.=''; $out.=''; } diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index bce6cd02eee..d5354ab385f 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -658,6 +658,21 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->sendtoid=0; } + elseif ($action == 'MEMBER_MODIFY') + { + $langs->load("agenda"); + $langs->load("other"); + $langs->load("members"); + + $object->actiontypecode='AC_OTH_AUTO'; + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberModifiedInDolibarr",$object->ref); + $object->actionmsg=$langs->transnoentities("MemberModifiedInDolibarr",$object->ref); + $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$object->getFullName($langs); + $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->type; + $object->actionmsg.="\n".$langs->transnoentities("Author").': '.$user->login; + + $object->sendtoid=0; + } elseif ($action == 'MEMBER_SUBSCRIPTION') { $langs->load("agenda"); @@ -721,21 +736,20 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->sendtoid=0; } - elseif($action == 'PROJECT_CREATE') { + elseif($action == 'PROJECT_VALIDATE') { $langs->load("agenda"); $langs->load("other"); $langs->load("projects"); $object->actiontypecode='AC_OTH_AUTO'; - if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectCreatedInDolibarr",$object->ref); - $object->actionmsg=$langs->transnoentities("ProjectCreatedInDolibarr",$object->ref); - $object->actionmsg.="\n".$langs->transnoentities("Task").': '.$object->ref; + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectValidatedInDolibarr",$object->ref); + $object->actionmsg=$langs->transnoentities("ProjectValidatedInDolibarr",$object->ref); + $object->actionmsg.="\n".$langs->transnoentities("Project").': '.$object->ref; $object->actionmsg.="\n".$langs->transnoentities("Author").': '.$user->login; $object->sendtoid=0; } - elseif($action == 'PROJECT_MODIFY') { $langs->load("agenda"); $langs->load("other"); diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index 2111a6c265c..5cbc7745080 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -68,19 +68,22 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('SHIPPING_VALIDATE','Shipping validated','Executed when a shipping is validated','shipping',20); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('SHIPPING_SENTBYMAIL','Shipping sent by mail','Executed when a shipping is sent by mail','shipping',21); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_VALIDATE','Member validated','Executed when a member is validated','member',22); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SUBSCRIPTION','Member subscribed','Executed when a member is subscribed','member',23); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_RESILIATE','Member resiliated','Executed when a member is resiliated','member',24); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_MODIFY','Member modified','Executed when a member is modified','member',24); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_DELETE','Member deleted','Executed when a member is deleted','member',25); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_VALIDATE','Intervention validated','Executed when a intervention is validated','ficheinter',19); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_BILLED','Intervention set billed','Executed when a intervention is set to billed (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',19); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_UNBILLED','Intervention set unbilled','Executed when a intervention is set to unbilled (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',19); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_REOPEN','Intervention opened','Executed when a intervention is re-opened','ficheinter',19); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',19); --- actions not enabled by default (no constant created for that) when we enable module agenda +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_MODIFY','Member modified','Executed when a member is modified','member',23); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SUBSCRIPTION','Member subscribed','Executed when a member is subscribed','member',24); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_RESILIATE','Member resiliated','Executed when a member is resiliated','member',25); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_DELETE','Member deleted','Executed when a member is deleted','member',27); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_VALIDATE','Intervention validated','Executed when a intervention is validated','ficheinter',30); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_BILLED','Intervention set billed','Executed when a intervention is set to billed (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',32); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_UNBILLED','Intervention set unbilled','Executed when a intervention is set to unbilled (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',33); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_REOPEN','Intervention opened','Executed when a intervention is re-opened','ficheinter',34); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',35); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_CREATE','Project creation','Executed when a project is created','project',140); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_MODIFY','Project modified','Executed when a project is modified','project',141); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_VALIDATE','Project validation','Executed when a project is validated','project',140); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_DELETE','Project deleted','Executed when a project is deleted','project',142); +-- actions not enabled by default (no constant created for that) when we enable module agenda +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_MODIFY','Member modified','Executed when a member is modified','member',26); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_MODIFY','Intervention modified','Executed when a intervention is modified','ficheinter',31); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_MODIFY','Project modified','Executed when a project is modified','project',141); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_CREATE','Task created','Executed when a project task is created','project',150); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_MODIFY','Task modified','Executed when a project task is modified','project',151); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_DELETE','Task deleted','Executed when a project task is deleted','project',152); From ce7368d10e00a44e0d8ba409720ed301956016d9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 11:51:07 +0200 Subject: [PATCH 265/410] Fix events create from member card not linked to member --- htdocs/adherents/agenda.php | 2 +- htdocs/langs/en_US/agenda.lang | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index ecb0b672250..fc73892d44d 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -141,7 +141,7 @@ if ($object->id > 0) if (! empty($conf->agenda->enabled)) { - print ''; + print ''; } print '
    '; diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index a429fc7159e..d0f3456987d 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -47,6 +47,7 @@ InvoiceDeleteDolibarr=Invoice %s deleted InvoicePaidInDolibarr=Invoice %s changed to paid InvoiceCanceledInDolibarr=Invoice %s canceled MemberValidatedInDolibarr=Member %s validated +MemberModifiedInDolibarr=Member %s modified MemberResiliatedInDolibarr=Member %s terminated MemberDeletedInDolibarr=Member %s deleted MemberSubscriptionAddedInDolibarr=Subscription for member %s added From 141ef91dea91b0662ba166c75e0deceacc4ba64c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 11:53:58 +0200 Subject: [PATCH 266/410] Fix default auto events --- htdocs/core/modules/modAgenda.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index a0c2a6e9de4..83175bcdefc 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -82,9 +82,9 @@ class modAgenda extends DolibarrModules { while ($obj = $this->db->fetch_object($sqlreadactions)) { - if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty or product creation because there is no validation). - if (preg_match('/^PROJECT_/',$obj->code)) continue; // We don't track such events by default. + if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE','TASK_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty/product/task creation because there is no validation). if (preg_match('/^TASK_/',$obj->code)) continue; // We don't track such events by default. + if (preg_match('/^_MODIFY/',$obj->code)) continue; // We don't track such events by default. $this->const[] = array('MAIN_AGENDA_ACTIONAUTO_'.$obj->code, "chaine", "1"); } } From 6bd112db5e844ba957e188d1db78d2ef45950dbb Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Thu, 30 Mar 2017 14:49:40 +0200 Subject: [PATCH 267/410] Unify the trigger name Should be COMPANY_RIB_MODIFY instead of COMPANY_RIB_UPDATE --- htdocs/societe/class/companybankaccount.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 6a00de29259..4101910005e 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -174,7 +174,7 @@ class CompanyBankAccount extends Account if (! $notrigger) { // Call trigger - $result=$this->call_trigger('COMPANY_RIB_UPDATE',$user); + $result=$this->call_trigger('COMPANY_RIB_MODIFY',$user); if ($result < 0) $error++; // End call triggers if(! $error ) From 2448b9ee55ed0eef1844aba8383e63842c600a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Thu, 30 Mar 2017 14:52:26 +0200 Subject: [PATCH 268/410] FIX #6619 Template invoices list do not respect restricted thirdparty user rights --- htdocs/compta/facture/fiche-rec.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index c7bf362ab7d..3a55c8b57c2 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -1384,8 +1384,14 @@ else $sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre, f.total, f.tva as total_vat, f.total_ttc, f.frequency,"; $sql.= " f.date_last_gen, f.date_when"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f"; + if (! $user->rights->societe->client->voir && ! $socid) { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } $sql.= " WHERE f.fk_soc = s.rowid"; $sql.= " AND f.entity = ".$conf->entity; + if (! $user->rights->societe->client->voir && ! $socid) { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; + } if ($search_ref) $sql .= natural_search('f.titre', $search_ref); if ($search_societe) $sql .= natural_search('s.nom', $search_societe); if ($search_frequency) $sql .= natural_search('f.frequency', $search_frequency); From cd5b074a4829abf1bcaa32d1f1dfe925d8aaca19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Thu, 30 Mar 2017 15:21:20 +0200 Subject: [PATCH 269/410] FIX #6621 Documents tab shows greyed out upload form even if the option to show actions not available is disabled --- htdocs/core/class/html.formfile.class.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index c117417e428..0821b9b2d2b 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -89,6 +89,11 @@ class FormFile } else { + //If there is no permission and the option to hide unauthorized actions is enabled, then nothing is printed + if (!$perm && !empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) { + return 1; + } + $maxlength=$size; $out = "\n\n\n"; From 8e70c4a0b738e42b42b845dae8af885aa95083b8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 15:39:50 +0200 Subject: [PATCH 270/410] Work on 6.0 new look and feel --- htdocs/adherents/agenda.php | 38 ++--- htdocs/adherents/document.php | 2 +- htdocs/adherents/note.php | 3 +- htdocs/contact/list.php | 9 +- htdocs/core/class/html.formother.class.php | 2 +- htdocs/core/lib/company.lib.php | 123 ++++++++------- htdocs/core/lib/functions.lib.php | 10 +- htdocs/core/modules/modAgenda.class.php | 4 +- htdocs/expedition/list.php | 73 +++++---- htdocs/imports/import.php | 53 ++++--- htdocs/langs/en_US/exports.lang | 2 + htdocs/product/popuprop.php | 7 +- htdocs/product/reassort.php | 171 +++++++++------------ htdocs/product/reassortlot.php | 68 ++++---- htdocs/product/stock/list.php | 22 +-- htdocs/product/stock/productlot_list.php | 129 ++++++++-------- htdocs/product/stock/replenish.php | 32 ++-- htdocs/product/stock/replenishorders.php | 135 ++++++++-------- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 20 files changed, 429 insertions(+), 458 deletions(-) diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index fc73892d44d..f85761ff266 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -36,7 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; $langs->load("companies"); $langs->load("members"); -$id = GETPOST('id','int'); +$id = GETPOST('id','int')?GETPOST('id','int'):GETPOST('rowid','int'); // Security check $result=restrictedArea($user,'adherent',$id); @@ -85,12 +85,13 @@ if ($object->id > 0) if (! empty($conf->notification->enabled)) $langs->load("mails"); $head = member_prepare_head($object); - dol_fiche_head($head, 'agenda', $langs->trans("Member"),0,'user'); + dol_fiche_head($head, 'agenda', $langs->trans("Member"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'rowid', $linkback); + /* print '
    '; print '
    '; @@ -107,9 +108,6 @@ if ($object->id > 0) // Morphy print ''.$langs->trans("Nature").''.$object->getmorphylib().''; - /*print ''; - print $form->showphoto('memberphoto',$member); - print '';*/ print ''; // Company @@ -120,15 +118,16 @@ if ($object->id > 0) print ''; print ''; - + */ - print '
    '; + print '
    '; + + print '
    '; $object->info($id); print dol_print_object_info($object, 1); - - print '
    '; + print '
    '; dol_fiche_end(); @@ -146,30 +145,11 @@ if ($object->id > 0) print '
    '; - print '
    '; - $out=''; - /*$objthirdparty=$object->thirdparty; - $objcon=new stdClass(); - - $permok=$user->rights->agenda->myactions->create; - if ((! empty($objthirdparty->id) || ! empty($objcon->id)) && $permok) - { - $out.=''; - $out.=$langs->trans("AddAnAction").' '; - $out.=img_picto($langs->trans("AddAnAction"),'filenew'); - $out.=""; - }*/ - print load_fiche_titre($langs->trans("ActionsOnMember"),$out,''); - // List of todo actions - //show_actions_todo($conf,$langs,$db,$object); - - // List of done actions + // List of actions show_actions_done($conf,$langs,$db,$object,null,0,'',''); } diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php index 47fbebbf976..cbc6d7f090c 100644 --- a/htdocs/adherents/document.php +++ b/htdocs/adherents/document.php @@ -108,7 +108,7 @@ if ($id > 0) $head = member_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans("Member"),0,'user'); + dol_fiche_head($head, 'document', $langs->trans("Member"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php index 9e6a20f6cb3..325b14680e7 100644 --- a/htdocs/adherents/note.php +++ b/htdocs/adherents/note.php @@ -69,7 +69,7 @@ if ($id) { $head = member_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("Member"), 0, 'user'); + dol_fiche_head($head, 'note', $langs->trans("Member"), -1, 'user'); print "
    "; print ''; @@ -109,7 +109,6 @@ if ($id) print ""; print '
    '; - print '
    '; $cssclass='titlefield'; diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 4e7a9c6f190..e7d4f603618 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -784,12 +784,13 @@ while ($i < min($num,$limit)) print ''.$contactstatic->getLibStatut(3).''; } // Action column - Links Add action and Export vcard - print ''; - print ''.img_object($langs->trans("AddAction"),"action").''; + print ''; + /*print ''.img_object($langs->trans("AddAction"),"action").''; print '   '; - print ''; + print ''; print img_picto($langs->trans("VCard"),'vcard.png').' '; - print ''; + print ''; */ + print ''; print "\n"; $i++; diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 270deb2134e..66e624e96b9 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -121,7 +121,7 @@ class FormOther $result = $this->db->query($sql); if ($result) { - print ''; if ($useempty) { print ''; diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 13152f85ac8..bbe9febd481 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1005,7 +1005,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $sql.= " a.fk_element, a.elementtype,"; $sql.= " a.fk_user_author, a.fk_contact,"; $sql.= " c.code as acode, c.libelle as alabel, c.picto as apicto,"; - $sql.= " u.login, u.rowid as user_id"; + $sql.= " u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; if (get_class($filterobj) == 'Societe') $sql.= ", sp.lastname, sp.firstname"; if (get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname"; if (get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref"; @@ -1078,9 +1078,14 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= 'dateend'=>$db->jdate($obj->dp2), 'note'=>$obj->label, 'percent'=>$obj->percent, + 'userid'=>$obj->user_id, - 'login'=>$obj->login, - 'contact_id'=>$obj->fk_contact, + 'login'=>$obj->user_login, + 'userfirstname'=>$obj->user_firstname, + 'userlastname'=>$obj->user_lastname, + 'userphoto'=>$obj->user_photo, + + 'contact_id'=>$obj->fk_contact, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'fk_element'=>$obj->fk_element, @@ -1109,7 +1114,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $sql = "SELECT m.rowid as id, mc.date_envoi as da, m.titre as note, '100' as percentage,"; $sql.= " 'AC_EMAILING' as acode,"; - $sql.= " u.rowid as user_id, u.login"; // User that valid action + $sql.= " u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; // User that valid action $sql.= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."user as u"; $sql.= " WHERE mc.email = '".$db->escape($objcon->email)."'"; // Search is done on email. $sql.= " AND mc.statut = 1"; @@ -1136,8 +1141,12 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= 'note'=>$obj->note, 'percent'=>$obj->percentage, 'acode'=>$obj->acode, - 'userid'=>$obj->user_id, - 'login'=>$obj->login + + 'userid'=>$obj->user_id, + 'login'=>$obj->user_login, + 'userfirstname'=>$obj->user_firstname, + 'userlastname'=>$obj->user_lastname, + 'userphoto'=>$obj->user_photo ); $numaction++; $i++; @@ -1189,52 +1198,50 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.='
    '; $out.=''; + + $out.=''; + if ($donetodo) + { + $out.=''; + } + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + // Action column + $out.=''; + $out.=''; + $out.=''; if ($donetodo) { - $out.=''; + if (get_class($filterobj) == 'Societe') $tmp.=''; + $out.=getTitleFieldOfList($tmp); } - $out.=getTitleFieldOfList($langs->trans("Ref"), 0, $_SERVER["PHP_SELF"], 'a.id', '', $param, '', $sortfield, $sortorder); - $out.=''; - $out.=getTitleFieldOfList($langs->trans("Date"), 0, $_SERVER["PHP_SELF"], 'a.datep,a.id', '', $param, '', $sortfield, $sortorder); - $out.=''; - $out.=''; - $out.=''; - $out.=''; + $out.=getTitleFieldOfList($langs->trans("Ref"), 0, $_SERVER["PHP_SELF"], 'a.id', '', $param, '', $sortfield, $sortorder); + $out.=getTitleFieldOfList($langs->trans("Owner")); + $out.=getTitleFieldOfList($langs->trans("Label"), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder); + $out.=getTitleFieldOfList($langs->trans("Date"), 0, $_SERVER["PHP_SELF"], 'a.datep,a.id', '', $param, 'align="center"', $sortfield, $sortorder); + $out.=getTitleFieldOfList($langs->trans("Type")); + $out.=getTitleFieldOfList(''); + $out.=getTitleFieldOfList(''); $out.=getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], 'a.percent', '', $param, 'align="center"', $sortfield, $sortorder); - $out.=''; - $out.=''; - - - $out.=''; - if ($donetodo) - { - $out.=''; - } - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - // Action column - $out.=''; + $out.=getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'maxwidthsearch '); $out.=''; foreach ($histo as $key=>$value) @@ -1256,6 +1263,15 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.=$actionstatic->getNomUrl(1, -1); $out.=''; + // Author of event + $out.=''; + // Title $out.=''; - + // Date - $out.=''; } - // Auteur - $out.=''; - - // Statut + // Status $out.=''; // Actions diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index f9ba39f870e..ea92fb5a63b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2711,7 +2711,7 @@ function img_error($titlealt = 'default') if ($titlealt == 'default') $titlealt = $langs->trans('Error'); - return img_picto($titlealt, 'error.png'); + return img_picto($titlealt, 'error.png', 'class="valigntextbottom"'); } /** @@ -2727,7 +2727,8 @@ function img_next($titlealt = 'default', $morealt='') if ($titlealt == 'default') $titlealt = $langs->trans('Next'); - return img_picto($titlealt, 'next.png', $morealt); + //return img_picto($titlealt, 'next.png', $morealt); + return ''; } /** @@ -2743,7 +2744,8 @@ function img_previous($titlealt = 'default', $morealt='') if ($titlealt == 'default') $titlealt = $langs->trans('Previous'); - return img_picto($titlealt, 'previous.png', $morealt); + //return img_picto($titlealt, 'previous.png', $morealt); + return ''; } /** @@ -3109,7 +3111,7 @@ function print_liste_field_titre($name, $file="", $field="", $begin="", $morepar * @param string $field Field to use for new sorting. Empty if this field is not sortable. * @param string $begin ("" by defaut) * @param string $moreparam Add more parameters on sort url links ("" by default) - * @param string $moreattrib Add more attributes on th ("" by defaut) + * @param string $moreattrib Add more attributes on th ("" by defaut). To add more css class, use param $prefix. * @param string $sortfield Current field used to sort * @param string $sortorder Current sort order * @param string $prefix Prefix for css. Use space after prefix to add your own CSS tag. diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index 291ca6bdbfd..339a208fc31 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -86,9 +86,9 @@ class modAgenda extends DolibarrModules { while ($obj = $this->db->fetch_object($sqlreadactions)) { - if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE','TASK_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty/product/task creation because there is no validation). + //if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE','TASK_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty/product/task creation because there is no validation). if (preg_match('/^TASK_/',$obj->code)) continue; // We don't track such events by default. - if (preg_match('/^_MODIFY/',$obj->code)) continue; // We don't track such events by default. + //if (preg_match('/^_MODIFY/',$obj->code)) continue; // We don't track such events by default. $this->const[] = array('MAIN_AGENDA_ACTIONAUTO_'.$obj->code, "chaine", "1"); } } diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 65d7fd5223e..4166bbb3791 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -308,44 +308,8 @@ if ($resql) print '
    '; print '
    '; + $out.=$formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:-1, 0, 0, 1); + $out.=''; + $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $out.=$searchpitco; + $out.='
    '; - if (get_class($filterobj) == 'Societe') $out.=''; - $out.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); - $out.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); - $out.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); + $tmp=''; + if (get_class($filterobj) == 'Societe') $tmp.=''; + $tmp.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); + $tmp.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); + $tmp.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); //$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort"); - if (get_class($filterobj) == 'Societe') $out.=''; - $out.=''.$langs->trans("Label").''.$langs->trans("Type").''.$langs->trans("Owner").''; - //TODO Add selection of fields - $out.='
    '; - $out.=$formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:-1, 0, 0, 1); - $out.=''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - $out.=$searchpitco; - $out.='
    '; + //$userstatic->id=$histo[$key]['userid']; + //$userstatic->login=$histo[$key]['login']; + //$out.=$userstatic->getLoginUrl(1); + $userstatic->fetch($histo[$key]['userid']); + $out.=$userstatic->getNomUrl(-1); + $out.=''; if (isset($histo[$key]['type']) && $histo[$key]['type']=='action') @@ -1276,9 +1292,9 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.=dol_trunc($libelle,120); } $out.=''; + $out.=''; $out.=dol_print_date($histo[$key]['datestart'],'dayhour'); if ($histo[$key]['dateend'] && $histo[$key]['dateend'] != $histo[$key]['datestart']) { @@ -1374,16 +1390,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.=' '; - //$userstatic->id=$histo[$key]['userid']; - //$userstatic->login=$histo[$key]['login']; - //$out.=$userstatic->getLoginUrl(1); - $userstatic->fetch($histo[$key]['userid']); - $out.=$userstatic->getNomUrl(1); - $out.=''.$actionstatic->LibStatut($histo[$key]['percent'],3,1,$histo[$key]['datestart']).'
    '."\n"; - print ''; - - if (! empty($arrayfields['e.ref']['checked'])) print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"],"e.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['e.ref_customer']['checked'])) print_liste_field_titre($arrayfields['e.ref_customer']['label'], $_SERVER["PHP_SELF"],"e.ref_customer","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom", "", $param,'align="left"',$sortfield,$sortorder); - if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['e.date_delivery']['checked'])) print_liste_field_titre($arrayfields['e.date_delivery']['label'], $_SERVER["PHP_SELF"],"e.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['l.ref']['checked'])) print_liste_field_titre($arrayfields['l.ref']['label'], $_SERVER["PHP_SELF"],"l.ref","",$param, '',$sortfield,$sortorder); - if (! empty($arrayfields['l.date_delivery']['checked'])) print_liste_field_titre($arrayfields['l.date_delivery']['label'], $_SERVER["PHP_SELF"],"l.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['e.datec']['checked'])) print_liste_field_titre($arrayfields['e.datec']['label'],$_SERVER["PHP_SELF"],"e.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['e.tms']['checked'])) print_liste_field_titre($arrayfields['e.tms']['label'],$_SERVER["PHP_SELF"],"e.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['e.fk_statut']['checked'])) print_liste_field_titre($arrayfields['e.fk_statut']['label'],$_SERVER["PHP_SELF"],"e.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['l.fk_statut']['checked'])) print_liste_field_titre($arrayfields['l.fk_statut']['label'], $_SERVER["PHP_SELF"],"l.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; // Ref if (! empty($arrayfields['e.ref']['checked'])) { @@ -462,6 +426,41 @@ if ($resql) print ''; print "\n"; + print ''; + if (! empty($arrayfields['e.ref']['checked'])) print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"],"e.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['e.ref_customer']['checked'])) print_liste_field_titre($arrayfields['e.ref_customer']['label'], $_SERVER["PHP_SELF"],"e.ref_customer","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom", "", $param,'align="left"',$sortfield,$sortorder); + if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['e.date_delivery']['checked'])) print_liste_field_titre($arrayfields['e.date_delivery']['label'], $_SERVER["PHP_SELF"],"e.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['l.ref']['checked'])) print_liste_field_titre($arrayfields['l.ref']['label'], $_SERVER["PHP_SELF"],"l.ref","",$param, '',$sortfield,$sortorder); + if (! empty($arrayfields['l.date_delivery']['checked'])) print_liste_field_titre($arrayfields['l.date_delivery']['label'], $_SERVER["PHP_SELF"],"l.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['e.datec']['checked'])) print_liste_field_titre($arrayfields['e.datec']['label'],$_SERVER["PHP_SELF"],"e.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['e.tms']['checked'])) print_liste_field_titre($arrayfields['e.tms']['label'],$_SERVER["PHP_SELF"],"e.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['e.fk_statut']['checked'])) print_liste_field_titre($arrayfields['e.fk_statut']['label'],$_SERVER["PHP_SELF"],"e.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['l.fk_statut']['checked'])) print_liste_field_titre($arrayfields['l.fk_statut']['label'], $_SERVER["PHP_SELF"],"l.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $i=0; $var=true; $totalarray=array(); diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 21348a5c948..8de637df3cc 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -507,8 +507,11 @@ if ($step == 3 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print ''; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -752,8 +755,11 @@ if ($step == 4 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '
    '.$langs->trans("InformationOnSourceFile").'

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print ''; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -1219,8 +1225,11 @@ if ($step == 5 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '
    '.$langs->trans("InformationOnSourceFile").'

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print ''; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -1261,38 +1270,33 @@ if ($step == 5 && $datatoimport) // Do not import first lines print ''; - - // Do not import end lines - print ''; - + print '
    '.$langs->trans("InformationOnSourceFile").'
    '; - print $langs->trans("ImportFromLine"); + print $langs->trans("ImportFromToLine"); print ''; if ($action=='launchsimu') { - print ''; + print ''; print ''; print '   '.$langs->trans("Modify").''; } else { - print ''; + print ''; print $form->textwithpicto("", $langs->trans("SetThisValueTo2ToExcludeFirstLine")); } - print '
    '; - print $langs->trans("EndAtLineNb"); - print ''; + print ' - '; if ($action=='launchsimu') { - print ''; + print ''; print ''; print '   '.$langs->trans("Modify").''; } else { - print ''; + print ''; print $form->textwithpicto("", $langs->trans("KeepEmptyToGoToEndOfFile")); } print '
    '; print $langs->trans("KeysToUseForUpdates"); print ''; @@ -1304,7 +1308,7 @@ if ($step == 5 && $datatoimport) print '   '.$langs->trans("Modify").''; } else { print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%'); - print $form->textwithpicto("", $langs->trans("SelectColumnsOfYourFileForUpdateAttempt")); + print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt")); } /*echo '
    ';
     	print_r($objimport->array_import_updatekeys);
    @@ -1315,7 +1319,7 @@ if ($step == 5 && $datatoimport)
     
     	print '
    '; - print ''.$langs->trans("InformationOnTargetTables").''; + print ''.$langs->trans("InformationOnTargetTables").'
    '; print ''; //print ''; @@ -1643,8 +1647,11 @@ if ($step == 6 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '
    '.$langs->trans("InformationOnTargetTables").'

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print '
    '; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -1701,7 +1708,7 @@ if ($step == 6 && $datatoimport) print '
    '; - print ''.$langs->trans("InformationOnTargetTables").''; + print ''.$langs->trans("InformationOnTargetTables").'
    '; print '
    '.$langs->trans("InformationOnSourceFile").'
    '; //print ''; diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index 47b6fde9840..acbf407fd62 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -113,8 +113,10 @@ ExportDateFilter=YYYY, YYYYMM, YYYYMMDD : filters by one year/month/day
    YYYY+ ExportNumericFilter=NNNNN filters by one value
    NNNNN+NNNNN filters over a range of values
    < NNNNN filters by lower values
    > NNNNN filters by higher values ImportFromLine=Import starting from line number EndAtLineNb=End at line number +ImportFromToLine=Import line numbers (from - to) SetThisValueTo2ToExcludeFirstLine=For example, set this value to 3 to exclude the 2 first lines KeepEmptyToGoToEndOfFile=Keep this field empty to go up to the end of file +SelectPrimaryColumnsForUpdateAttempt=Select column(s) to use as primary key for update attempt ## filters SelectFilterFields=If you want to filter on some values, just input values here. FilteredFields=Filtered fields diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index 52ed6c9c969..5320e637316 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -103,7 +103,7 @@ $head[$h][1] = $title; $head[$h][2] = 'popularityprop'; $h++; -dol_fiche_head($head,'popularityprop',$langs->trans("Statistics")); +dol_fiche_head($head, 'popularityprop', $langs->trans("Statistics"), -1); // Array of liens to show @@ -136,7 +136,6 @@ if ($resql) $num = $db->num_rows($resql); $i = 0; - $var=True; while ($i < $num) { $objp = $db->fetch_object($resql); @@ -166,7 +165,6 @@ print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', print_liste_field_titre($langs->trans('NbOfQtyInProposals'), $_SERVER["PHP_SELF"], 'c', '', $param, 'align="right"', $sortfield, $sortorder); print "\n"; -$var=True; foreach($infoprod as $prodid => $vals) { // Multilangs @@ -186,8 +184,7 @@ foreach($infoprod as $prodid => $vals) } } - $var=!$var; - print ""; + print ""; print ''; + $out.= "\n"; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 271f87ab4a0..99b27c20822 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -219,10 +219,10 @@ class Form if (empty($notabletag)) $ret.=''; if (empty($notabletag)) $ret.=''; if (empty($notabletag)) $ret.='
    '.$langs->trans("InformationOnTargetTables").'
    '; if ($vals['type'] == 1) print img_object($langs->trans("ShowService"),"service"); else print img_object($langs->trans("ShowProduct"),"product"); diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index 13bc0fef186..8e3d1aa1985 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -121,10 +121,7 @@ $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s on p.rowid = s.fk_produc if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp"; $sql.= " WHERE p.entity IN (".getEntity('product', 1).")"; if ($search_categ) $sql.= " AND p.rowid = cp.fk_product"; // Join for the needed table to filter by categ -if ($sall) -{ - $sql.= " AND (p.ref LIKE '%".$db->escape($sall)."%' OR p.label LIKE '%".$db->escape($sall)."%' OR p.description LIKE '%".$db->escape($sall)."%' OR p.note LIKE '%".$db->escape($sall)."%')"; -} +if ($sall) $sql.=natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $all); // if the type is not 1, we show all products (type = 0,2,3) if (dol_strlen($type)) { @@ -137,41 +134,32 @@ if (dol_strlen($type)) $sql.= " AND p.fk_product_type <> '1'"; } } -if ($sref) $sql.= " AND p.ref LIKE '%".$sref."%'"; -if ($sbarcode) $sql.= " AND p.barcode LIKE '%".$sbarcode."%'"; -if ($snom) $sql.= " AND p.label LIKE '%".$db->escape($snom)."%'"; -if (! empty($tosell)) -{ - $sql.= " AND p.tosell = ".$tosell; -} -if (! empty($tobuy)) -{ - $sql.= " AND p.tobuy = ".$tobuy; -} -if (! empty($canvas)) -{ - $sql.= " AND p.canvas = '".$db->escape($canvas)."'"; -} -if($catid) -{ - $sql.= " AND cp.fk_categorie = ".$catid; -} -if ($fourn_id > 0) -{ - $sql.= " AND p.rowid = pf.fk_product AND pf.fk_soc = ".$fourn_id; -} +if ($sref) $sql.= natural_search('p.ref', $ref); +if ($sbarcode) $sql.= natural_search('p.barcode', $sbarcode); +if ($snom) $sql.= natural_search('p.label', $snom); +if (! empty($tosell)) $sql.= " AND p.tosell = ".$tosell; +if (! empty($tobuy)) $sql.= " AND p.tobuy = ".$tobuy; +if (! empty($canvas)) $sql.= " AND p.canvas = '".$db->escape($canvas)."'"; +if($catid) $sql.= " AND cp.fk_categorie = ".$catid; +if ($fourn_id > 0) $sql.= " AND p.rowid = pf.fk_product AND pf.fk_soc = ".$fourn_id; // Insert categ filter -if ($search_categ) -{ - $sql .= " AND cp.fk_categorie = ".$db->escape($search_categ); -} +if ($search_categ) $sql .= " AND cp.fk_categorie = ".$db->escape($search_categ); $sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql.= " p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock"; -if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; // Not used yet +if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; $sql.= $db->order($sortfield,$sortorder); -$sql.= $db->plimit($limit + 1, $offset); -$resql = $db->query($sql); +// Count total nb of records +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} + +$sql.= $db->plimit($limit + 1, $offset); + +$resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -197,31 +185,31 @@ if ($resql) llxHeader("", $texte, $helpurl); - if ($sref || $snom || $sall || GETPOST('search')) - { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products'); - } - else - { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products'); - } - - if (! empty($catid)) - { - print "
    "; - $c = new Categorie($db); - $c->fetch($catid); - $ways = $c->print_all_ways(' > ','product/reassort.php'); - print " > ".$ways[0]."
    \n"; - print "

    "; - } - print ''; print ''; print ''; print ''; print ''; + if ($sref || $snom || $sall || GETPOST('search')) + { + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); + } + else + { + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); + } + + if (! empty($catid)) + { + print "
    "; + $c = new Categorie($db); + $c->fetch($catid); + $ways = $c->print_all_ways(' > ','product/reassort.php'); + print " > ".$ways[0]."
    \n"; + print "

    "; + } + // Filter on categories $moreforfilter=''; if (! empty($conf->categorie->enabled)) @@ -264,32 +252,8 @@ if ($resql) print '
    '; print ''; - // Lignes des titres - print ""; - print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); - if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("StockLimit"), $_SERVER["PHP_SELF"], "p.seuil_stock_alerte",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); - // Details per warehouse - if (! empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context) - { - if ($nb_warehouse>1) { - foreach($warehouses_list as &$wh) { - print_liste_field_titre($wh['label'], '', '','','','align="right"'); - } - - } - } - if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy",$param,"",'align="right"',$sortfield,$sortorder); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; print ''; @@ -310,24 +274,47 @@ if ($resql) if ($virtualdiffersfromphysical) print ''; print ''; print ''; + print ''; print ''; print ''; - $var=True; + // Lignes des titres + print ""; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); + if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("StockLimit"), $_SERVER["PHP_SELF"], "p.seuil_stock_alerte",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); + // Details per warehouse + if (! empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context) + { + if ($nb_warehouse>1) { + foreach($warehouses_list as &$wh) { + print_liste_field_titre($wh['label'], '', '','','','align="right"'); + } + + } + } + if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); - $var=!$var; - print ''; + print ''; @@ -376,27 +363,17 @@ if ($resql) } print ''; print ''; - print ''; - print "\n"; + print ''; + print ''; + print "\n"; $i++; } print "
    '; print ''; print '   '; $searchpitco=$form->showFilterAndCheckAddButtons(0); print $searchpitco; print '
    '; - + print '
    '; $product=new Product($db); $product->fetch($objp->rowid); $product->load_stock(); - print $product->getNomUrl(1,'',16); //if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow")); print ''.$langs->trans("Movements").''.$product->LibStatut($objp->statut,5,0).''.$product->LibStatut($objp->tobuy,5,1).'
    '.$product->LibStatut($objp->tobuy,5,1).'
    "; print '
    '; + print ''; - if ($num > $conf->liste_limit) - { - if ($sref || $snom || $sall || GETPOST('search')) - { - print_barre_liste('', $page, "reassort.php", "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, ''); - } - else - { - print_barre_liste('', $page, "reassort.php", "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"")."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, ''); - } - } - $db->free($resql); } diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index 01285f09417..af1c6f2ec15 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -160,15 +160,17 @@ $sql.= " pb.batch, pb.eatby, pb.sellby,"; $sql.= " pl.eatby, pl.sellby"; if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('ps.reel IS NULL', '0', 'ps.reel').") < p.seuil_stock_alerte"; // Not used yet $sql.= $db->order($sortfield,$sortorder); + $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); } -$sql.= $db->plimit($limit + 1, $offset); -$resql = $db->query($sql); +$sql.= $db->plimit($limit + 1, $offset); + +$resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -194,13 +196,19 @@ if ($resql) llxHeader("",$title,$helpurl,$texte); + print '
    '; + print ''; + print ''; + print ''; + print ''; + if ($sref || $snom || $sall || GETPOST('search')) { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products'); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); } else { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products'); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); } if (! empty($catid)) @@ -213,12 +221,6 @@ if ($resql) print "
    "; } - print ''; - print ''; - print ''; - print ''; - print ''; - // Filter on categories $moreforfilter=''; if (! empty($conf->categorie->enabled)) @@ -255,26 +257,8 @@ if ($resql) print '
    '; print ''; - // Lignes des titres - print ""; - print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); - if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Warehouse"), $_SERVER["PHP_SELF"], "e.label",$param,"",'',$sortfield,$sortorder); - //print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Batch"), $_SERVER["PHP_SELF"], "pb.batch",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("EatByDate"), $_SERVER["PHP_SELF"], "pb.eatby",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("SellByDate"), $_SERVER["PHP_SELF"], "pb.sellby",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); - // TODO Add info of running suppliers/customers orders - //print_liste_field_titre($langs->trans("TheoreticalStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy","",$param,'align="right"',$sortfield,$sortorder); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; print ''; @@ -294,16 +278,35 @@ if ($resql) print ''; print ''; print ''; + print ''; print ''; print ''; + // Lignes des titres + print ""; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); + if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Warehouse"), $_SERVER["PHP_SELF"], "e.label",$param,"",'',$sortfield,$sortorder); + //print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Batch"), $_SERVER["PHP_SELF"], "pb.batch",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("EatByDate"), $_SERVER["PHP_SELF"], "pb.eatby",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("SellByDate"), $_SERVER["PHP_SELF"], "pb.sellby",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); + // TODO Add info of running suppliers/customers orders + //print_liste_field_titre($langs->trans("TheoreticalStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + $product_static=new Product($db); $warehousetmp=new Entrepot($db); - $var=True; while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); @@ -337,9 +340,7 @@ if ($resql) $warehousetmp->label=$objp->warehouse_ref; $warehousetmp->fk_parent=$objp->warehouse_parent; - $var=!$var; - - print ''; + print ''; // Ref print ''; print ''; print ''; + print ''; print "\n"; $i++; } diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 0bfd9048352..f31b7c9eb6e 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -149,18 +149,8 @@ if ($result) print '
    '; print '
    '; print ''; print '    '; $searchpitco=$form->showFilterAndCheckAddButtons(0); print $searchpitco; print '
    '; @@ -380,6 +381,7 @@ if ($resql) print ''.$langs->trans("Movements").''.$product_static->LibStatut($objp->statut,5,0).''.$product_static->LibStatut($objp->tobuy,5,1).'
    '."\n"; - print ""; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("LocationSummary"),$_SERVER["PHP_SELF"], "e.lieu","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stockqty",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("EstimatedStockValue"), $_SERVER["PHP_SELF"], "estimatedvalue",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("EstimatedStockValueSell"), $_SERVER["PHP_SELF"], "",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"], "e.statut",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'',$param,'',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; print ''; print ''; + + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("LocationSummary"),$_SERVER["PHP_SELF"], "e.lieu","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stockqty",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("EstimatedStockValue"), $_SERVER["PHP_SELF"], "estimatedvalue",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("EstimatedStockValueSell"), $_SERVER["PHP_SELF"], "",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"], "e.statut",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'',$param,'',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; if ($num) { diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 2910103e380..58bb6f6a3cb 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -236,8 +236,7 @@ if ($search_fk_user_creat) $sql.= natural_search("fk_user_creat",$search_fk_user if ($search_fk_user_modif) $sql.= natural_search("fk_user_modif",$search_fk_user_modif); if ($search_import_key) $sql.= natural_search("import_key",$search_import_key); - -if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); +if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); // Add where from extra fields foreach ($search_array_options as $key => $val) { @@ -342,6 +341,69 @@ if ($resql) print '
    '; print '
    '; print ''; @@ -183,6 +173,16 @@ if ($result) print '
    '."\n"; + // Fields title search + print ''; + if (! empty($arrayfields['t.entity']['checked'])) print ''; + if (! empty($arrayfields['t.batch']['checked'])) print ''; + if (! empty($arrayfields['t.fk_product']['checked'])) print ''; + if (! empty($arrayfields['t.eatby']['checked'])) print ''; + if (! empty($arrayfields['t.sellby']['checked'])) print ''; + if (! empty($arrayfields['t.fk_user_creat']['checked'])) print ''; + if (! empty($arrayfields['t.fk_user_modif']['checked'])) print ''; + if (! empty($arrayfields['t.import_key']['checked'])) print ''; + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['t.datec']['checked'])) + { + // Date creation + print ''; + } + if (! empty($arrayfields['t.tms']['checked'])) + { + // Date modification + print ''; + } + /*if (! empty($arrayfields['u.statut']['checked'])) + { + // Status + print ''; + }*/ + // Action column + print ''; + print ''."\n"; + // Fields title print ''; if (! empty($arrayfields['t.entity']['checked'])) print_liste_field_titre($arrayfields['t.entity']['label'],$_SERVER['PHP_SELF'],'t.entity','',$param,'',$sortfield,$sortorder); @@ -374,69 +436,6 @@ if ($resql) print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); print ''."\n"; - // Fields title search - print ''; - if (! empty($arrayfields['t.entity']['checked'])) print ''; - if (! empty($arrayfields['t.batch']['checked'])) print ''; - if (! empty($arrayfields['t.fk_product']['checked'])) print ''; - if (! empty($arrayfields['t.eatby']['checked'])) print ''; - if (! empty($arrayfields['t.sellby']['checked'])) print ''; - if (! empty($arrayfields['t.fk_user_creat']['checked'])) print ''; - if (! empty($arrayfields['t.fk_user_modif']['checked'])) print ''; - if (! empty($arrayfields['t.import_key']['checked'])) print ''; - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } - // Fields from hook - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['t.datec']['checked'])) - { - // Date creation - print ''; - } - if (! empty($arrayfields['t.tms']['checked'])) - { - // Date modification - print ''; - } - /*if (! empty($arrayfields['u.statut']['checked'])) - { - // Status - print ''; - }*/ - // Action column - print ''; - print ''."\n"; - $productlot = new Productlot($db); $i=0; diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 9185406a6ef..ded0feec881 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -403,7 +403,7 @@ $head[1][2] = 'replenishorders'; print load_fiche_titre($langs->trans('Replenishment'), '', 'title_generic.png'); -dol_fiche_head($head, 'replenish', '', 0, ''); +dol_fiche_head($head, 'replenish', '', -1, ''); print $langs->trans("ReplenishmentStatusDesc").'
    '."\n"; if ($usevirtualstock == 1) @@ -501,22 +501,8 @@ print '' ''. ''; -// Lines of title -print ''; -print_liste_field_titre('', $_SERVER["PHP_SELF"], ''); -print_liste_field_titre($langs->trans('Ref'), $_SERVER["PHP_SELF"], 'p.ref', $param, '', '', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', $param, '', '', $sortfield, $sortorder); -if (!empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans('Duration'), $_SERVER["PHP_SELF"], 'p.duration', $param, '', 'align="center"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('DesiredStock'), $_SERVER["PHP_SELF"], 'p.desiredstock', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('StockLimitShort'), $_SERVER["PHP_SELF"], 'p.seuil_stock_alerte', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($stocklabel, $_SERVER["PHP_SELF"], 'stock_physique', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('Ordered'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('StockToBuy'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('SupplierRef'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); -print "\n"; - // Lignes des champs de filtre -print ''; +print ''; print ''; print ''; print ''; @@ -532,6 +518,20 @@ print $searchpitco; print ''; print ''; +// Lines of title +print ''; +print_liste_field_titre('', $_SERVER["PHP_SELF"], ''); +print_liste_field_titre($langs->trans('Ref'), $_SERVER["PHP_SELF"], 'p.ref', $param, '', '', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', $param, '', '', $sortfield, $sortorder); +if (!empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans('Duration'), $_SERVER["PHP_SELF"], 'p.duration', $param, '', 'align="center"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('DesiredStock'), $_SERVER["PHP_SELF"], 'p.desiredstock', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('StockLimitShort'), $_SERVER["PHP_SELF"], 'p.seuil_stock_alerte', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($stocklabel, $_SERVER["PHP_SELF"], 'stock_physique', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('Ordered'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('StockToBuy'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('SupplierRef'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); +print "\n"; + $prod = new Product($db); $var = True; diff --git a/htdocs/product/stock/replenishorders.php b/htdocs/product/stock/replenishorders.php index 4986d7c524d..607e28165ed 100644 --- a/htdocs/product/stock/replenishorders.php +++ b/htdocs/product/stock/replenishorders.php @@ -97,7 +97,7 @@ $head[1][0] = DOL_URL_ROOT.'/product/stock/replenishorders.php'; $head[1][1] = $texte; $head[1][2] = 'replenishorders'; -dol_fiche_head($head, 'replenishorders', '', 0, ''); +dol_fiche_head($head, 'replenishorders', '', -1, ''); $commandestatic = new CommandeFournisseur($db); @@ -160,71 +160,9 @@ if ($resql) print ''; - print '
    '; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); + print ''; + $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + print $searchpitco; + print '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print ''; - print ''; - print ''; - print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); - print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - print $searchpitco; - print '
     
    '. - ''; - print_liste_field_titre( - $langs->trans('Ref'), - $_SERVER['PHP_SELF'], - 'cf.ref', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('Company'), - $_SERVER['PHP_SELF'], - 's.nom', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('Author'), - $_SERVER['PHP_SELF'], - 'u.login', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('AmountTTC'), - $_SERVER['PHP_SELF'], - 'cf.total_ttc', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('OrderCreation'), - $_SERVER['PHP_SELF'], - 'cf.date_creation', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('Status'), - $_SERVER['PHP_SELF'], - 'cf.fk_statut', - '', - '', - 'align="right"', - $sortfield, - $sortorder - ); - print ''. + print '
    '; - ''. + print ''. ''. @@ -246,20 +184,81 @@ if ($resql) ''. ''; - $var = true; + print ''; + print_liste_field_titre( + $langs->trans('Ref'), + $_SERVER['PHP_SELF'], + 'cf.ref', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('Company'), + $_SERVER['PHP_SELF'], + 's.nom', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('Author'), + $_SERVER['PHP_SELF'], + 'u.login', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('AmountTTC'), + $_SERVER['PHP_SELF'], + 'cf.total_ttc', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('OrderCreation'), + $_SERVER['PHP_SELF'], + 'cf.date_creation', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('Status'), + $_SERVER['PHP_SELF'], + 'cf.fk_statut', + '', + '', + 'align="right"', + $sortfield, + $sortorder + ); + print ''; + $userstatic = new User($db); while ($i < min($num,$conf->liste_limit)) { $obj = $db->fetch_object($resql); - $var = !$var; $showline = dolDispatchToDo($obj->rowid) && (!$sproduct || in_array($sproduct, getProducts($obj->rowid))); if ($showline) { $href = DOL_URL_ROOT . '/fourn/commande/card.php?id=' . $obj->rowid; - print ''. + print ''. // Ref ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; + if (! empty($conf->use_javascript_ajax)) { - $out.= '
    '. ''. '
    '. ''. diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index f7cb1c0bb5a..b43eb6450c1 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1948,7 +1948,7 @@ div.popuptab { padding-right: 5px; } div.tabsAction { - margin: 20px 0em 25px 0em; + margin: 20px 0em 20px 0em; padding: 0em 0em; text-align: right; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f83d5df0d50..2a393dee748 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1941,7 +1941,7 @@ div.tabBar table.tableforservicepart2:last-child { } div.tabsAction { - margin: 20px 0em 25px 0em; + margin: 20px 0em 20px 0em; padding: 0em 0em; text-align: right; } From 18e1e5b7806c67938c03391c9fabfd54ea97286f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 15:54:48 +0200 Subject: [PATCH 271/410] NEW Add "depends on" and "required by "into module informations --- htdocs/admin/modulehelp.php | 18 ++++++++++-------- htdocs/core/modules/modHRM.class.php | 5 ++++- htdocs/langs/en_US/admin.lang | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 5b428443248..3fe6addea2d 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -1,12 +1,5 @@ - * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2017 Laurent Destailleur - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2011 Juanjo Menent - * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2015 Raphaël Doursenaud +/* Copyright (C) 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 @@ -343,6 +336,15 @@ if ($mode == 'desc') if ($mode == 'feature') { + $text.='
    '.$langs->trans("DependsOn").': '; + if (count($objMod->requiredby)) $text.=join(',', $objMod->depends); + else $text.=$langs->trans("None"); + $text.='
    '.$langs->trans("RequiredBy").': '; + if (count($objMod->requiredby)) $text.=join(',', $objMod->requiredby); + else $text.=$langs->trans("None"); + + $text.='


    '; + $text.=''.$langs->trans("AddRemoveTabs").': '; if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs)) { diff --git a/htdocs/core/modules/modHRM.class.php b/htdocs/core/modules/modHRM.class.php index 5cbb282424a..74a0107aedb 100644 --- a/htdocs/core/modules/modHRM.class.php +++ b/htdocs/core/modules/modHRM.class.php @@ -52,7 +52,10 @@ class modHRM extends DolibarrModules $this->const_name = 'MAIN_MODULE_' . strtoupper($this->name); $this->special = 0; - // $this->picto = ''; + // Name of image file used for this module. + // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' + // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' + $this->picto='generic'; // define triggers $this->module_parts = array(); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index b3f43698843..1d16fefa959 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -425,6 +425,8 @@ Use3StepsApproval=By default, Purchase Orders need to be created and approved by UseDoubleApproval=Use a 3 steps approval when amount (without tax) is higher than... WarningPHPMail=WARNING: Some email providers (like Yahoo) does not allow you to send an email from another server than the Yahoo server if the email address used as a sender is your Yahoo email (like myemail@yahoo.com, myemail@yahoo.fr, ...). Your current setup use the server of the application to send email, so some recipients (the one compatible with the restrictive DMARC protocol), will ask Yahoo if they can accept your email and Yahoo will respond "no" because the server is not a server owned by Yahoo, so few of your sent Emails may not be accepted.
    If your Email provider (like Yahoo) has this restriction, you must change Email setup to choose the other method "SMTP server" and enter the SMTP server and credentials provided by your Email provider (ask your EMail provider to get SMTP credentials for your account). ClickToShowDescription=Click to show description +DependsOn=This module need the module(s) +RequiredBy=This module is required by module(s) # Modules Module0Name=Users & groups Module0Desc=Users / Employees and Groups management From da1427ef5411a38ce9956965d8e785c4999653cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 16:00:53 +0200 Subject: [PATCH 272/410] Work on 6.0 look and feel --- htdocs/comm/mailing/list.php | 29 +++++++------- htdocs/opensurvey/list.php | 52 ++++++++++++++---------- htdocs/resource/list.php | 39 +++++++++--------- htdocs/user/hierarchy.php | 16 ++++---- htdocs/user/index.php | 76 ++++++++++++++++++------------------ 5 files changed, 114 insertions(+), 98 deletions(-) diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php index 2d6fae37b98..622783d7ca5 100644 --- a/htdocs/comm/mailing/list.php +++ b/htdocs/comm/mailing/list.php @@ -122,18 +122,7 @@ if ($result) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"m.rowid",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Title"),$_SERVER["PHP_SELF"],"m.titre",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateCreation"),$_SERVER["PHP_SELF"],"m.date_creat",$param,"",'align="center"',$sortfield,$sortorder); - if (! $filteremail) print_liste_field_titre($langs->trans("NbOfEMails"),$_SERVER["PHP_SELF"],"m.nbemail",$param,"",'align="center"',$sortfield,$sortorder); - if (! $filteremail) print_liste_field_titre($langs->trans("DateLastSend"),$_SERVER["PHP_SELF"],"m.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); - else print_liste_field_titre($langs->trans("DateSending"),$_SERVER["PHP_SELF"],"mc.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],($filteremail?"mc.statut":"m.statut"),$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; print ''; @@ -151,8 +140,18 @@ if ($result) print ''; print "\n"; - $var=True; - + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"m.rowid",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Title"),$_SERVER["PHP_SELF"],"m.titre",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateCreation"),$_SERVER["PHP_SELF"],"m.date_creat",$param,"",'align="center"',$sortfield,$sortorder); + if (! $filteremail) print_liste_field_titre($langs->trans("NbOfEMails"),$_SERVER["PHP_SELF"],"m.nbemail",$param,"",'align="center"',$sortfield,$sortorder); + if (! $filteremail) print_liste_field_titre($langs->trans("DateLastSend"),$_SERVER["PHP_SELF"],"m.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); + else print_liste_field_titre($langs->trans("DateSending"),$_SERVER["PHP_SELF"],"mc.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],($filteremail?"mc.statut":"m.statut"),$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $email=new Mailing($db); while ($i < min($num,$limit)) @@ -161,7 +160,7 @@ if ($result) $var=!$var; - print ""; + print ""; print ''; print ''; diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php index 9a95797736d..203602bde6e 100644 --- a/htdocs/opensurvey/list.php +++ b/htdocs/opensurvey/list.php @@ -33,8 +33,9 @@ if (!$user->rights->opensurvey->read) accessforbidden(); $action=GETPOST('action'); $id=GETPOST('id','alpha'); $numsondage= $id; -$surveytitle=GETPOST('surveytitle'); -$status=GETPOST('status'); +$search_ref = GETPOST('search_ref', 'alpha'); +$surveytitle=GETPOST('surveytitle', 'alpha'); +$status=GETPOST('status', 'int'); //if (! isset($_POST['status']) && ! isset($_GET['status'])) $status='opened'; // If filter unknown, we choose 'opened' $sortfield = GETPOST("sortfield",'alpha'); @@ -61,6 +62,7 @@ if (GETPOST('button_removefilter')) { $status=''; $surveytitle=''; + $search_ref=''; } @@ -93,19 +95,8 @@ $moreforfilter = ''; print '
    '; print '
    '; print ''; print '
    '; print img_object($langs->trans("ShowEMail"),"email").' '.stripslashes($obj->rowid).''.$obj->titre.'
    '."\n"; -print ''; -print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.id_sondage",$param,"","",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Title"), $_SERVER["PHP_SELF"], "p.titre",$param,"","",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Type")); -print_liste_field_titre($langs->trans("Author"), $_SERVER["PHP_SELF"], "u.".$fieldtosortuser,$param,"","",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("NbOfVoters")); -print_liste_field_titre($langs->trans("ExpireDate"), $_SERVER["PHP_SELF"], "p.date_fin",$param,"",'align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Status"), $_SERVER["PHP_SELF"], "p.status",$param,"",'align="center"',$sortfield,$sortorder); -print_liste_field_titre(''); -print ''."\n"; - -print ''; -print ''; +print ''; +print ''; print ''; print ''; print ''; @@ -119,6 +110,17 @@ print $searchpitco; print ''; print ''."\n"; +print ''; +print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.id_sondage", $param,"","",$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Title"), $_SERVER["PHP_SELF"], "p.titre", $param,"","",$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Type")); +print_liste_field_titre($langs->trans("Author"), $_SERVER["PHP_SELF"], "u.".$fieldtosortuser, $param,"","",$sortfield,$sortorder); +print_liste_field_titre($langs->trans("NbOfVoters"), $_SERVER["PHP_SELF"], "", $param,"",'align="right"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("ExpireDate"), $_SERVER["PHP_SELF"], "p.date_fin", $param,"",'align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Status"), $_SERVER["PHP_SELF"], "p.status", $param,"",'align="center"',$sortfield,$sortorder); +print_liste_field_titre(''); +print ''."\n"; + $sql = "SELECT p.id_sondage, p.fk_user_creat, p.format, p.date_fin, p.status, p.titre, p.nom_admin,"; $sql.= " u.login, u.firstname, u.lastname"; $sql.= " FROM ".MAIN_DB_PREFIX."opensurvey_sondage as p"; @@ -133,9 +135,20 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql.= " WHERE p.entity = ".getEntity('survey',1); if ($status == 'expired') $sql.=" AND date_fin < '".$db->idate($now)."'"; if ($status == 'opened') $sql.=" AND date_fin >= '".$db->idate($now)."'"; -if ($surveytitle) $sql.=" AND titre LIKE '%".$db->escape($surveytitle)."%'"; +if ($search_ref) $sql.=natural_search("p.id_sondage", $search_ref); +if ($surveytitle) $sql.=natural_search("p.titre", $surveytitle); + $sql.= $db->order($sortfield,$sortorder); -$sql.= $db->plimit($conf->liste_limit+1, $offset); + +// Count total nb of records +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} + +$sql.= $db->plimit($limit + 1,$offset); $resql=$db->query($sql); if (! $resql) dol_print_error($db); @@ -159,8 +172,7 @@ while ($i < min($num,$limit)) $opensurvey_static->id=$obj->id_sondage; $opensurvey_static->status=$obj->status; - $var=!$var; - print ''; + print ''; print ''; - print''."\n"; + print''."\n"; print ''; print ''; - // Activate preview tab on element card - if (class_exists("Imagick")) - { - print ''; - print ''; - print ''; - } - // First day for weeks print ''; print ""; - // Activate preview tab on element card - if (class_exists("Imagick")) - { - - print '"; - print ''; - print ""; - } - // First day for weeks print '
    '; print ''.img_picto('','object_opensurvey').' '.$obj->id_sondage.''; print ''.dol_htmlentities($obj->titre).''; @@ -184,7 +196,7 @@ while ($i < min($num,$limit)) print ''.$nbuser.''.$nbuser.''.dol_print_date($db->jdate($obj->date_fin),'day'); if ($db->jdate($obj->date_fin) < time()) { print ' ('.$langs->trans("Expired").')'; } diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 2c97b68f7ed..5a3d5390bb0 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -194,25 +194,7 @@ $moreforfilter = ''; print '
    '; print ''."\n"; -print ''; -if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"t.code","",$param,"",$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - -print ''; +print ''; if (! empty($arrayfields['t.ref']['checked'])) { print ''; print "\n"; +print ''; +if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"t.code","",$param,"",$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + + if ($ret) { foreach ($object->lines as $resource) diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php index 888d4ca5317..734b1aa0d14 100644 --- a/htdocs/user/hierarchy.php +++ b/htdocs/user/hierarchy.php @@ -144,14 +144,8 @@ print ''; -print ''; -print_liste_field_titre($langs->trans("HierarchicView")); -print_liste_field_titre('',$_SERVER['PHP_SELF'],"",'',"",'align="center"'); -print_liste_field_titre($langs->trans("Status"),$_SERVER['PHP_SELF'],"",'',"",'align="right"'); -print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','','','','maxwidthsearch '); -print ''; -print ''; +print ''; print ''; print ''; // Status @@ -164,6 +158,14 @@ print $searchpitco; print ''; print ''; +print ''; +print_liste_field_titre($langs->trans("HierarchicView")); +print_liste_field_titre('',$_SERVER['PHP_SELF'],"",'',"",'align="center"'); +print_liste_field_titre($langs->trans("Status"),$_SERVER['PHP_SELF'],"",'',"",'align="right"'); +print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','','','','maxwidthsearch '); +print ''; + + $nbofentries=(count($data) - 1); if ($nbofentries > 0) diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 60defe580a7..3e1da6a7431 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -174,6 +174,7 @@ if (empty($reshook)) * View */ +$user2=new User($db); $buttonviewhierarchy=''; @@ -315,43 +316,8 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '; @@ -255,6 +237,25 @@ print $searchpitco; print '
      
    '."\n"; -print ''; -if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($langs->trans("Login"),$_SERVER['PHP_SELF'],"u.login",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.lastname']['checked'])) print_liste_field_titre($langs->trans("Lastname"),$_SERVER['PHP_SELF'],"u.lastname",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.firstname']['checked'])) print_liste_field_titre($langs->trans("FirstName"),$_SERVER['PHP_SELF'],"u.firstname",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.gender']['checked'])) print_liste_field_titre($langs->trans("Gender"),$_SERVER['PHP_SELF'],"u.gender",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.employee']['checked'])) print_liste_field_titre($langs->trans("Employee"),$_SERVER['PHP_SELF'],"u.employee",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.accountancy_code']['checked'])) print_liste_field_titre($langs->trans("AccountancyCode"),$_SERVER['PHP_SELF'],"u.accountancy_code",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.email']['checked'])) print_liste_field_titre($langs->trans("EMail"),$_SERVER['PHP_SELF'],"u.email",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.fk_soc']['checked'])) print_liste_field_titre($langs->trans("Company"),$_SERVER['PHP_SELF'],"u.fk_soc",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.entity']['checked'])) print_liste_field_titre($langs->trans("Entity"),$_SERVER['PHP_SELF'],"u.entity",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.fk_user']['checked'])) print_liste_field_titre($langs->trans("HierarchicalResponsible"),$_SERVER['PHP_SELF'],"u.fk_user",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.datelastlogin']['checked'])) print_liste_field_titre($langs->trans("LastConnexion"),$_SERVER['PHP_SELF'],"u.datelastlogin",$param,"",'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['u.datepreviouslogin']['checked'])) print_liste_field_titre($langs->trans("PreviousConnexion"),$_SERVER['PHP_SELF'],"u.datepreviouslogin",$param,"",'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['u.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"u.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['u.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"u.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['u.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"u.statut","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - // Search bar -print ''; +print ''; if (! empty($arrayfields['u.login']['checked'])) { print ''; @@ -459,7 +425,43 @@ print ''; print "\n"; -$user2=new User($db); + +print ''; +if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($langs->trans("Login"),$_SERVER['PHP_SELF'],"u.login",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.lastname']['checked'])) print_liste_field_titre($langs->trans("Lastname"),$_SERVER['PHP_SELF'],"u.lastname",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.firstname']['checked'])) print_liste_field_titre($langs->trans("FirstName"),$_SERVER['PHP_SELF'],"u.firstname",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.gender']['checked'])) print_liste_field_titre($langs->trans("Gender"),$_SERVER['PHP_SELF'],"u.gender",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.employee']['checked'])) print_liste_field_titre($langs->trans("Employee"),$_SERVER['PHP_SELF'],"u.employee",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.accountancy_code']['checked'])) print_liste_field_titre($langs->trans("AccountancyCode"),$_SERVER['PHP_SELF'],"u.accountancy_code",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.email']['checked'])) print_liste_field_titre($langs->trans("EMail"),$_SERVER['PHP_SELF'],"u.email",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.fk_soc']['checked'])) print_liste_field_titre($langs->trans("Company"),$_SERVER['PHP_SELF'],"u.fk_soc",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.entity']['checked'])) print_liste_field_titre($langs->trans("Entity"),$_SERVER['PHP_SELF'],"u.entity",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.fk_user']['checked'])) print_liste_field_titre($langs->trans("HierarchicalResponsible"),$_SERVER['PHP_SELF'],"u.fk_user",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.datelastlogin']['checked'])) print_liste_field_titre($langs->trans("LastConnexion"),$_SERVER['PHP_SELF'],"u.datelastlogin",$param,"",'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['u.datepreviouslogin']['checked'])) print_liste_field_titre($langs->trans("PreviousConnexion"),$_SERVER['PHP_SELF'],"u.datepreviouslogin",$param,"",'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['u.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"u.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['u.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"u.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['u.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"u.statut","",$param,'align="center"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + + $i = 0; while ($i < min($num,$limit)) From 979bcd3a9b225c7e7e6b672a4fb8b6ea390f2240 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 11:39:12 +0200 Subject: [PATCH 273/410] NEW Can add a background image on login page --- htdocs/admin/company.php | 40 ++-- htdocs/admin/ihm.php | 181 ++++++++++++++++-- htdocs/cashdesk/index.php | 2 +- htdocs/cashdesk/tpl/ticket.tpl.php | 2 +- htdocs/core/lib/files.lib.php | 2 +- htdocs/core/lib/security2.lib.php | 4 +- htdocs/core/menus/standard/auguria.lib.php | 2 +- htdocs/core/menus/standard/eldy.lib.php | 4 +- htdocs/core/tpl/login.tpl.php | 28 ++- htdocs/core/tpl/passwordforgotten.tpl.php | 26 +-- .../mycompany/background_computer_coffee.jpg | Bin 0 -> 385205 bytes htdocs/langs/en_US/admin.lang | 2 + htdocs/margin/tabs/productMargins.php | 2 +- htdocs/opensurvey/fonctions.php | 2 +- htdocs/product/document.php | 3 +- htdocs/product/fournisseurs.php | 5 +- htdocs/product/info.php | 3 +- htdocs/product/note.php | 2 +- htdocs/product/price.php | 3 +- htdocs/product/stock/product.php | 3 +- htdocs/public/members/new.php | 4 +- htdocs/public/paybox/newpayment.php | 4 +- htdocs/public/paypal/newpayment.php | 4 +- htdocs/theme/eldy/style.css.php | 17 +- htdocs/theme/md/style.css.php | 16 +- htdocs/user/passwordforgotten.php | 4 +- htdocs/viewimage.php | 4 +- 27 files changed, 270 insertions(+), 99 deletions(-) create mode 100644 htdocs/install/doctemplates/mycompany/background_computer_coffee.jpg diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 0f8efb23da0..d73f23d0ef7 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; @@ -51,8 +52,6 @@ $error=0; if ( ($action == 'update' && empty($_POST["cancel"])) || ($action == 'updateedit') ) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $tmparray=getCountry(GETPOST('country_id','int'),'all',$db,$langs,0); if (! empty($tmparray['id'])) { @@ -76,21 +75,23 @@ if ( ($action == 'update' && empty($_POST["cancel"])) dolibarr_set_const($db, "MAIN_INFO_SOCIETE_WEB",$_POST["web"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOTE",$_POST["note"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_GENCOD",$_POST["barcode"],'chaine',0,'',$conf->entity); - if ($_FILES["logo"]["tmp_name"]) + + $varforimage='logo'; $dirforimage=$conf->mycompany->dir_output.'/logos/'; + if ($_FILES[$varforimage]["tmp_name"]) { - if (preg_match('/([^\\/:]+)$/i',$_FILES["logo"]["name"],$reg)) + if (preg_match('/([^\\/:]+)$/i',$_FILES[$varforimage]["name"],$reg)) { $original_file=$reg[1]; $isimage=image_format_supported($original_file); if ($isimage >= 0) { - dol_syslog("Move file ".$_FILES["logo"]["tmp_name"]." to ".$conf->mycompany->dir_output.'/logos/'.$original_file); - if (! is_dir($conf->mycompany->dir_output.'/logos/')) + dol_syslog("Move file ".$_FILES[$varforimage]["tmp_name"]." to ".$dirforimage.$original_file); + if (! is_dir($dirforimage)) { - dol_mkdir($conf->mycompany->dir_output.'/logos/'); + dol_mkdir($dirforimage); } - $result=dol_move_uploaded_file($_FILES["logo"]["tmp_name"],$conf->mycompany->dir_output.'/logos/'.$original_file,1,0,$_FILES['logo']['error']); + $result=dol_move_uploaded_file($_FILES[$varforimage]["tmp_name"],$dirforimage.$original_file,1,0,$_FILES[$varforimage]['error']); if ($result > 0) { dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO",$original_file,'chaine',0,'',$conf->entity); @@ -101,8 +102,8 @@ if ( ($action == 'update' && empty($_POST["cancel"])) // Create thumbs //$object->addThumbs($newfile); // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... - // Used on logon for example - $imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.$original_file, $maxwidthsmall, $maxheightsmall, '_small', $quality); + // Create small thumb, Used on logon for example + $imgThumbSmall = vignette($dirforimage.$original_file, $maxwidthsmall, $maxheightsmall, '_small', $quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg)) { $imgThumbSmall = $reg[1]; // Save only basename @@ -110,9 +111,8 @@ if ( ($action == 'update' && empty($_POST["cancel"])) } else dol_syslog($imgThumbSmall); - // Create mini thumbs for company (Ratio is near 16/9) - // Used on menu or for setup page for example - $imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.$original_file, $maxwidthmini, $maxheightmini, '_mini', $quality); + // Create mini thumb, Used on menu or for setup page for example + $imgThumbMini = vignette($dirforimage.$original_file, $maxwidthmini, $maxheightmini, '_mini', $quality); if (image_format_supported($imgThumbMini) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg)) { $imgThumbMini = $reg[1]; // Save only basename @@ -143,6 +143,7 @@ if ( ($action == 'update' && empty($_POST["cancel"])) } } } + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_MANAGERS",$_POST["MAIN_INFO_SOCIETE_MANAGERS"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_CAPITAL",$_POST["capital"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_FORME_JURIDIQUE",$_POST["forme_juridique_code"],'chaine',0,'',$conf->entity); @@ -196,7 +197,7 @@ if ( ($action == 'update' && empty($_POST["cancel"])) } } -if ($action == 'addthumb') +if ($action == 'addthumb') // Regenerate thumbs { if (file_exists($conf->mycompany->dir_output.'/logos/'.$_GET["file"])) { @@ -208,7 +209,7 @@ if ($action == 'addthumb') // Create thumbs //$object->addThumbs($newfile); // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... - // Used on logon for example + // Create small thumb. Used on logon for example $imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthsmall, $maxheightsmall, '_small',$quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg)) { @@ -217,8 +218,7 @@ if ($action == 'addthumb') } else dol_syslog($imgThumbSmall); - // Create mini thumbs for company (Ratio is near 16/9) - // Used on menu or for setup page for example + // Create mini thumbs. Used on menu or for setup page for example $imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthmini, $maxheightmini, '_mini',$quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg)) { @@ -300,7 +300,7 @@ if ($action == 'edit' || $action == 'updateedit') });'; print ''."\n"; - print '
    '; + print ''; print ''; print ''; $var=true; @@ -383,7 +383,7 @@ if ($action == 'edit' || $action == 'updateedit') print ''.img_delete($langs->trans("Delete")).''; if (file_exists($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { print '   '; - print ''; + print ''; } } else { print ''; @@ -775,7 +775,7 @@ else } else if ($mysoc->logo_mini && is_file($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { - print ''; + print ''; } else { diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 83f6701e2a1..ff3bb89946b 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -26,6 +26,8 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; @@ -70,6 +72,26 @@ if (GETPOST('cancel')) $action=''; } +if ($action == 'removebackgroundlogin' && ! empty($conf->global->MAIN_LOGIN_BACKGROUND)) +{ + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $logofile=$conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND; + dol_delete_file($logofile); + dolibarr_del_const($db, "MAIN_LOGIN_BACKGROUND",$conf->entity); + $mysoc->logo=''; + + /*$logosmallfile=$conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small; + dol_delete_file($logosmallfile); + dolibarr_del_const($db, "MAIN_INFO_SOCIETE_LOGO_SMALL",$conf->entity); + $mysoc->logo_small=''; + + $logominifile=$conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini; + dol_delete_file($logominifile); + dolibarr_del_const($db, "MAIN_INFO_SOCIETE_LOGO_MINI",$conf->entity); + $mysoc->logo_mini='';*/ +} + if ($action == 'update') { dolibarr_set_const($db, "MAIN_LANG_DEFAULT", $_POST["main_lang_default"],'chaine',0,'',$conf->entity); @@ -123,6 +145,78 @@ if ($action == 'update') // This one is not always defined if (isset($_POST["MAIN_USE_PREVIEW_TABS"])) dolibarr_set_const($db, "MAIN_USE_PREVIEW_TABS", $_POST["MAIN_USE_PREVIEW_TABS"],'chaine',0,'',$conf->entity); + $varforimage='imagebackground'; $dirforimage=$conf->mycompany->dir_output.'/logos/'; + if ($_FILES[$varforimage]["tmp_name"]) + { + if (preg_match('/([^\\/:]+)$/i',$_FILES[$varforimage]["name"],$reg)) + { + $original_file=$reg[1]; + + $isimage=image_format_supported($original_file); + if ($isimage >= 0) + { + dol_syslog("Move file ".$_FILES[$varforimage]["tmp_name"]." to ".$dirforimage.$original_file); + if (! is_dir($dirforimage)) + { + dol_mkdir($dirforimage); + } + $result=dol_move_uploaded_file($_FILES[$varforimage]["tmp_name"],$dirforimage.$original_file,1,0,$_FILES[$varforimage]['error']); + if ($result > 0) + { + dolibarr_set_const($db, "MAIN_LOGIN_BACKGROUND",$original_file,'chaine',0,'',$conf->entity); + + // Create thumbs of logo (Note that PDF use original file and not thumbs) + /* + if ($isimage > 0) + { + // Create thumbs + //$object->addThumbs($newfile); // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... + + // Create small thumb, Used on logon for example + $imgThumbSmall = vignette($dirforimage.$original_file, $maxwidthsmall, $maxheightsmall, '_small', $quality); + if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg)) + { + $imgThumbSmall = $reg[1]; // Save only basename + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_SMALL",$imgThumbSmall,'chaine',0,'',$conf->entity); + } + else dol_syslog($imgThumbSmall); + + // Create mini thumb, Used on menu or for setup page for example + $imgThumbMini = vignette($dirforimage.$original_file, $maxwidthmini, $maxheightmini, '_mini', $quality); + if (image_format_supported($imgThumbMini) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg)) + { + $imgThumbMini = $reg[1]; // Save only basename + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_MINI",$imgThumbMini,'chaine',0,'',$conf->entity); + } + else dol_syslog($imgThumbMini); + } + else dol_syslog("ErrorImageFormatNotSupported",LOG_WARNING); + */ + } + else if (preg_match('/^ErrorFileIsInfectedWithAVirus/',$result)) + { + $error++; + $langs->load("errors"); + $tmparray=explode(':',$result); + setEventMessages($langs->trans('ErrorFileIsInfectedWithAVirus',$tmparray[1]), null, 'errors'); + } + else + { + $error++; + setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors'); + } + } + else + { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); + } + } + } + + + $_SESSION["mainmenu"]=""; // Le gestionnaire de menu a pu changer header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup"); @@ -152,7 +246,7 @@ if ($action == 'edit') // Edit //WYSIWYG Editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - print ''; + print ''; print ''; print ''; @@ -160,7 +254,7 @@ if ($action == 'edit') // Edit print '
    '; print '
    '; - print ''; + print ''; print ''; print ''; @@ -315,14 +409,6 @@ if ($action == 'edit') // Edit print ''; print ''; - // Message on login page - print ''."\n"; - // Message of the day on home page print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("Language").' 
     
    '.$langs->trans("MessageLogin").''; - - $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); - $doleditor->Create(); - - print '
    '.$langs->trans("MessageOfDay").''; @@ -333,6 +419,40 @@ if ($action == 'edit') // Edit print '
    '."\n"; + print '
    '; + + // Other + print ''; + print ''; + print ''; + print ''; + + // Message on login page + print ''."\n"; + + // Logo + $var=!$var; + print ''; + + print '
    '.$langs->trans("LoginPage").' 
    '.$langs->trans("MessageLogin").''; + $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); + $doleditor->Create(); + print '
    '; + print '
    '; + print ''; + print ''; + if (! empty($conf->global->MAIN_LOGIN_BACKGROUND)) { + print ''.img_delete($langs->trans("Delete")).''; + if (file_exists($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) { + print '   '; + print ''; + } + } else { + print ''; + } + print '
    '; + print '
    '."\n"; + print '
    '; print ''; @@ -346,7 +466,7 @@ else // Show { // Language print ''; - print ''; + print ''; print ''; - // Message login - print ''."\n"; - // Message of the day print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").' 
    '.$langs->trans("Language").' 
    '.$langs->trans("DefaultLanguage").''; $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); @@ -486,12 +606,6 @@ else // Show print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); print '
    '.$langs->trans("MessageLogin").''; - if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); - else print ' '; - print '
    '.$langs->trans("MessageOfDay").''; if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); @@ -500,6 +614,39 @@ else // Show print '
    '."\n"; + print '
    '; + + // Login page + print ''; + print ''; + + // Message login + print ''."\n"; + + // Background login + // Logo + $var=!$var; + print ''; + + print '
    '.$langs->trans("LoginPage").' 
    '.$langs->trans("MessageLogin").''; + if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); + else print ' '; + print '
    '.$langs->trans("BackgroundImageLogin").''; + print '
    '; + print $conf->global->MAIN_LOGIN_BACKGROUND; + print '
    '; + // It offers the generation of the thumbnail if it does not exist + if ($conf->global->MAIN_LOGIN_BACKGROUND && is_file($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) + { + print ''; + } + else + { + print ''; + } + print '
    '; + print '
    '."\n"; + print '
    '; print ''.$langs->trans("Modify").''; print '
    '; diff --git a/htdocs/cashdesk/index.php b/htdocs/cashdesk/index.php index 9a61a50b38a..8f6af8b6d4d 100644 --- a/htdocs/cashdesk/index.php +++ b/htdocs/cashdesk/index.php @@ -63,7 +63,7 @@ top_htmlhead('','',0,0,'',$arrayofcss); logo_small)) { - print 'Logo company'; + print 'Logo company'; } else { diff --git a/htdocs/cashdesk/tpl/ticket.tpl.php b/htdocs/cashdesk/tpl/ticket.tpl.php index 78ce86f45f7..40be470c429 100644 --- a/htdocs/cashdesk/tpl/ticket.tpl.php +++ b/htdocs/cashdesk/tpl/ticket.tpl.php @@ -37,7 +37,7 @@ $object->fetch($facid);

    name; ?>
    diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 1cb4da03488..0d4c1dff71e 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1590,7 +1590,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $relative_original_file = $original_file; // Wrapping for some images - if ($modulepart == 'companylogo' && !empty($conf->mycompany->dir_output)) + if (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output)) { $accessallowed=1; $original_file=$conf->mycompany->dir_output.'/logos/'.$original_file; diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index fc05e2c9194..cadf133169d 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -227,11 +227,11 @@ function dol_loginfunction($langs,$conf,$mysoc) if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_small); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('thumbs/'.$mysoc->logo_small); } elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode($mysoc->logo); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode($mysoc->logo); $width=128; } elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png')) diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 2c2d2c5ec63..e95359e5683 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -257,7 +257,7 @@ function print_left_auguria_menu($db,$menu_array_before,$menu_array_after,&$tabM $mysoc->logo_mini=$conf->global->MAIN_INFO_SOCIETE_LOGO_MINI; if (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_mini); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('thumbs/'.$mysoc->logo_mini); } else { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 178f1ca9db7..ccf6902a289 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -466,7 +466,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $mysoc->logo_mini=$conf->global->MAIN_INFO_SOCIETE_LOGO_MINI; if (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_mini); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('thumbs/'.$mysoc->logo_mini); } else { @@ -478,7 +478,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu print '

    '; print ''; print ''; print ''; print '
    '."\n"; diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index e0aa28ce2d6..a23d14a979d 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -45,7 +45,7 @@ print top_htmlhead('', $titleofloginpage, 0, 0, $arrayofjs, array(), 0, $disable ?> - +global->MAIN_LOGIN_BACKGROUND)?'':' style="background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode($conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>> dol_use_jmobile)) { ?> -
    +
     
    '.$langs->trans("UsePreviewTabs").''; - print $form->selectyesno('MAIN_USE_PREVIEW_TABS',isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0,1); - print ' 
    '.$langs->trans("WeekStartOnDay").''; print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1'),'MAIN_START_WEEK',0); @@ -532,16 +519,6 @@ else // Show print ' 
    '.$langs->trans("UsePreviewTabs").''; - print yn(isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0)." 
    '.$langs->trans("WeekStartOnDay").''; print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index f853e88a0df..c5fe89593b6 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -752,6 +752,8 @@ if ($action == 'create') print '
    '; print '

    '; + + print ''; // Related company @@ -1184,7 +1186,7 @@ if ($id > 0) } else { - dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); + dol_fiche_head($head, 'card', $langs->trans("Action"), -1, 'action'); // Clone event @@ -1255,6 +1257,8 @@ if ($id > 0) dol_banner_tab($object, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', $morehtmlref); + print '
    '; + print '
    '; // Affichage fiche action en mode visu @@ -1345,6 +1349,7 @@ if ($id > 0) print '
    '; + print '
    '; print '
    '; if ($conf->societe->enabled) @@ -1380,21 +1385,6 @@ if ($id > 0) } print ''; } - - // Project - /* - if (! empty($conf->projet->enabled)) - { - print ''; - } - */ // Priority print '
    '.$langs->trans("Project").''; - if ($object->fk_project) - { - $project=new Project($db); - $project->fetch($object->fk_project); - print $project->getNomUrl(1,'',1); - } - print '
    '.$langs->trans("Priority").''; @@ -1423,7 +1413,9 @@ if ($id > 0) //Extra field if (empty($reshook) && ! empty($extrafields->attribute_label)) { - print '

    '; + print '

    '; + print '
    '; + print '
    '; foreach($extrafields->attribute_label as $key=>$label) { if (isset($_POST["options_" . $key])) { @@ -1443,6 +1435,8 @@ if ($id > 0) print '
    '; } + print ''; + dol_fiche_end(); } diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php index 241843623c2..3edc08d87cb 100644 --- a/htdocs/comm/action/document.php +++ b/htdocs/comm/action/document.php @@ -121,7 +121,7 @@ if ($object->id > 0) $now=dol_now(); $delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60; - dol_fiche_head($head, 'documents', $langs->trans("Action"),0,'action'); + dol_fiche_head($head, 'documents', $langs->trans("Action"), -1, 'action'); $linkback = img_picto($langs->trans("BackToList"),'object_list','class="hideonsmartphone pictoactionview"'); $linkback.= ''.$langs->trans("BackToList").''; @@ -164,6 +164,8 @@ if ($object->id > 0) dol_banner_tab($object, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', $morehtmlref); + print '
    '; + print '
    '; // Affichage fiche action en mode visu @@ -236,9 +238,6 @@ if ($object->id > 0) print '
    '; - - print '
    '; - print ''; // Construit liste des fichiers @@ -255,7 +254,9 @@ if ($object->id > 0) print '
    '; - dol_fiche_end(); + print '
    '; + + dol_fiche_end(); $modulepart = 'actions'; diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 13fb3d9624f..5d9c84a22b6 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1332,7 +1332,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($user->rights->agenda->allactions->create || (($event->authorid == $user->id || $event->userownerid == $user->id) && $user->rights->agenda->myactions->create)) { - $cssclass.= " movable"; + $cssclass.= " movable cursormove"; }else{ $cssclass.= " unmovable"; } diff --git a/htdocs/comm/action/info.php b/htdocs/comm/action/info.php index 2ad3f424b12..7bee5550453 100644 --- a/htdocs/comm/action/info.php +++ b/htdocs/comm/action/info.php @@ -59,7 +59,7 @@ $object->fetch($id); $object->info($object->id); $head=actions_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("Action"),0,'action'); +dol_fiche_head($head, 'info', $langs->trans("Action"), -1, 'action'); $linkback = img_picto($langs->trans("BackToList"),'object_list','class="hideonsmartphone pictoactionview"'); $linkback.= '
    '.$langs->trans("BackToList").''; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 9b70ee36ace..444669a6f49 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1516,7 +1516,7 @@ if ($action == 'create') // Public note print '
    ' . $langs->trans('NotePublic') . '' . $langs->trans('NotePublic') . ''; $note_public = $object->getDefaultCreateValueFor('note_public', (is_object($objectsrc)?$objectsrc->note_public:null)); $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); @@ -1526,7 +1526,7 @@ if ($action == 'create') if (empty($user->societe_id)) { print '
    ' . $langs->trans('NotePrivate') . '' . $langs->trans('NotePrivate') . ''; $note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc))?$objectsrc->note_private:null)); $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); diff --git a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php index 315293281cc..7c3d6ab4e7f 100644 --- a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php @@ -223,7 +223,7 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes $stringtoshow.=' '.$langs->trans("AmountOfBillsByMonthHT"); $stringtoshow.='
    '; $stringtoshow.=$langs->trans("Year").' '; - $stringtoshow.=''; + $stringtoshow.=''; $stringtoshow.=''; $stringtoshow.=''; if ($shownb && $showtot) diff --git a/htdocs/core/boxes/box_lastlogin.php b/htdocs/core/boxes/box_lastlogin.php index 7211877a593..05bd3043b0a 100644 --- a/htdocs/core/boxes/box_lastlogin.php +++ b/htdocs/core/boxes/box_lastlogin.php @@ -79,7 +79,7 @@ class box_lastlogin extends ModeleBoxes ); $this->info_box_contents[$line][1] = array( 'td' => '', - 'text' => $user->getNomUrl(1), + 'text' => $user->getNomUrl(-1), 'asis' => 1 ); diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index c016741cb39..39f39524b41 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -247,25 +247,26 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" $s=dol_trunc($head['text'],isset($head['limit'])?$head['limit']:$MAXLENGTHBOX); $out.= $s; } - $out.= ' '; - - $sublink=''; - if (! empty($head['sublink'])) $sublink.= ''; - if (! empty($head['subpicto'])) $sublink.= img_picto($head['subtext'], $head['subpicto'], 'class="'.(empty($head['subclass'])?'':$head['subclass']).'" id="idsubimg'.$this->boxcode.'"'); - if (! empty($head['sublink'])) $sublink.= ''; + $out.= '
    '; + $sublink=''; + if (! empty($head['sublink'])) $sublink.= ''; + if (! empty($head['subpicto'])) $sublink.= img_picto($head['subtext'], $head['subpicto'], 'class="'.(empty($head['subclass'])?'':$head['subclass']).'" id="idsubimg'.$this->boxcode.'"'); + if (! empty($head['sublink'])) $sublink.= ''; + + $out.= ''; $out.=$sublink; // The image must have the class 'boxhandle' beause it's value used in DOM draggable objects to define the area used to catch the full object - $out.= img_picto($langs->trans("MoveBox",$this->box_id),'grip_title','class="boxhandle hideonsmartphone" style="cursor:move;"'); - $out.= img_picto($langs->trans("CloseBox",$this->box_id),'close_title','class="boxclose" rel="x:y" style="cursor:pointer;" id="imgclose'.$this->box_id.'"'); + $out.= img_picto($langs->trans("MoveBox",$this->box_id),'grip_title','class="boxhandle hideonsmartphone cursormove"'); + $out.= img_picto($langs->trans("CloseBox",$this->box_id),'close_title','class="boxclose cursorpointer" rel="x:y" id="imgclose'.$this->box_id.'"'); $label=$head['text']; if (! empty($head['graph'])) $label.=' ('.$langs->trans("Graph").')'; $out.= ''; $out.= '
    '; } - $out.= '
    '; - else $ret.='
    '; - $ret.=''; + //else $ret.='
    '; + $ret.=''; if (preg_match('/ckeditor|textarea/',$typeofdata) && empty($notabletag)) $ret.='
    '."\n"; - $ret.=''; + $ret.=''; if (empty($notabletag)) $ret.='
    '."\n"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ea92fb5a63b..6028f9bcabc 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1164,7 +1164,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || $conf->browser->layout=='phone') $tmptxt=$object->getLibStatut(5, $object->totalpaye); $morehtmlstatus.=$tmptxt; } - elseif ($object->element == 'contrat') + elseif ($object->element == 'contrat' || $object->element == 'contract') { if ($object->statut==0) $morehtmlstatus.=$object->getLibStatut(2); else $morehtmlstatus.=$object->getLibStatut(4); @@ -2375,14 +2375,14 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @param int $pictoisfullpath If 1, image path is a full path * @param int $srconly Return only content of the src attribute of img. * @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip. * @return string Return img tag * @see #img_object, #img_picto_common */ -function img_picto($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) +function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) { global $conf; @@ -2434,7 +2434,8 @@ function img_picto($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $ if (preg_match('/:[^\s0-9]/',$titlealt)) $tmparray=explode(':',$titlealt); // We explode if we have TextA:TextB. Not if we have TextA: TextB $title=$tmparray[0]; $alt=empty($tmparray[1])?'':$tmparray[1]; - return ''.dol_escape_htmltag($alt).''; // Alt is used for accessibility, title for popup + if ($picto == 'refresh') var_dump($moreatt); + return ''.dol_escape_htmltag($alt).''; // Alt is used for accessibility, title for popup } } @@ -2444,16 +2445,16 @@ function img_picto($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $ * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $picto Name of image to show object_picto (example: user, group, action, bill, contract, propal, product, ...) * For external modules use imagename@mymodule to search into directory "img" of module. - * @param string $morealt Add more attribute on img tag (ie: class="datecallink") + * @param string $moreatt Add more attribute on img tag (ie: class="datecallink") * @param int $pictoisfullpath If 1, image path is a full path * @param int $srconly Return only content of the src attribute of img. * @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip. * @return string Return img tag * @see #img_picto, #img_picto_common */ -function img_object($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) +function img_object($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) { - return img_picto($titlealt, 'object_'.$picto, $morealt, $pictoisfullpath, $srconly, $notitle); + return img_picto($titlealt, 'object_'.$picto, $moreatt, $pictoisfullpath, $srconly, $notitle); } /** @@ -2461,12 +2462,12 @@ function img_object($titlealt, $picto, $morealt = '', $pictoisfullpath = false, * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $picto Name of image file to show (If no extension provided, we use '.png'). Image must be stored into htdocs/theme/common directory. - * @param string $morealt Add more attribute on img tag + * @param string $moreatt Add more attribute on img tag * @param int $pictoisfullpath If 1, image path is a full path * @return string Return img tag * @see #img_object, #img_picto */ -function img_weather($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) +function img_weather($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0) { global $conf; @@ -2474,7 +2475,7 @@ function img_weather($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) $path = DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/weather/'.$picto; - return img_picto($titlealt, $path, $morealt, 1); + return img_picto($titlealt, $path, $moreatt, 1); } /** @@ -2482,12 +2483,12 @@ function img_weather($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $picto Name of image file to show (If no extension provided, we use '.png'). Image must be stored into htdocs/theme/common directory. - * @param string $morealt Add more attribute on img tag + * @param string $moreatt Add more attribute on img tag * @param int $pictoisfullpath If 1, image path is a full path * @return string Return img tag * @see #img_object, #img_picto */ -function img_picto_common($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) +function img_picto_common($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0) { global $conf; @@ -2506,7 +2507,7 @@ function img_picto_common($titlealt, $picto, $morealt = '', $pictoisfullpath = 0 } } - return img_picto($titlealt, $path, $morealt, 1); + return img_picto($titlealt, $path, $moreatt, 1); } /** @@ -2612,9 +2613,9 @@ function img_view($titlealt = 'default', $float = 0, $other = '') if ($titlealt == 'default') $titlealt = $langs->trans('View'); - $morealt = ($float ? 'style="float: right" ' : '').$other; + $moreatt = ($float ? 'style="float: right" ' : '').$other; - return img_picto($titlealt, 'view.png', $morealt); + return img_picto($titlealt, 'view.png', $moreatt); } /** @@ -2686,17 +2687,17 @@ function img_info($titlealt = 'default') * Show warning logo * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"'). If 1 + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"'). If 1 * @return string Return img tag */ -function img_warning($titlealt = 'default', $morealt = '') +function img_warning($titlealt = 'default', $moreatt = '') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Warning'); - //return '
    '.img_picto($titlealt, 'warning_white.png', 'class="pictowarning valignmiddle"'.($morealt ? ($morealt == '1' ? ' style="float: right"' : ' '.$morealt): '')).'
    '; - return img_picto($titlealt, 'warning.png', 'class="pictowarning valignmiddle"'.($morealt ? ($morealt == '1' ? ' style="float: right"' : ' '.$morealt): '')); + //return '
    '.img_picto($titlealt, 'warning_white.png', 'class="pictowarning valignmiddle"'.($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' '.$moreatt): '')).'
    '; + return img_picto($titlealt, 'warning.png', 'class="pictowarning valignmiddle"'.($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' '.$moreatt): '')); } /** @@ -2718,16 +2719,16 @@ function img_error($titlealt = 'default') * Show next logo * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. -* @param string $morealt Add more attribute on img tag (For example 'style="float: right"') +* @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_next($titlealt = 'default', $morealt='') +function img_next($titlealt = 'default', $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Next'); - //return img_picto($titlealt, 'next.png', $morealt); + //return img_picto($titlealt, 'next.png', $moreatt); return ''; } @@ -2735,16 +2736,16 @@ function img_next($titlealt = 'default', $morealt='') * Show previous logo * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_previous($titlealt = 'default', $morealt='') +function img_previous($titlealt = 'default', $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Previous'); - //return img_picto($titlealt, 'previous.png', $morealt); + //return img_picto($titlealt, 'previous.png', $moreatt); return ''; } @@ -2787,16 +2788,16 @@ function img_up($titlealt = 'default', $selected = 0, $moreclass='') * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param int $selected Selected - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_left($titlealt = 'default', $selected = 0, $morealt='') +function img_left($titlealt = 'default', $selected = 0, $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Left'); - return img_picto($titlealt, ($selected ? '1leftarrow_selected.png' : '1leftarrow.png'), $morealt); + return img_picto($titlealt, ($selected ? '1leftarrow_selected.png' : '1leftarrow.png'), $moreatt); } /** @@ -2804,16 +2805,16 @@ function img_left($titlealt = 'default', $selected = 0, $morealt='') * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param int $selected Selected - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_right($titlealt = 'default', $selected = 0, $morealt='') +function img_right($titlealt = 'default', $selected = 0, $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Right'); - return img_picto($titlealt, ($selected ? '1rightarrow_selected.png' : '1rightarrow.png'), $morealt); + return img_picto($titlealt, ($selected ? '1rightarrow_selected.png' : '1rightarrow.png'), $moreatt); } /** diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 6e6e0c7b511..d2567f30c04 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -334,8 +334,6 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) $thumbsbyrow=6; print ''; - $var=false; - // Title if ($foruserprofile) { @@ -343,10 +341,10 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print ''; print ''; - print ''; + print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; } @@ -362,7 +360,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print ''; print ''; - print ''; + print ''; print ''; print ''; } - //$var=!$var; - print ''; + print '
    '.$langs->trans("NoPhotoYet")."
    "; } - - print '
     
    '.$langs->trans("DefaultSkin").''.$conf->global->MAIN_THEME.' '.$langs->trans("UsePersonalValue").' '.$langs->trans("UsePersonalValue").' 
    '.$langs->trans("ThemeDir").''; foreach($dirthemes as $dirtheme) @@ -373,8 +371,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print '
    '; + print '
    '; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + print ''; print ''; print ''; + print ''; print ''; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + print ''; print ''; print ''; print ''; @@ -686,7 +677,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - print ''; + print ''; print ''; print ''; - // Do not import first lines + // Lines nb to import print ''; @@ -2346,7 +2346,7 @@ else if (! empty($conf->adherent->enabled)) { $langs->load("members"); - print ''; + print ''; print ''; print "\n"; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ed3fdad13c4..dce0e5c19bc 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1854,7 +1854,14 @@ class Societe extends CommonObject $result=''; $label=''; $linkstart=''; $linkend=''; - $label.= '
    '; + if (! empty($this->logo) && class_exists('Form')) + { + $label.= '
    '; + $label.= Form::showphoto('societe', $this, 80, 0, 0, 'photowithmargin', 'mini'); + $label.= '
    '; + } + + $label.= '
    '; if ($option == 'customer' || $option == 'compta' || $option == 'category' || $option == 'category_supplier') { @@ -1908,12 +1915,6 @@ class Societe extends CommonObject if (! empty($conf->accounting->enabled) && $this->fournisseur) $label.= '
    ' . $langs->trans('SupplierAccountancyCode') . ': '. $this->code_compta_fournisseur; - if (! empty($this->logo) && class_exists('Form')) - { - $label.= '
    '; - $label.= Form::showphoto('societe', $this, 80, 0, 0, 'photowithmargin', 'mini'); - $label.= '
    '; - } $label.= '
    '; // Add type of canvas diff --git a/htdocs/societe/tpl/linesalesrepresentative.tpl.php b/htdocs/societe/tpl/linesalesrepresentative.tpl.php index d8d4b4b08bb..34a7ce3f4c4 100644 --- a/htdocs/societe/tpl/linesalesrepresentative.tpl.php +++ b/htdocs/societe/tpl/linesalesrepresentative.tpl.php @@ -37,5 +37,5 @@ if ($i < $nbofsalesrepresentative) print ', '; } } - else print $langs->trans("NoSalesRepresentativeAffected"); + else print ''.$langs->trans("NoSalesRepresentativeAffected").''; print ''; diff --git a/htdocs/theme/eldy/img/refresh.png b/htdocs/theme/eldy/img/refresh.png index 9994475cdfe0fb8c646eb1877a84443066a73d93..a4fac077e7aa050f4a84419d6d3df6af9af4d16d 100644 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mrg*wIhEy;fJ!7wTyg;VmVfw;# z3XjYVH8e}Kd|^AApH(;6IMmbY==^!jM;xqceSE*Jp1kz@pJ!X=+3pO>|DZB`;RK5- zoKu5Viru@@@#Ruwc}hu^K;{(g;6rYIdZVU#Do$GzmwC{Bk^A?Gw(Lap^d8T>-j}!PC{xWt~$( F695yoR&f9T literal 722 zcmV;@0xkWCP)YH zKm%ON42;6;44maEEON_y_)3;}a?MFlVvu6M2S6HfG??{Q1@TrKZ_qjae0RaWBQ;JJ z3v{?_RJj@Wd6{r%^pjyw+!)2X_{kcRZ-39Z|NnbB?%&Jx$=}a5yPjL)FIN>K$D+u~ z!oY~3QJs&0x5JJ-`a-wjxgUqk|NPly@&Elw+y6h-2K|3JHSq1GaD{$%ekMs)kYXMd z2IfR%2I&N429-E@22od02JS9PR==~&ve(|O()+q2mS_8w3h67~X4(C}*I@N#vMG0z z01E>vgD5AX=+;D%AB z^#AV(5m+h8!63*W!ObXlp+fP?>+Pw(weOTlLQ|~a4||Th;uPWpUIVY_-S?E-#wW+^DRXfB>7kwm_^tb1O-?bz~N}X z!@#`EovY$ii^A8NSt4I0ftE3da4-n$4Ch|*ZNB~g>+ROJVzfEJYxNm)SNn@Bm|)Is zDb3EnVj;l5zQUEg@O-Aom4gvHr^LA!B^iW(9-VK@5`M2v>CKk~ZvRi0=$%^QFEahk zoRp8p>)g(^8gsh<1B@eHfk81@jlm{Sjlmcgpll2rK&M3TGe~U>;+p!RP2=O&S&sjo zOmzMEV^iM0uN%{TpQ>>@)?&>csLBiRI|=|sDpP_oqxu$qj?SxvlK0+q>;3*a-R$4L zX}bU4PImaUJzjCEuPlQO)>Oj>Oc5IV45G!lOfH9G_)dOoRrq^7TlnpcVD5#pj5xfV z*%|oprq@VW2JYo9EXy|du+8r_W3&MU9xxnO*wNGh0HJEuBo)&9!2kdN07*qoM6N<$ Eg5ua`M*si- diff --git a/htdocs/theme/eldy/img/reload.png b/htdocs/theme/eldy/img/reload.png deleted file mode 100644 index a4029f119def5d9ca4c5f7f1bc6a452176bf5b06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 704 zcmb7??@Lor9LBF`=^U1X>V4y5N$e2{G6k^_+1%BMO-*2b|;o^^|?8?hdl^qD(~U7?6ySOppu+gG7)!Q4hvMSYQj|No=(Kykg?MTQ)Jvq%YX^x9` z<~II3e3`G%>{>ifvstipIJmpH^0&q~lxANZzwr5ye<^4kE@;2R-G0>>G;ihPIQy!4 zPOU`7?hhi(v26Y5#Cl)v*noY9_R!V0D-$zQvwQt=_^YF8PlvI>ZY}jIQu5~uf4Ht} zo_Tsr-L__EPhx)dj^+;R&tEea_v^b=+0TwYzo$4q)c;r;XZ_XkX7U7UEu8!?m_9wd z{6H*CU+OGAZOdol_hide_leftmenu; $dol_optimize_smallscreen=$conf->dol_optimize_smallscreen; $dol_no_mouse_hover=$conf->dol_no_mouse_hover; - //$conf->global->THEME_ELDY_ENABLE_PERSONALIZED=0; //$user->conf->THEME_ELDY_ENABLE_PERSONALIZED=0; //var_dump($user->conf->THEME_ELDY_RGB); // Colors -$colorbackhmenu1='110,120,160'; // topmenu +$colorbackhmenu1='90,100,130'; // topmenu $colorbackvmenu1='255,255,255'; // vmenu $colortopbordertitle1='120,120,120'; // top border of title $colorbacktitle1='240,240,240'; // title of tables,list @@ -97,7 +96,6 @@ $colortext='0,0,0'; $colortextlink='0,0,120'; $fontsize='13'; $fontsizesmaller='12'; -$usegradienttop=(isset($conf->global->THEME_ELDY_TOPMENU_BACK1)?0:1); $useboldtitle=(isset($conf->global->THEME_ELDY_USEBOLDTITLE)?$conf->global->THEME_ELDY_USEBOLDTITLE:1); $borderwith=2; @@ -125,7 +123,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_FONT_SIZE2='12'; } - + // Case of option availables only if THEME_ELDY_ENABLE_PERSONALIZED is on $colorbackhmenu1 =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TOPMENU_BACK1)?$colorbackhmenu1:$conf->global->THEME_ELDY_TOPMENU_BACK1) :(empty($user->conf->THEME_ELDY_TOPMENU_BACK1)?$colorbackhmenu1:$user->conf->THEME_ELDY_TOPMENU_BACK1); $colorbackvmenu1 =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_VERMENU_BACK1)?$colorbackvmenu1:$conf->global->THEME_ELDY_VERMENU_BACK1) :(empty($user->conf->THEME_ELDY_VERMENU_BACK1)?$colorbackvmenu1:$user->conf->THEME_ELDY_VERMENU_BACK1); @@ -137,7 +135,6 @@ $colorbacklineimpair1=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty( $colorbacklineimpair2=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEIMPAIR2) ?$colorbacklineimpair2:$conf->global->THEME_ELDY_LINEIMPAIR2):(empty($user->conf->THEME_ELDY_LINEIMPAIR2)?$colorbacklineimpair2:$user->conf->THEME_ELDY_LINEIMPAIR2); $colorbacklinepair1 =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEPAIR1) ?$colorbacklinepair1:$conf->global->THEME_ELDY_LINEPAIR1) :(empty($user->conf->THEME_ELDY_LINEPAIR1)?$colorbacklinepair1:$user->conf->THEME_ELDY_LINEPAIR1); $colorbacklinepair2 =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEPAIR2) ?$colorbacklinepair2:$conf->global->THEME_ELDY_LINEPAIR2) :(empty($user->conf->THEME_ELDY_LINEPAIR2)?$colorbacklinepair2:$user->conf->THEME_ELDY_LINEPAIR2); -$colorbacklinepairhover=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEPAIRHOVER) ?$colorbacklinepairhover:$conf->global->THEME_ELDY_LINEPAIRHOVER) :(empty($user->conf->THEME_ELDY_LINEPAIRHOVER)?$colorbacklinepairhover:$user->conf->THEME_ELDY_LINEPAIRHOVER); $colorbackbody =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_BACKBODY) ?$colorbackbody:$conf->global->THEME_ELDY_BACKBODY) :(empty($user->conf->THEME_ELDY_BACKBODY)?$colorbackbody:$user->conf->THEME_ELDY_BACKBODY); $colortexttitlenotab =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TEXTTITLENOTAB)?$colortexttitlenotab:$conf->global->THEME_ELDY_TEXTTITLENOTAB) :(empty($user->conf->THEME_ELDY_TEXTTITLENOTAB)?$colortexttitlenotab:$user->conf->THEME_ELDY_TEXTTITLENOTAB); $colortexttitle =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TEXTTITLE) ?$colortexttitle:$conf->global->THEME_ELDY_TEXTTITLE) :(empty($user->conf->THEME_ELDY_TEXTTITLE)?$colortexttitle:$user->conf->THEME_ELDY_TEXTTITLE); @@ -145,6 +142,7 @@ $colortext =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty( $colortextlink =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TEXTLINK) ?$colortextlink:$conf->global->THEME_ELDY_TEXTLINK) :(empty($user->conf->THEME_ELDY_TEXTLINK)?$colortextlink:$user->conf->THEME_ELDY_TEXTLINK); $fontsize =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_FONT_SIZE1) ?$fontsize:$conf->global->THEME_ELDY_FONT_SIZE1) :(empty($user->conf->THEME_ELDY_FONT_SIZE1)?$fontsize:$user->conf->THEME_ELDY_FONT_SIZE1); $fontsizesmaller =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_FONT_SIZE2) ?$fontsize:$conf->global->THEME_ELDY_FONT_SIZE2) :(empty($user->conf->THEME_ELDY_FONT_SIZE2)?$fontsize:$user->conf->THEME_ELDY_FONT_SIZE2); + // Hover color $colorbacklinepairhover=((! isset($conf->global->THEME_ELDY_USE_HOVER) || (string) $conf->global->THEME_ELDY_USE_HOVER === '0')?'':($conf->global->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$conf->global->THEME_ELDY_USE_HOVER)); if (! empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)) @@ -271,6 +269,9 @@ input.select2-input { .liste_titre input[name=monthvalid], .liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } +input[type=submit] { + margin-left: 5px; +} input, input.flat, form.flat select, select, select.flat, .dataTables_length label select { global->THEME_ELDY_SHOW_BORDER_INPUT)) print "border: none;" @@ -519,6 +520,9 @@ textarea.centpercent { .nowrap { white-space: ; } +.nowraponall { + white-space: nowrap; +} .nobold { font-weight: normal !important; } @@ -534,6 +538,9 @@ textarea.centpercent { .cursorpointer { cursor: pointer; } +.cursormove { + cursor: move; +} .badge { display: inline-block; min-width: 10px; @@ -548,9 +555,6 @@ textarea.centpercent { background-color: #777; border-radius: 10px; } -.movable { - cursor: move; -} .borderrightlight { border-right: 1px solid #DDD; @@ -876,7 +880,7 @@ td.showDragHandle { } #id-right, #id-left { padding-top: 16px; - padding-bottom: 8px; + padding-bottom: 16px; display: table-cell; /* DOL_XXX Empeche fonctionnement correct du scroll horizontal sur tableau, avec datatable ou CSS */ float: none; @@ -1100,6 +1104,9 @@ div.statusref { margin-bottom: 10px; clear: both; } +div.statusref img { + padding-left: 8px; +} img.photoref, div.photoref { border: 1px solid #CCC; -moz-box-shadow: 3px 3px 4px #DDD; @@ -1156,14 +1163,14 @@ div#id-top { background: rgb(); /*-webkit-box-shadow: 0 0 6px rgba(0,0,0,0.4); box-shadow: 0 0 6px rgba(0,0,0,0.4); */ - + /* background-image: linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -o-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -moz-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -ms-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-gradient( linear, left top, left bottom, color-stop(0, rgba(255,255,255,.1)), color-stop(1, rgba(0,0,0,.4)) ); - + */ /* height: 34px; @@ -1240,15 +1247,15 @@ ul.tmenu { /* t r b l */ display: table; } ul.tmenu li { /* We need this to have background color when menu entry wraps on new lines */ -/* background: rgb(); - + /* background: rgb(); + /* background-image: linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -o-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -moz-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -ms-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-gradient( linear, left top, left bottom, color-stop(0, rgba(255,255,255,.1)), color-stop(1, rgba(0,0,0,.4)) ); - */ + */ } li.tmenu, li.tmenusel { @@ -1293,7 +1300,7 @@ div.tmenuleft div.tmenucenter { padding-left: 0px; - padding-right: 0px; + padding-right: 3px; padding-top: 8px; height: 26px; @@ -1335,7 +1342,7 @@ div.mainmenu { position : relative; background-repeat:no-repeat; background-position:center top; - height: px; + height: px; margin-left: 0px; min-width: 40px; } @@ -1526,9 +1533,9 @@ form#login { background-color: #FFFFFF; - -moz-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); - -webkit-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); - box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); + -moz-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); + -webkit-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); + box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); border-radius: 5px; /*border-top:solid 1px rgba(180,180,180,.4); @@ -2063,82 +2070,32 @@ span.butAction, span.butActionDelete { margin: 0em em; padding: 0.6em em; font-family: ; -/* for bootstrap look - color: #fff; - background-color: #337ab7; - border-color: #2e6da4; - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-weight: normal; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; - */ - - font-weight: normal; - border-color: #c5c5c5; - border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); - display: inline-block; - text-align: center; - cursor: pointer; - color: #fff; - background: rgb(); - background-image: linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -o-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -moz-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -ms-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - - color: #333333; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #bbbbbb; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + font-weight: normal; + border-color: #c5c5c5; + border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); + display: inline-block; + text-align: center; + cursor: pointer; + color: #fff; + background: rgb(); + border: 1px solid rgb(); } .butAction:hover { - -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); + -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + -webkit-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); } .butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete { - color: #800 !important; + background: #633; + border: 1px solid #633; } .butActionDelete:hover { - -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); + -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + -webkit-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); } .butActionRefused { @@ -2148,130 +2105,14 @@ span.butAction, span.butActionDelete { margin: 0em em; padding: 0.6em em; font-family: !important; -/* for bootstrap look - color: #333; - background-color: #e6e6e6; - border-color: #adadad; - display: inline-block; - margin-bottom: 0; - font-weight: normal !important; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; -*/ - - font-weight: normal !important; - border-color: #c5c5c5; - border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); - display: inline-block; - margin: 0em em; - padding: 0.6em em; - text-align: center; - cursor: pointer; - color: #999 !important; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #bbbbbb; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - + font-weight: normal !important; + display: inline-block; + text-align: center; + cursor: pointer; + color: #999 !important; + border: 1px solid #bbb; } -/* Prepare for bootstrap look -.butAction, .butActionDelete, .butActionRefused { - border-color: #c5c5c5; - border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); - display: inline-block; - padding: 4px 14px; - margin-bottom: 0; - line-height: 20px; - text-align: center; - vertical-align: middle; - cursor: pointer; - color: #333333; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #bbbbbb; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.butAction { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #006dcc; - background-image: -moz-linear-gradient(top, #0088cc, #0044cc); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); - background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); - background-image: -o-linear-gradient(top, #0088cc, #0044cc); - background-image: linear-gradient(to bottom, #0088cc, #0044cc); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); - border-color: #0044cc #0044cc #002a80; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.butActionDelete { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #cc6d00; - background-image: -moz-linear-gradient(top, #cc8800, #cc4400); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#cc8800), to(#cc4400)); - background-image: -webkit-linear-gradient(top, #cc8800, #cc4400); - background-image: -o-linear-gradient(top, #cc8800, #cc4400); - background-image: linear-gradient(to bottom, #cc8800, #cc4400); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffcc8800', endColorstr='#ffcc4400', GradientType=0); - border-color: #cc4400 #cc4400 #802a00; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -a.butAction:link, a.butAction:visited, a.butAction:hover, a.butAction:active { - color: #FFFFFF; -} -End bootstrap */ - global->MAIN_BUTTON_HIDE_UNAUTHORIZED) && (! $user->admin)) { ?> .butActionRefused { display: none; @@ -2531,14 +2372,12 @@ div.pagination li.pagination span.inactive { cursor: default; color: #ccc; } +li.noborder.litext, li.noborder.litext a, div.pagination li a.inactive:hover, div.pagination li span.inactive:hover { - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; } /*div.pagination li.litext { padding-top: 8px; @@ -2563,7 +2402,7 @@ div.pagination li.noborder a:hover { } div.pagination li a, div.pagination li span { - background-color: #fff; + /* background-color: #fff; */ /* border: 1px solid #ddd; */ } div.pagination li:first-child a, @@ -2581,6 +2420,10 @@ div.pagination li a:hover, div.pagination li span:hover, div.pagination li a:focus, div.pagination li span:focus { + -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + -webkit-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + /* color: #000; background-color: #eee; border-color: #ccc; @@ -2591,7 +2434,7 @@ div.pagination li span:focus { background-image: -o-linear-gradient(top, #eee, #ddd); background-image: linear-gradient(to bottom, #eee, #ddd); background-repeat: repeat-x; - +*/ } div.pagination li .active a, div.pagination li .active span, @@ -3123,15 +2966,13 @@ td.legendLabel { padding: 2px 2px 2px 0 !important; } margin-bottom: 2px; margin-top: 10px; } -.photowithmargin { -/* -webkit-box-shadow: 0px 0px 3px #777; - -moz-box-shadow: 0px 0px 3px #777; - box-shadow: 0px 0px 3px #777;*/ -} -.photointoolitp { +.photointooltip { margin-top: 6px; - float: left; - /*text-align: center; */ + margin-bottom: 6px; + text-align: center; + /*-moz-box-shadow: 3px 3px 4px #DDD; + -webkit-box-shadow: 3px 3px 4px #DDD; + box-shadow: 3px 3px 4px #DDD;*/ } .photodelete { margin-top: 6px !important; @@ -4651,7 +4492,7 @@ border-top-right-radius: 6px; /* nboftopmenuentries = , fontsize= */ /* rule to reduce top menu - 1st reduction */ -@media only screen and (max-width: px) +@media only screen and (max-width: px) /* reduction 1 */ { div.tmenucenter { width: px; /* size of viewport */ @@ -4680,7 +4521,7 @@ border-top-right-radius: 6px; } } /* rule to reduce top menu - 2nd reduction */ -@media only screen and (max-width: px) +@media only screen and (max-width: px) /* reduction 2 */ { div.mainmenu { height: 23px; @@ -4689,6 +4530,9 @@ border-top-right-radius: 6px; max-width: px; /* size of viewport */ text-overflow: clip; } + span.mainmenuaspan { + margin-left: 1px; + } .mainmenuaspan { /*display: none;*/ font-size: 10px; @@ -4696,10 +4540,11 @@ border-top-right-radius: 6px; .topmenuimage { background-size: 20px auto; margin-top: 2px; + left: 4px; } } /* rule to reduce top menu - 3rd reduction */ -@media only screen and (max-width: px) +@media only screen and (max-width: px) /* reduction 3 */ { /* Reduce login top right info */ .usertextatoplogin { @@ -4743,6 +4588,7 @@ border-top-right-radius: 6px; .topmenuimage { background-size: 20px auto; margin-top: 2px !important; + left: 2px; } div.mainmenu { min-width: 20px; diff --git a/htdocs/theme/md/img/edit.png b/htdocs/theme/md/img/edit.png index 7012f52be5ae6acc556b223c8a822b5883ce62ac..6334689a36e2cc1be67f0f5ea5233231e0d99130 100644 GIT binary patch delta 278 zcmbQjxQuCnWIY=L14G!kzHlJLmgMd3!tfsi7wla=87RV8;1OBOz`!jG!i)^F=12eq z*-JcqUD+Qp%k#3b=v?_T5h%3T)5S5w;`G@|8+i{I2(&)57jstF$iQsC^yXv05``l! z4b6F+Tv}Q)8grc{dmM9>k>-kty!LbV=bsPi-B+L5n~=tr(a5`D+83q*)|2NO8dwX= zH>YZTVc1n?&z{Gyx##(uhUH7TXNK0MiWbZb3GA;}z_w@R)k#qc82b(=-h9JwlkK?d z1&>dOYfihgJy~sWFIDOA`nQvdO&D)_zH(a_^o02rTW57h&yfJbNm3_Ho{*T*`saBS a^R&mF4IlX1PKp3Mz~JfX=d#Wzp$Pz}xNtoH delta 130 zcmV-|0Db?a0+a!e8G8f(008{QM%(}Z09#2!K~#7F#m(IbfG`jQ;fd8)ms*nq@uxOH zu#1aJp3NB$ap(1e<=q-K4q6{ABz5|%!!p}TN3#g@nT_{kC1D~k5D6usFcH8biug<> k!jFU+LJgsYP#_=d0-J70jk-!ing9R*07*qoM6N<$f-|=>8~^|S diff --git a/htdocs/theme/md/img/reload.png b/htdocs/theme/md/img/reload.png deleted file mode 100644 index a4fac077e7aa050f4a84419d6d3df6af9af4d16d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mrg*wIhEy;fJ!7wTyg;VmVfw;# z3XjYVH8e}Kd|^AApH(;6IMmbY==^!jM;xqceSE*Jp1kz@pJ!X=+3pO>|DZB`;RK5- zoKu5Viru@@@#Ruwc}hu^K;{(g;6rYIdZVU#Do$GzmwC{Bk^A?Gw(Lap^d8T>-j}!PC{xWt~$( F695yoR&f9T diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 28c3c6c0193..94f0b11b560 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -521,6 +521,9 @@ textarea.centpercent { .nowrap { white-space: ; } +.nowraponall { + white-space: nowrap; +} .nobold { font-weight: normal !important; } @@ -536,6 +539,9 @@ textarea.centpercent { .cursorpointer { cursor: pointer; } +.cusormove { + cursor: move; +} .badge { display: inline-block; min-width: 10px; @@ -550,9 +556,6 @@ textarea.centpercent { background-color: #777; border-radius: 10px; } -.movable { - cursor: move; -} .borderrightlight { @@ -1145,6 +1148,9 @@ div.statusref { margin-bottom: 10px; clear: both; } +div.statusref img { + padding-left: 8px; +} img.photoref, div.photoref { border: 1px solid #CCC; -moz-box-shadow: 3px 3px 4px #DDD; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 26af6c659ff..811f39b3c88 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1986,12 +1986,18 @@ class User extends CommonObject if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; - $result = ''; - $companylink = ''; - $link = ''; - - $label = '' . $langs->trans("User") . ''; - $label.= '
    '; + $result=''; $label=''; + $linkstart=''; $linkend=''; + + if (! empty($this->photo)) + { + $label.= '
    '; + $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); + $label.= '
    '; + } + + $label.= '
    '; + $label.= '' . $langs->trans("User") . '
    '; $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,'',''); if (! empty($this->login)) $label.= '
    ' . $langs->trans('Login') . ': ' . $this->login; @@ -2008,12 +2014,6 @@ class User extends CommonObject $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal")); $label.= '
    ' . $langs->trans("Type") . ': ' . $type; $label.='
    '; - if (! empty($this->photo)) - { - $label.= '
    '; - $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); - $label.= '
    '; - } // Info Login if ($infologin) From ee86b7bcefe182574dac69a4bb13a35d16302446 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 17:50:54 +0200 Subject: [PATCH 276/410] Avoid javascript warning when in stable mode. --- htdocs/main.inc.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index ab156334c4f..bc1af5cc340 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1146,8 +1146,11 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; if (constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; - if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; - else print ''."\n"; + if (! empty($conf->global->MAIN_FEATURES_LEVEL)) + { + if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; + else print ''."\n"; + } if (constant('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; From 9d193924bdaac93976cd53998d1fdffdea9f15eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 18:05:20 +0200 Subject: [PATCH 277/410] Fix bad constants --- htdocs/main.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index bc1af5cc340..c8dac96f11e 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1144,14 +1144,14 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs { // JQuery. Must be before other includes print ''."\n"; - if (constant('JS_JQUERY')) print ''."\n"; + if (defined('JS_JQUERY')) print ''."\n"; else print ''."\n"; if (! empty($conf->global->MAIN_FEATURES_LEVEL)) { - if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; + if (defined('JS_JQUERY_MIGRATE')) print ''."\n"; else print ''."\n"; } - if (constant('JS_JQUERY_UI')) print ''."\n"; + if (defined('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; if (! defined('DISABLE_JQUERY_TIPTIP')) print ''."\n"; From 2903518fb1329b4b8e6f4851b19ebd052d03c21f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 18:11:01 +0200 Subject: [PATCH 278/410] Fix bad links --- htdocs/main.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index c8dac96f11e..074f626f299 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1144,14 +1144,14 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs { // JQuery. Must be before other includes print ''."\n"; - if (defined('JS_JQUERY')) print ''."\n"; + if (defined('JS_JQUERY') && constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; if (! empty($conf->global->MAIN_FEATURES_LEVEL)) { - if (defined('JS_JQUERY_MIGRATE')) print ''."\n"; + if (defined('JS_JQUERY_MIGRATE') && constant('JS_JQUERY_MIGRATE')) print ''."\n"; else print ''."\n"; } - if (defined('JS_JQUERY_UI')) print ''."\n"; + if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; if (! defined('DISABLE_JQUERY_TIPTIP')) print ''."\n"; From 93687997c98ef4a60d88aea568f2d2f60f916374 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 18:40:53 +0200 Subject: [PATCH 279/410] Work on 6.0 look and feel --- htdocs/adherents/stats/index.php | 2 +- htdocs/comm/propal/stats/index.php | 2 +- htdocs/commande/stats/index.php | 2 +- htdocs/compta/deplacement/stats/index.php | 2 +- htdocs/compta/facture/fiche-rec.php | 29 +++++++++++------------ htdocs/compta/facture/stats/index.php | 2 +- htdocs/don/stats/index.php | 2 +- htdocs/expedition/stats/index.php | 2 +- htdocs/expensereport/stats/index.php | 2 +- htdocs/fichinter/stats/index.php | 2 +- htdocs/projet/stats/index.php | 2 +- 11 files changed, 24 insertions(+), 25 deletions(-) diff --git a/htdocs/adherents/stats/index.php b/htdocs/adherents/stats/index.php index 6acdd1e56b7..aec8cd588f6 100644 --- a/htdocs/adherents/stats/index.php +++ b/htdocs/adherents/stats/index.php @@ -141,7 +141,7 @@ if (! $mesg) $head = member_stats_prepare_head($adh); -dol_fiche_head($head, 'statssubscription', $langs->trans("Statistics"), 0, 'user'); +dol_fiche_head($head, 'statssubscription', $langs->trans("Statistics"), -1, 'user'); print '
    '; diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php index 04c1af11e1d..2ec1a3d660b 100644 --- a/htdocs/comm/propal/stats/index.php +++ b/htdocs/comm/propal/stats/index.php @@ -242,7 +242,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,'propal_stats'); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php index d900709b835..534011d73fe 100644 --- a/htdocs/commande/stats/index.php +++ b/htdocs/commande/stats/index.php @@ -253,7 +253,7 @@ if ($mode == 'supplier') $type='supplier_order_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/compta/deplacement/stats/index.php b/htdocs/compta/deplacement/stats/index.php index 216988b6a7a..36bc107d672 100644 --- a/htdocs/compta/deplacement/stats/index.php +++ b/htdocs/compta/deplacement/stats/index.php @@ -223,7 +223,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,'trip_stats'); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 9d4329a671b..46a7bc299f6 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -1637,21 +1637,8 @@ else print '
    '; print '
    '; @@ -410,11 +407,11 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print '
    '; if ($subdir == $selected_theme) { - print ' '.$subdir.''; + print ' '.$subdir.''; } else { - print ' '.$subdir; + print ' '.$subdir; } print '
    '; @@ -432,8 +429,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // BackgroundColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -455,8 +452,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("BackgroundColor").''; //var_dump($conf->global->THEME_ELDY_BACKBODY); @@ -478,8 +474,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // TopMenuBackgroundColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -501,10 +497,10 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $default='515870'; - if ($conf->theme == 'md') $default='5A3278'; + $default='5a6482'; + if ($conf->theme == 'md') $default='5a3278'; $var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''; if ($edit) @@ -525,8 +521,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // TopMenuBackgroundColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -549,8 +545,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) else { $default=$langs->trans('No'); - $var=!$var; - print '
    '.$langs->trans("TopMenuDisableImages").''; if ($edit) @@ -577,8 +572,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("BackgroundTableTitleColor").''; if ($edit) @@ -604,8 +598,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("TextTitleColor").''; if ($edit) @@ -627,8 +620,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // Text LinkColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -650,8 +643,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("LinkColor").''; if ($edit) @@ -670,11 +662,10 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } // Use Hover - $var=!$var; if ($foruserprofile) { /* Must first change option to choose color of highlight instead of yes or no. - print '
    '.$langs->trans("HighlightLinesOnMouseHover").'global->THEME_ELDY_USE_HOVER?" checked":"").'> '.$langs->trans("UsePersonalValue").'
    '.$langs->trans("HighlightLinesColor").''; //print ''; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 8de637df3cc..29bcc04d54b 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -1268,7 +1268,7 @@ if ($step == 5 && $datatoimport) print $nboflines; print '
    '; print $langs->trans("ImportFromToLine"); print ''; @@ -1307,8 +1307,15 @@ if ($step == 5 && $datatoimport) } print '   '.$langs->trans("Modify").''; } else { - print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%'); - print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt")); + if (count($objimport->array_import_updatekeys[0])) + { + print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%'); + } + else + { + print ''.$langs->trans("UpdateNotYetSupportedForThisImport").''; + } + print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt")); } /*echo '
    ';
     	print_r($objimport->array_import_updatekeys);
    diff --git a/htdocs/install/doctemplates/mycompany/background_dolibarr.jpg b/htdocs/install/doctemplates/mycompany/background_dolibarr.jpg
    new file mode 100644
    index 0000000000000000000000000000000000000000..31177b1b5c2bd609f69d46bcb5f40ce6ff9e5004
    GIT binary patch
    literal 337251
    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 *t*wru8UyS-Ivy?BEW;6vH@VChTi0 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 +|XIw%`F&R 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 z%0D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 XTdN}e0t*0GsX|4%|Bk)(zlHw;vn+8r literal 0 HcmV?d00001 diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index acbf407fd62..139b3e463b8 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -117,6 +117,7 @@ ImportFromToLine=Import line numbers (from - to) SetThisValueTo2ToExcludeFirstLine=For example, set this value to 3 to exclude the 2 first lines KeepEmptyToGoToEndOfFile=Keep this field empty to go up to the end of file SelectPrimaryColumnsForUpdateAttempt=Select column(s) to use as primary key for update attempt +UpdateNotYetSupportedForThisImport=Update is not supported for this type of import (only insert) ## filters SelectFilterFields=If you want to filter on some values, just input values here. FilteredFields=Filtered fields diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index fc6e9ecb743..a886dcf475b 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -241,8 +241,10 @@ else dol_banner_tab($act, 'element_id', $linkback, ($user->societe_id?0:1), 'id', 'ref', $morehtmlref, '&element='.$element, 0, '', ''); + print '

    '; + dol_fiche_end(); } } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index c9fb0de6edf..bb043076157 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1670,7 +1670,7 @@ else // Zip / Town print '
    '.fieldLabel('Zip','zipcode').''; - print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6); + print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 0, '', 'maxwidth50onsmartphone'); print ''.fieldLabel('Town','town').''; print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id')); print '
    '.$langs->trans("LinkedToDolibarrMember").'
    '.$langs->trans("LinkedToDolibarrMember").''; $adh=new Adherent($db); $result=$adh->fetch('','',$object->id); @@ -2357,7 +2357,7 @@ else } else { - print $langs->trans("ThirdpartyNotLinkedToMember"); + print ''.$langs->trans("ThirdpartyNotLinkedToMember").''; } print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountVAT"),$_SERVER['PHP_SELF'],"f.tva","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER['PHP_SELF'],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("RecurringInvoiceTemplate"),$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateLastGeneration"),$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("NextDateToExecution"),$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre(''); // Field may contains ling text - print "\n"; - - // Filters lines - print ''; + print ''; // Ref if (! empty($arrayfields['f.titre']['checked'])) { @@ -1756,7 +1743,19 @@ else print ''; print "\n"; - + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountHT"),$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountVAT"),$_SERVER['PHP_SELF'],"f.tva","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER['PHP_SELF'],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("RecurringInvoiceTemplate"),$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateLastGeneration"),$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("NextDateToExecution"),$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre(''); // Field may contains ling text + print "\n"; + + if ($num > 0) { $var=true; diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php index 5c5aa8489be..767082997d8 100644 --- a/htdocs/compta/facture/stats/index.php +++ b/htdocs/compta/facture/stats/index.php @@ -225,7 +225,7 @@ if ($mode == 'supplier') $type='supplier_invoice_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); $tmp_companies = $form->select_thirdparty_list($socid,'socid',$filter,1, 0, 0, array(), '', 1); //Array passed as an argument to Form::selectarray to build a proper select input diff --git a/htdocs/don/stats/index.php b/htdocs/don/stats/index.php index 7da3fadcc6e..b8cd532d35a 100644 --- a/htdocs/don/stats/index.php +++ b/htdocs/don/stats/index.php @@ -224,7 +224,7 @@ $type='donation_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/expedition/stats/index.php b/htdocs/expedition/stats/index.php index 3dfe5af6b48..f4e8d45f5a1 100644 --- a/htdocs/expedition/stats/index.php +++ b/htdocs/expedition/stats/index.php @@ -223,7 +223,7 @@ $type='shipment_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/expensereport/stats/index.php b/htdocs/expensereport/stats/index.php index c81996fda3b..f0448db1771 100644 --- a/htdocs/expensereport/stats/index.php +++ b/htdocs/expensereport/stats/index.php @@ -206,7 +206,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,'trip_stats'); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/fichinter/stats/index.php b/htdocs/fichinter/stats/index.php index c053239de1c..e6e1470b47a 100644 --- a/htdocs/fichinter/stats/index.php +++ b/htdocs/fichinter/stats/index.php @@ -231,7 +231,7 @@ if ($mode == 'supplier') $type='supplier_order_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/projet/stats/index.php b/htdocs/projet/stats/index.php index 15a2f3403c4..e9aad0d0b7e 100644 --- a/htdocs/projet/stats/index.php +++ b/htdocs/projet/stats/index.php @@ -271,7 +271,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics"), 0, ''); +dol_fiche_head($head,'byyear',$langs->trans("Statistics"), -1, ''); print '
    '; From 7254b54a0401c37fdd0bbe37c144658cc26d4276 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 00:35:05 +0200 Subject: [PATCH 280/410] Work on 6.0 look and feel --- htdocs/comm/action/index.php | 154 +++++++++++++++++------------- htdocs/theme/eldy/graph-color.php | 2 +- htdocs/theme/eldy/style.css.php | 24 +++-- htdocs/theme/md/style.css.php | 23 +++-- htdocs/user/card.php | 59 ++++++------ htdocs/user/class/user.class.php | 6 +- 6 files changed, 152 insertions(+), 116 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 87fc887560c..cb93f8bffab 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -364,12 +364,19 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on $s.=''."\n"; $s.='' . "\n"; @@ -384,7 +391,6 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on $s.='jQuery(document).ready(function () { jQuery("table input[name^=\"check_ext\"]").click(function() { var name = $(this).attr("name"); - jQuery(".family_ext" + name.replace("check_ext", "")).toggle(); }); });' . "\n"; @@ -1007,10 +1013,10 @@ if (empty($action) || $action == 'show_month') // View by month print $langs->trans($labelshort[$numdayinweek]); } else print $langs->trans("Day".$numdayinweek); - print "\n"; + print ' '."\n"; $i++; } - echo " \n"; + echo ' '."\n"; $todayarray=dol_getdate($now,'fast'); $todaytms=dol_mktime(0, 0, 0, $todayarray['mon'], $todayarray['mday'], $todayarray['year']); @@ -1193,21 +1199,23 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa global $theme_datacolor; global $cachethirdparties, $cachecontacts, $cacheusers, $colorindexused; - print "\n".'
    '; + $dateint = sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day); + + print "\n"; // Line with title of day $curtime = dol_mktime(0, 0, 0, $month, $day, $year); - print '
    '."\n"; + print '
    '."\n"; - print '
    '."\n"; + print ''."\n"; // Line with td contains all div of each events - print ''; + print ''; // td tr - print '
    '; - print ''; + print '
    '; if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create) { $newparam.='&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$year; @@ -1218,11 +1226,11 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print img_picto($langs->trans("NewAction"),'edit_add.png'); print ''; } - print '
    '; - print '
    '; + print '
    '; + print '
    '; //$curtime = dol_mktime (0, 0, 0, $month, $day, $year); $i=0; $nummytasks=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); @@ -1242,26 +1250,26 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa { if ($i < $maxprint || $maxprint == 0 || ! empty($conf->global->MAIN_JS_SWITCH_AGENDA)) { - $keysofuserassigned=array_keys($event->userassigned); + $keysofuserassigned=array_keys($event->userassigned); $ponct=($event->date_start_in_calendar == $event->date_end_in_calendar); // Define $color (Hex string like '0088FF') and $cssclass of event $color=-1; $colorindex=-1; - if (in_array($user->id, $keysofuserassigned)) - { - $nummytasks++; $cssclass='family_mytasks'; - - if (empty($cacheusers[$event->userownerid])) - { - $newuser=new User($db); - $newuser->fetch($event->userownerid); - $cacheusers[$event->userownerid]=$newuser; - } - //var_dump($cacheusers[$event->userownerid]->color); - - // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) - if (! empty($cacheusers[$event->userownerid]->color)) $color=$cacheusers[$event->userownerid]->color; + if (in_array($user->id, $keysofuserassigned)) + { + $nummytasks++; $cssclass='family_mytasks'; + + if (empty($cacheusers[$event->userownerid])) + { + $newuser=new User($db); + $newuser->fetch($event->userownerid); + $cacheusers[$event->userownerid]=$newuser; + } + //var_dump($cacheusers[$event->userownerid]->color); + + // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) + if (! empty($cacheusers[$event->userownerid]->color)) $color=$cacheusers[$event->userownerid]->color; } else if ($event->type_code == 'ICALEVENT') // Event come from external ical file { @@ -1352,19 +1360,25 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // Show rect of event print "\n"; - print '
    '."\n"; + print '
    '; - print '
      '; // always 1 li per ul, 1 ul per event - print '
    • '; - print 'transparency)?'':' cal_event_busy').'" style="'.$h; + print 'background: #'.$color.';'; + //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($color, -5).'), to(#'.dol_color_minus($color, -5).'));'; //if (! empty($event->transparency)) print 'background: #'.$color.'; background: -webkit-gradient(linear, left top, left bottom, from(#'.$color.'), to(#'.dol_color_minus($color,1).'));'; //else print 'background-color: transparent !important; background: none; border: 1px solid #bbb;'; - print ' -moz-border-radius:4px;" width="100%">'; - print ''; + print ''; // Status - Percent - print '
      '; + //print ' -moz-border-radius:4px;"'; + //print 'border: 1px solid #ccc" width="100%"'; + print '">'; + print '
      '; + + $daterange=''; + if ($event->type_code == 'BIRTHDAY') // It's a birthday { print $event->getNomUrl(1,$maxnbofchar,'cal_event','birthday','contact'); @@ -1380,9 +1394,6 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // Date if (empty($event->fulldayevent)) { - //print ''; - $daterange=''; - // Show hours (start ... end) $tmpyearstart = date('Y',$event->date_start_in_calendar); $tmpmonthstart = date('m',$event->date_start_in_calendar); @@ -1415,22 +1426,6 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) $daterange.=dol_print_date($event->date_end_in_calendar,'%H:%M'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user } - //print $daterange; - if ($event->type_code != 'ICALEVENT') - { - $savlabel=$event->libelle; - $event->libelle=$daterange; - //print ''; - print $event->getNomUrl(0); - //print ''; - $event->libelle=$savlabel; - } - else - { - print $daterange; - } - //print ' '; - print " "; } else { @@ -1441,9 +1436,36 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } // Show title - if ($event->type_code == 'ICALEVENT') print dol_trunc($event->libelle,$maxnbofchar); - else print $event->getNomUrl(0,$maxnbofchar,'cal_event'); + $titletoshow = $daterange; + $titletoshow.=($titletoshow?' ':'').$event->libelle; + + if ($event->type_code == 'ICALEVENT') print $titletoshow; + else + { + $savlabel=$event->libelle; + $event->libelle=$titletoshow; + print $event->getNomUrl(0,$maxnbofchar,'cal_event','',0,1); + $event->libelle=$savlabel; + } + // Loop on each assigned user + $listofusertoshow=''; + $posuserassigned=0; + foreach($event->userassigned as $tmpid => $tmpdata) + { + if (! $posuserassigned && $titletoshow) $listofusertoshow.='
      '; + $posuserassigned++; + if (empty($cacheusers[$tmpid])) + { + $newuser=new User($db); + $newuser->fetch($tmpid); + $cacheusers[$tmpid]=$newuser; + } + + $listofusertoshow.=$cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'valigntextbottom'); + } + print $listofusertoshow; + if ($event->type_code == 'ICALEVENT') print '
      ('.dol_trunc($event->icalname,$maxnbofchar).')'; // If action related to company / contact @@ -1486,12 +1508,16 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '
      '; - if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') print $event->getLibStatut(3,1); + $withstatus=0; + if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') + { + $withstatus=1; + if ($event->percentage >= 0) $withstatus=2; + } + print ''; + if ($withstatus) print $event->getLibStatut(3,1); else print ' '; print '
      '; - print '
    • '; - print '
    '; print '
    '."\n"; $i++; } @@ -1533,10 +1559,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print ''."\n"; } - print '
    '; - print '
    '."\n"; + print ''; // table + print "\n"; } diff --git a/htdocs/theme/eldy/graph-color.php b/htdocs/theme/eldy/graph-color.php index 42989907747..d270936aedc 100644 --- a/htdocs/theme/eldy/graph-color.php +++ b/htdocs/theme/eldy/graph-color.php @@ -28,7 +28,7 @@ global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet; $theme_bordercolor = array(235,235,224); -$theme_datacolor = array(array(120,140,220), array(190,120,120), array(0,160,140), array(190,190,100), array(115,125,150), array(100,170,20), array(250,190,30), array(150,135,125), array(85,135,150), array(150,135,80), array(150,80,150)); +$theme_datacolor = array(array(136,102,136), array(140,140,180), array(190,120,120), array(0,160,140), array(190,190,100), array(115,125,150), array(100,170,20), array(250,190,30), array(150,135,125), array(85,135,150), array(150,135,80), array(150,80,150)); $theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4')); $theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC')); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index d0b423804cf..913bcac5f30 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1670,11 +1670,22 @@ img.login, img.printer, img.entity { .userimgatoplogin img.userphoto { /* size for user photo in login bar */ width: 16px; height: 16px; + border-radius: 8px; + background-size: contain; + background-size: contain; } img.userphoto { /* size for user photo in lists */ - border-radius: 2px; + border-radius: 9px; width: 18px; height: 18px; + background-size: contain; + vertical-align: middle; +} +img.userphotosmall { /* size for user photo in lists */ + border-radius: 6px; + width: 12px; + height: 12px; + background-size: contain; vertical-align: middle; } .span-icon-user { @@ -3271,6 +3282,7 @@ a.websitebuttonsitepreview img { /* Module agenda */ /* ============================================================================== */ +.agendacell { height: 60px; } table.cal_month { border-spacing: 0px; } table.cal_month td:first-child { border-left: 0px; } table.cal_month td:last-child { border-right: 0px; } @@ -3294,18 +3306,10 @@ table.cal_month td:last-child { border-right: 0px; } .cal_today_peruser_impair { background: #F8F8F0; } .peruser_busy { background: #CC8888; } .peruser_notbusy { background: #EEDDDD; opacity: 0.5; } -table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 6px; border-radius: 6px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - background: -webkit-gradient(linear, left top, left bottom, from(#006aac), to(#00438d)); - min-height: 20px; - } +table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 6px; border-radius: 6px; min-height: 20px; } table.cal_event td { border: none; padding-: 2px; padding-: 2px; padding-top: 0px; padding-bottom: 0px; } table.cal_event td.cal_event { padding: 4px 4px !important; } table.cal_event td.cal_event_right { padding: 4px 4px !important; } -ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; } -li.cal_event { border: none; list-style-type: none; } .cal_event a:link { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:visited { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:active { color: #111111; font-size: 11px; font-weight: normal !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 94f0b11b560..947b8a57168 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1701,14 +1701,24 @@ img.login, img.printer, img.entity { font-weight: bold; } .userimgatoplogin img.userphoto { /* size for user photo in login bar */ - border-radius: 5px; + border-radius: 8px; width: 16px; height: 16px; + background-size: contain; vertical-align: text-bottom; } img.userphoto { /* size for user photo in lists */ + border-radius: 9px; width: 18px; height: 18px; + background-size: contain; + vertical-align: middle; +} +img.userphotosmall { /* size for user photo in lists */ + border-radius: 6px; + width: 12px; + height: 12px; + background-size: contain; vertical-align: middle; } .span-icon-user { @@ -3366,6 +3376,7 @@ a.websitebuttonsitepreview img { /* Module agenda */ /* ============================================================================== */ +.agendacell { height: 60px; } table.cal_month { border-spacing: 0px; } table.cal_month td:first-child { border-left: 0px; } table.cal_month td:last-child { border-right: 0px; } @@ -3389,18 +3400,10 @@ table.cal_month td:last-child { border-right: 0px; } .cal_today_peruser_impair { background: #F8F8F0; } .peruser_busy { background: #CC8888; } .peruser_notbusy { background: #EEDDDD; opacity: 0.5; } -table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 3px; border-radius: 3px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - background: -webkit-gradient(linear, left top, left bottom, from(#006aac), to(#00438d)); - min-height: 20px; - } +table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 3px; border-radius: 3px; min-height: 20px; } table.cal_event td { border: none; padding-: 2px; padding-: 2px; padding-top: 0px; padding-bottom: 0px; } table.cal_event td.cal_event { padding: 4px 4px !important; } table.cal_event td.cal_event_right { padding: 4px 4px !important; } -ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; } -li.cal_event { border: none; list-style-type: none; } .cal_event a:link { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:visited { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:active { color: #111111; font-size: 11px; font-weight: normal !important; } diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 839d09ee9c7..37a0042c137 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -2346,35 +2346,38 @@ else print ''; } - print '
    '; - /* - * Documents generes - */ - $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->user->user->creer; - $delallowed = $user->rights->user->user->supprimer; - - $var = true; - - $somethingshown = $formfile->show_documents('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object, null, null); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - - print '
    '; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'user', $socid); + if ($action != 'edit') + { + print '
    '; + /* + * Documents generes + */ + $filename = dol_sanitizeFileName($object->ref); + $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->user->user->creer; + $delallowed = $user->rights->user->user->supprimer; + + $var = true; + + $somethingshown = $formfile->show_documents('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, null); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + print '
    '; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'user', $socid); + + + print '
    '; + } - - print '
    '; - - if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) $ldap->close; + if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) $ldap->close(); } } diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 811f39b3c88..112609ce521 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1968,7 +1968,7 @@ class User extends CommonObject * Return a link to the user card (with optionaly the picto) * Use this->id,this->lastname, this->firstname * - * @param int $withpictoimg Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo) + * @param int $withpictoimg Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) * @param string $option On what the link point to * @param integer $infologin Add complete info tooltip * @param integer $notooltip 1=Disable tooltip on picto and name @@ -2074,10 +2074,10 @@ class User extends CommonObject // Only picto if ($withpictoimg > 0) $picto='
    '.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'
    '; // Picto must be a photo - else $picto='
    '.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto', 'mini', 0, 1).'
    '; + else $picto='
    '.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'
    '; $result.=$picto; } - if (abs($withpictoimg) != 2) + if ($withpictoimg > -2 && $withpictoimg != 2) { if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='
    '; if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen); From 65be3107c36cb0299fe1909d1a926d10c0cec506 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 00:51:16 +0200 Subject: [PATCH 281/410] Fix phpunit --- test/phpunit/FunctionsLibTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index a53f971904c..28e55fd793b 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -712,15 +712,15 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase $s=img_picto('title','/fullpath/img.png','',1); print __METHOD__." s=".$s."\n"; - $this->assertEquals('',$s,'testImgPicto3'); + $this->assertEquals('',$s,'testImgPicto3'); $s=img_picto('title','/fullpath/img.png','',true); print __METHOD__." s=".$s."\n"; - $this->assertEquals('',$s,'testImgPicto4'); + $this->assertEquals('',$s,'testImgPicto4'); $s=img_picto('title:alt','/fullpath/img.png','',true); print __METHOD__." s=".$s."\n"; - $this->assertEquals('alt',$s,'testImgPicto5'); + $this->assertEquals('alt',$s,'testImgPicto5'); } /** From e221c48997c195389d122814e26f6d4796ea3b42 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 00:59:21 +0200 Subject: [PATCH 282/410] Css --- htdocs/comm/action/index.php | 2 +- htdocs/theme/eldy/graph-color.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index cb93f8bffab..d365acef38b 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1368,7 +1368,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '>'; print ' Date: Sat, 1 Apr 2017 01:06:23 +0200 Subject: [PATCH 283/410] Fix php dependencies --- build/debian/control | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/debian/control b/build/debian/control index 75ffb43b2c0..29c2469a4e6 100755 --- a/build/debian/control +++ b/build/debian/control @@ -10,12 +10,12 @@ Build-Depends: debhelper (>= 9), po-debconf Package: dolibarr Architecture: all -Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm | php5, - php5-cli, +Depends: libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php, + php-cli, # Required PHP extensions - php5-mysql | php5-mysqli, php5-curl, php5-gd, php5-ldap, + php-mysql | php-mysqli, php-curl, php-gd, php-ldap, # Required PHP libraries - php-pear, php-mail-mime, + php-pear, php-mail-mime, php-xml, php-mbstring, # php-tcpdf, # libfpdf-tpl-php, php-fpdf, # libphp-adodb, From d975e7f442f959d2eb4c4e6944a29fbe6c06b32f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 12:46:47 +0200 Subject: [PATCH 284/410] Work on 6.0 look and feel --- htdocs/accountancy/admin/account.php | 28 +++++------ htdocs/accountancy/admin/categories_list.php | 12 +++-- htdocs/accountancy/admin/productaccount.php | 43 ++++++++--------- htdocs/accountancy/bookkeeping/balance.php | 41 +++++++--------- htdocs/accountancy/bookkeeping/list.php | 36 +++++++------- htdocs/accountancy/customer/lines.php | 43 +++++++++-------- htdocs/accountancy/customer/list.php | 35 +++++++------- htdocs/accountancy/expensereport/lines.php | 33 ++++++------- htdocs/accountancy/expensereport/list.php | 32 +++++++------ htdocs/accountancy/supplier/lines.php | 44 +++++++++--------- htdocs/accountancy/supplier/list.php | 40 +++++++++------- htdocs/compta/paiement/list.php | 49 ++++++++++---------- htdocs/compta/salaries/index.php | 26 +++++------ htdocs/compta/sociales/index.php | 27 ++++++----- htdocs/compta/tva/reglement.php | 30 ++++++------ htdocs/core/class/html.form.class.php | 2 +- htdocs/core/get_menudiv.php | 8 +++- htdocs/core/lib/company.lib.php | 3 +- htdocs/core/lib/functions.lib.php | 4 +- htdocs/core/menus/standard/eldy.lib.php | 31 ++++++++----- htdocs/don/list.php | 37 +++++++-------- htdocs/fourn/facture/paiement.php | 28 +++++------ htdocs/loan/card.php | 47 +++++++++++++------ htdocs/loan/class/loan.class.php | 4 +- htdocs/loan/document.php | 2 +- htdocs/loan/index.php | 22 ++++----- htdocs/loan/info.php | 2 +- htdocs/loan/note.php | 2 +- htdocs/theme/eldy/style.css.php | 36 +++----------- htdocs/theme/md/style.css.php | 12 +++-- 30 files changed, 386 insertions(+), 373 deletions(-) diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 4e05b019d08..b10463361f8 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -242,20 +242,8 @@ if ($resql) print '
    '; print '
    '."\n"; - print ''; - - if (! empty($arrayfields['aa.account_number']['checked'])) print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"],"aa.account_number","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.label']['checked'])) print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"],"aa.label","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.account_parent']['checked'])) print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"],"aa.account_parent", "", $param,'align="left"',$sortfield,$sortorder); - if (! empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'],$_SERVER["PHP_SELF"],'aa.pcg_type','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'],$_SERVER["PHP_SELF"],'aa.pcg_subtype','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'],$_SERVER["PHP_SELF"],'aa.active','',$param,'',$sortfield,$sortorder); - - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Line for search fields - print ''; + print ''; if (! empty($arrayfields['aa.account_number']['checked'])) print ''; if (! empty($arrayfields['aa.label']['checked'])) print ''; if (! empty($arrayfields['aa.account_parent']['checked'])) print ''; @@ -268,8 +256,16 @@ if ($resql) print ''; print ''; - $var = false; - + print ''; + if (! empty($arrayfields['aa.account_number']['checked'])) print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"],"aa.account_number","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.label']['checked'])) print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"],"aa.label","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.account_parent']['checked'])) print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"],"aa.account_parent", "", $param,'align="left"',$sortfield,$sortorder); + if (! empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'],$_SERVER["PHP_SELF"],'aa.pcg_type','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'],$_SERVER["PHP_SELF"],'aa.pcg_subtype','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'],$_SERVER["PHP_SELF"],'aa.active','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $accountstatic = new AccountingAccount($db); $accountparent = new AccountingAccount($db); @@ -281,7 +277,7 @@ if ($resql) $accountstatic->label = $obj->label; $accountstatic->account_number = $obj->account_number; - print ''; + print ''; // Account number if (! empty($arrayfields['aa.account_number']['checked'])) diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index 3a775149987..30466926f0a 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -806,7 +806,7 @@ if ($id) print ''; // Title line with search boxes - print ''; + print ''; $filterfound=0; foreach ($fieldlist as $field => $value) { @@ -831,14 +831,16 @@ if ($id) } if ($id == 4) print ''; print ''; - print ''; + print ''; + print ''; - print ''; + print ''; if ($num) { @@ -860,7 +862,9 @@ if ($id) // Show fields if (empty($reshook)) fieldList($fieldlist,$obj,$tabname[$id],'edit'); - print ''; + print ''; + print '"; if ($objp->amount < 0) @@ -568,3 +601,102 @@ else llxFooter(); $db->close(); + +/*Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line + * @param $db Object database object + * @param $bankId int bank line id + * @param $label + * + */ +function Get_attach_files($db, $bankId,$label=''){ + $out=''; + global$conf; + $sql='SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; + $sql.=' e.`ref` AS refe, sp.rowid AS ids, d.rowid AS idd'; + $sql.=' FROM '.MAIN_DB_PREFIX.'bank_url AS u'; + if ( !empty($label) || $label=='(CustomerInvoicePayment)'){ + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement AS p ON p.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture AS pf ON pf.fk_paiement = p.rowid'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture AS f ON f.rowid = pf.fk_facture'; + } + if( !empty($label) || $label=='(SupplierInvoicePayment)'){ + //invoice suplier (SupplierInvoicePayment) + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn AS fp ON fp.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS fpf ON fpf.fk_paiementfourn = fp.rowid'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS ff ON ff.rowid = fpf.fk_facturefourn'; + } + if( !empty($label) || $label=='(ExpenseReportPayment)'){ + //EXPENSEs (ExpenseReportPayment) + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_expensereport AS ep ON ep.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport AS e ON e.rowid = ep.fk_expensereport'; + } + if( !empty($label) || $label=='(DonationPayment)'){ + //donation + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_donation AS dp ON dp.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'don AS d ON d.rowid = dp.fk_donation'; + } + if( !empty($label) || $label=='(SalaryPayment)'){ + //loan +// $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_loan AS lp ON lp.fk_bank = u.fk_bank'; + //salary + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_salary AS sp ON sp.fk_bank = u.fk_bank'; + } + //END SQL + $sql.=" WHERE u.fk_bank in('".$bankId."')AND u.type in ('payment','payment_supplier','payment_expensereport','payment_salary','payment_donation' )"; + $resd = $db->query($sql); + $files=array(); + $link=''; + if ($resd) + { + $numd = $db->num_rows($resd); + $upload_dir =''; + $i=0; + if($numd>0) + { + + + $objd = $db->fetch_object($resd); + + switch($objd->type){ + case "payment": + $subdir=dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->facture->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=facture&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + + case "payment_supplier": + $subdir=get_exdir($objd->id,2,0,0,$objd,'invoice_supplier').$objd->reff; + $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=facture_fournisseur&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "payment_expensereport": + $subdir=dol_sanitizeFileName($objd->refe); + $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=expensereport&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "payment_salary": + $subdir=dol_sanitizeFileName($objd->ids); + $upload_dir = $conf->salaries->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=salaries&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "payment_donation": + $subdir=get_exdir(null,2,0,1,$objd,'donation'). '/'. dol_sanitizeFileName($objd->idd); + $upload_dir = $conf->don->dir_output . '/' . $subdir; + $link="../../document.php?modulepart=don&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + default: + break; + } + + if(!empty($upload_dir)){ + $files=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$','',SORT_ASC,1); + foreach ($files as $key => $file){ + $out.= '
    '.$file['name'].''; + } + $_SESSION["releve"][$num][]=$files; + } + } + } + $db->free($resd); + return $out; +} From ca72e5e19f04dd908c7fcd542d2c610164fcd151 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Wed, 5 Apr 2017 20:53:41 +0200 Subject: [PATCH 314/410] NEW : download button --- htdocs/compta/bank/releve.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 2ab6df9047f..4eb52dd2178 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -595,6 +595,9 @@ else print ""; print "\n"; + // download button + echo ''.$langs->trans('DownloadFile')." \n"; + } From 337eac30c17a8f08d38f8eed856423cc0b3f8ee0 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Wed, 5 Apr 2017 21:14:41 +0200 Subject: [PATCH 315/410] Update releve.php --- htdocs/compta/bank/releve.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 4eb52dd2178..2acb0b327ce 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -552,7 +552,7 @@ else dol_print_error($db); } } - print Get_attach_files($db,$objp->rowid,$objp->label); + print Get_attach_files($db,$objp->rowid,$num,$objp->label); print ""; if ($objp->amount < 0) @@ -608,10 +608,11 @@ $db->close(); /*Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line * @param $db Object database object * @param $bankId int bank line id - * @param $label + * @param $num int bank statement + * @param $label string label used to optimise the sql querry * */ -function Get_attach_files($db, $bankId,$label=''){ +function Get_attach_files($db, $bankId,$num,$label=''){ $out=''; global$conf; $sql='SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; From 18fc5bec9b143276c09df9b50ff8497d61b60a8c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 10:56:37 +0200 Subject: [PATCH 316/410] Better log --- htdocs/product/stock/class/mouvementstock.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 631f6697c33..6088c14ed60 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -176,8 +176,8 @@ class MouvementStock extends CommonObject if ($this->db->jdate($obj->eatby) != $eatby && $this->db->jdate($obj->eatby) != $eatbywithouthour) // We test date without hours and with hours for backward compatibility { // If found and eatby/sellby defined into table and provided and differs, return error - $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)); - dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)), LOG_ERR); + $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby), 'dayhour'), dol_print_date($eatby, 'dayhour')); + dol_syslog("ThisSerialAlreadyExistWithDifferentDate batch=".$batch.", eatby found into product_lot = ".$obj->eatby." = ".dol_print_date($this->db->jdate($obj->eatby), 'dayhourrfc')." so eatbywithouthour = ".$eatbywithouthour." = ".dol_print_date($eatbywithouthour)." - eatby provided = ".$eatby." = ".dol_print_date($eatby, 'dayhourrfc'), LOG_ERR); $this->db->rollback(); return -3; } From 6b2d8a3c34e911de4f110ae512d33565178c92ed Mon Sep 17 00:00:00 2001 From: arnaud Date: Thu, 6 Apr 2017 11:14:15 +0200 Subject: [PATCH 317/410] FIX limit+1 dosn't show Total line --- htdocs/compta/facture/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index b2b95d74963..14a5c484e8c 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -551,7 +551,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $nbtotalofrecords = $db->num_rows($result); } -$sql.= $db->plimit($limit+1,$offset); +$sql.= $db->plimit($limit,$offset); //print $sql; $resql = $db->query($sql); From e2ea5945ddc772a60ef2e5229fbe302c8126bb6b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 14:48:24 +0200 Subject: [PATCH 318/410] Work on look and feel v6 --- htdocs/adherents/class/adherent.class.php | 85 ++++++++--- htdocs/adherents/list.php | 6 +- htdocs/categories/photos.php | 16 +-- htdocs/categories/traduction.php | 4 +- htdocs/categories/viewcat.php | 4 +- htdocs/compta/bank/ligne.php | 16 ++- htdocs/core/class/commonobject.class.php | 4 +- htdocs/core/class/html.form.class.php | 4 +- htdocs/core/class/html.formfile.class.php | 19 ++- htdocs/core/lib/functions.lib.php | 3 +- htdocs/core/tpl/contacts.tpl.php | 4 +- htdocs/main.inc.php | 2 +- htdocs/projet/card.php | 13 +- htdocs/projet/class/task.class.php | 11 ++ htdocs/projet/contact.php | 13 +- htdocs/projet/element.php | 18 +-- htdocs/projet/ganttchart.inc.php | 4 +- htdocs/projet/ganttview.php | 13 +- htdocs/projet/tasks.php | 11 +- htdocs/projet/tasks/contact.php | 44 +++--- htdocs/projet/tasks/document.php | 31 +++- htdocs/projet/tasks/note.php | 31 ++-- htdocs/projet/tasks/task.php | 42 ++++-- htdocs/projet/tasks/time.php | 163 ++++++++++++---------- htdocs/user/class/user.class.php | 4 +- 25 files changed, 355 insertions(+), 210 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 833b5bf224e..f3dfd857973 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1570,40 +1570,85 @@ class Adherent extends CommonObject /** * Return clicable name (with picto eventually) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $maxlen length max libelle - * @param string $option Page lien + * @param int $withpictoimg 0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) + * @param int $maxlen length max label + * @param string $option Page for link + * @param string $mode ''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref + * @param string $morecss Add more css on link * @return string Chaine avec URL */ - function getNomUrl($withpicto=0,$maxlen=0,$option='card') + function getNomUrl($withpictoimg=0,$maxlen=0,$option='card',$mode='ref',$morecss='') { - global $langs; + global $conf, $langs; - $result=''; - $label = '' . $langs->trans("ShowMember") . ''; + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; + + $result=''; $label=''; + $link=''; $linkstart=''; $linkend=''; + + if (! empty($this->photo)) + { + $label.= '
    '; + $label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); + $label.= '
    '; + } + + $label.= '
    '; + $label.= '' . $langs->trans("Member") . ''; if (! empty($this->ref)) $label.= '
    ' . $langs->trans('Ref') . ': ' . $this->ref; if (! empty($this->firstname) || ! empty($this->lastname)) $label.= '
    ' . $langs->trans('Name') . ': ' . $this->getFullName($langs); - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; - - $link=''; $linkend=''; + $label.='
    '; + if ($option == 'card' || $option == 'category') { - $link = ''; + $link = 'ref,$maxlen):$this->ref) : '').$linkend; + + $linkclose=""; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $langs->load("users"); + $label=$langs->trans("ShowUser"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } + + $link.=$linkclose.'>'; + $linkend=''; + + //if ($withpictoimg == -1) $result.='
    '; + $result.=$link; + if ($withpictoimg) + { + $paddafterimage=''; + if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"'; + // Only picto + if ($withpictoimg > 0) $picto='
    '.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'
    '; + // Picto must be a photo + else $picto='
    '.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'
    '; + $result.=$picto; + } + if ($withpictoimg > -2 && $withpictoimg != 2) + { + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='
    '; + if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen); + elseif ($mode == 'ref') $result.=$this->id; + else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen); + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='
    '; + } + $result.=$linkend; + //if ($withpictoimg == -1) $result.='
    '; + return $result; } diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index e492e31b440..4589cdc754f 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -611,6 +611,7 @@ while ($i < min($num, $limit)) $memberstatic->statut=$obj->statut; $memberstatic->datefin= $datefin; $memberstatic->socid = $obj->fk_soc; + $memberstatic->photo = $obj->photo; if (! empty($obj->fk_soc)) { $memberstatic->fetch_thirdparty(); @@ -619,8 +620,7 @@ while ($i < min($num, $limit)) $companyname=$obj->company; } - $var=!$var; - print "
    "; + print ''; if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { @@ -631,7 +631,7 @@ while ($i < min($num, $limit)) if (! empty($arrayfields['d.ref']['checked'])) { print "\n"; } // Firstname diff --git a/htdocs/categories/photos.php b/htdocs/categories/photos.php index ee03f9f4771..100d2d0d48e 100644 --- a/htdocs/categories/photos.php +++ b/htdocs/categories/photos.php @@ -105,7 +105,7 @@ if ($object->id) $head = categories_prepare_head($object,$type); - dol_fiche_head($head, 'photos', $title, 0, 'category'); + dol_fiche_head($head, 'photos', $title, -1, 'category'); $linkback = ''.$langs->trans("BackToList").''; @@ -130,6 +130,7 @@ if ($object->id) print '
    '; + print '
    '; print '
    '; print '
    '; + print ''; if ($filterfound) { $searchpitco=$form->showFilterAndCheckAddButtons(0); print $searchpitco; } print '
    '; + print ''; print ''; print ''; print ''; diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index cae9295229b..dda7d545043 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -312,22 +312,8 @@ if ($result) print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, '', 0, '', '', $limit); print ''; - print ''; - print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "p.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("OnSell"), $_SERVER["PHP_SELF"], "p.tosell", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("OnBuy"), $_SERVER["PHP_SELF"], "p.tobuy", "", $param, 'align="center"', $sortfield, $sortorder); - if ($accounting_product_mode == 'ACCOUNTANCY_BUY') { - $fieldtosortaccount="p.accountancy_code_buy"; - } - else $fieldtosortaccount="p.accountancy_code_sell"; - print_liste_field_titre($langs->trans("CurrentDedicatedAccountingAccount"), $_SERVER["PHP_SELF"], $fieldtosortaccount, "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AssignDedicatedAccountingAccount")); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print ''; - - print ''; + + print ''; print ''; print ''; if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print ''; @@ -342,12 +328,28 @@ if ($result) print ' '.$langs->trans("or").' '.$form->selectarray('search_current_account_valid', $listofvals, $search_current_account_valid, 1); print ''; print ''; - print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "p.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("OnSell"), $_SERVER["PHP_SELF"], "p.tosell", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("OnBuy"), $_SERVER["PHP_SELF"], "p.tobuy", "", $param, 'align="center"', $sortfield, $sortorder); + if ($accounting_product_mode == 'ACCOUNTANCY_BUY') { + $fieldtosortaccount="p.accountancy_code_buy"; + } + else $fieldtosortaccount="p.accountancy_code_sell"; + print_liste_field_titre($langs->trans("CurrentDedicatedAccountingAccount"), $_SERVER["PHP_SELF"], $fieldtosortaccount, "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AssignDedicatedAccountingAccount")); + $clickpitco=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($clickpitco, '', '', '', '', 'align="center"'); + print ''; + $product_static = new Product($db); $var = true; @@ -381,8 +383,7 @@ if ($result) $compta_prodbuy_id = $aarowid_servbuy; } - $var = ! $var; - print ''; + print ''; print ''; print ""; $i ++; diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 8f6fab3ec3f..5f4801da32c 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -182,6 +182,22 @@ else { } print '
     '; - $searchpitco=$form->showFilterAndCheckAddButtons(1, 'checkforselect', 1); + print ''; + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; print $product_static->getNomUrl(1); @@ -440,7 +441,7 @@ if ($result) } // Checkbox select - print ''; + print ''; print '
    '; + + print ''; + print ''; + print ''; + + print ''; + print ''; print_liste_field_titre($langs->trans("AccountAccounting"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder); print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "t.label_compte", "", $options, "", $sortfield, $sortorder); @@ -191,28 +207,6 @@ else { print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder); print "\n"; - print ''; - print ''; - - print ''; - print ''; - print ''; - - print ''; - - print ''; - - $var = True; - $total_debit = 0; $total_credit = 0; $sous_total_debit = 0; @@ -220,7 +214,6 @@ else { $displayed_account = ""; foreach ($object->lines as $line) { - $var = ! $var; $link = ''; $total_debit += $line->debit; $total_credit += $line->credit; @@ -229,7 +222,7 @@ else { if (empty($description)) { $link = '' . img_edit_add() . ''; } - print ''; + print ''; // Permet d'afficher le compte comptable if ($root_account_description != $displayed_account) { diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index ae38233afac..9cd649ce4be 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -371,20 +371,8 @@ print ''; -print_liste_field_titre($langs->trans("TransactionNumShort"), $_SERVER['PHP_SELF'], "t.piece_num", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Docdate"), $_SERVER['PHP_SELF'], "t.doc_date", "", $param, 'align="center"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("AccountAccountingShort"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Code_tiers"), $_SERVER['PHP_SELF'], "t.code_tiers", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "t.label_compte", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $param, 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $param, 'align="center"', $sortfield, $sortorder); -print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder); -print "\n"; -print ''; +print ''; print ''; print ''; print ''; print ''; print ''; print ''; -$var = True; +print ''; +print_liste_field_titre($langs->trans("TransactionNumShort"), $_SERVER['PHP_SELF'], "t.piece_num", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Docdate"), $_SERVER['PHP_SELF'], "t.doc_date", "", $param, 'align="center"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("AccountAccountingShort"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Code_tiers"), $_SERVER['PHP_SELF'], "t.code_tiers", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "t.label_compte", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $param, 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $param, 'align="center"', $sortfield, $sortorder); +$checkpicto=''; +if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); +print_liste_field_titre($checkpicto, $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder); +print "\n"; + $total_debit = 0; $total_credit = 0; @@ -431,7 +433,7 @@ foreach ($object->lines as $line ) { $total_debit += $line->debit; $total_credit += $line->credit; - print ''; + print ''; print ''; print ''; diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index a759472304e..a015fa05929 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -256,22 +256,7 @@ if ($result) { print '
    '; print '
    '; + print $langs->trans('From'); + print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, ''); + print ' '; + print $langs->trans('to'); + print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array(), 1, 1, ''); + print ''; + $searchpitco=$form->showFilterAndCheckAddButtons(0); + print $searchpitco; + print '
    '; - print $langs->trans('From'); - print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, ''); - print '
    '; - print $langs->trans('to'); - print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array(), 1, 1, ''); - print '
       '; - $searchpitco=$form->showFilterAndCheckAddButtons(0); - print $searchpitco; - print '
    '; print $langs->trans('From') . ': '; @@ -415,12 +403,26 @@ print '  '; -$searchpitco=$form->showFilterAndCheckAddButtons(0); -print $searchpitco; +$searchpicto=$form->showFilterButtons(); +print $searchpicto; print '
    ' . $line->piece_num . '' . dol_print_date($line->doc_date, 'day') . '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "fd.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, fd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "fd.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "fd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "fd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Country"), $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATIntra"), $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; - - print ''; + print ''; print ''; print ''; print ''; @@ -284,16 +269,30 @@ if ($result) { print ''; print ''; print '\n"; + + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "fd.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, fd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "fd.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "fd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "fd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Country"), $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATIntra"), $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); + $clickpicto=$form->showCheckAddButtons(); + print_liste_field_titre($clickpicto, '', '', '', '', 'align="center"'); + print "\n"; $facture_static = new Facture($db); $product_static = new Product($db); - $var = True; while ( $objp = $db->fetch_object($result) ) { - $var = ! $var; $codecompta = length_accountg($objp->account_number) . ' - ' . $objp->label_compte; $facture_static->ref = $objp->facnumber; @@ -304,7 +303,7 @@ if ($result) { $product_static->type = $objp->product_type; $product_static->label = $objp->product_label; - print ''; + print ''; print ''; @@ -335,7 +334,7 @@ if ($result) { print ''; print ''; print ''; - print ''; + print ''; print ""; $i ++; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 09ad316a398..e8e10b4a0be 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -271,22 +271,9 @@ if ($result) { print '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons(1); - print $searchpitco; + $searchpicto=$form->showFilterButtons(); + print $searchpicto; print "
    ' . $objp->rowid . '' . $objp->country .'' . $objp->tva_intra . '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); - print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; // We add search filter - print ''; + print ''; print ''; print ''; print ''; @@ -298,11 +285,27 @@ if ($result) { print ''; print ''; print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); + print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); + $checkpicto=''; + if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($checkpitco, '', '', '', '', 'align="center"'); + print "\n"; + $facture_static = new Facture($db); $product_static = new Product($db); $form = new Form($db); diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index 56298045532..20994d76a93 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -233,20 +233,7 @@ if ($result) { print '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - print $searchpitco; + $searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre(''); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; - - print ''; + print ''; print ''; print ''; print ''; @@ -257,11 +244,25 @@ if ($result) { print ''; print ''; print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre(''); + $checkpicto=$form->showCheckAddButtons(); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + $expensereport_static = new ExpenseReport($db); $var = True; @@ -300,7 +301,7 @@ if ($result) { print img_edit(); print ''; - print ''; + print ''; print ""; $i ++; diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 5bb232fc7c1..49a63a15698 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -259,21 +259,9 @@ if ($result) { print '
    '; print '
    '; - $searchpicto=$form->showFilterAndCheckAddButtons(1); + $searchpicto=$form->showFilterButtons(); print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); - print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; // We add search filter - print ''; + print ''; print ''; print ''; print ''; @@ -284,11 +272,27 @@ if ($result) { print ''; print ''; print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); + print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); + $checkpicto=''; + if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + + $expensereport_static = new ExpenseReport($db); $form = new Form($db); diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index 121ba0e9f46..1f0d06fbec6 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -239,21 +239,7 @@ if ($result) { print '
    '; print '
    '; - $searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpicto=$form->showFilterButtons(); print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; - - print ''; + print ''; print ''; print ''; print ''; @@ -265,18 +251,32 @@ if ($result) { print ''; print ''; print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); + $checkpicto=$form->showCheckAddButtons(); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + $facturefournisseur_static = new FactureFournisseur($db); $product_static = new Product($db); - $var = True; - while ( $i < min($num_lines, $limit) ) { + while ($i < min($num_lines, $limit)) { $objp = $db->fetch_object($result); - $var = ! $var; + $codecompta = length_accountg($objp->account_number) . ' - ' . $objp->label; $facturefournisseur_static->ref = $objp->facnumber; @@ -287,7 +287,7 @@ if ($result) { $product_static->type = $objp->type; $product_static->label = $objp->product_label; - print ''; + print ''; print ''; @@ -320,7 +320,7 @@ if ($result) { print img_edit(); print ''; - print ''; + print ''; print ""; $i ++; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 19ef52f0d85..9b42337852c 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -267,24 +267,11 @@ if ($result) { $moreforfilter = ''; print '
    '; - print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons(1); - print $searchpitco; + $searchpicto=$form->showFilterButtons(); + print $searchpicto; print '
    ' . $objp->rowid . '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); - print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; + + print '
    '."\n"; // We add search filter - print ''; + print ''; print ''; print ''; print ''; @@ -297,11 +284,28 @@ if ($result) { print ''; print ''; print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); + print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); + $checkpicto=''; + if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + $facturefourn_static = new FactureFournisseur($db); $productfourn_static = new ProductFournisseur($db); $form = new Form($db); diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index 4cb63b7d905..d0ba0373457 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -225,29 +225,8 @@ if ($resql) print '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - print $searchpitco; + $searchpicto=$form->showFilterButtons(); + print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("RefPayment"),$_SERVER["PHP_SELF"],"p.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"c.libelle","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) - { - print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - } - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"p.amount","",$param,'align="right"',$sortfield,$sortorder); - //print_liste_field_titre($langs->trans("Invoices"),"","","",$param,'align="left"',$sortfield,$sortorder); - - $parameters=array(); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - - if (! empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"p.statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Lines for filters fields - print ''; + print ''; print ''; @@ -285,12 +264,32 @@ if ($resql) } print "\n"; - $var=true; + print ''; + print_liste_field_titre($langs->trans("RefPayment"),$_SERVER["PHP_SELF"],"p.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"c.libelle","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) + { + print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); + } + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"p.amount","",$param,'align="right"',$sortfield,$sortorder); + //print_liste_field_titre($langs->trans("Invoices"),"","","",$param,'align="left"',$sortfield,$sortorder); + + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + if (! empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"p.statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); - $var=!$var; - print ""; + + print ''; print ''; } - print ''; // Notification for this thirdparty + /*print ''; // Notification for this thirdparty print ''; + print '';*/ + print '
    '; print ''; print '
    '; $paymentstatic->id=$objp->rowid; diff --git a/htdocs/compta/salaries/index.php b/htdocs/compta/salaries/index.php index 88414e45566..a6d99cbdaad 100644 --- a/htdocs/compta/salaries/index.php +++ b/htdocs/compta/salaries/index.php @@ -85,7 +85,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP * View */ -llxHeader(); +llxHeader('', $langs->trans("Salaries")); $form = new Form($db); $salstatic = new PaymentSalary($db); @@ -155,18 +155,7 @@ if ($result) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"s.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"u.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"s.label","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"s.datep","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PaymentMode"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("BankAccount"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"s.amount","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; // Ref print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"s.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"u.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"s.label","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"s.datep","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PaymentMode"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("BankAccount"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"s.amount","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + print "\n"; while ($i < min($num,$limit)) diff --git a/htdocs/compta/sociales/index.php b/htdocs/compta/sociales/index.php index 66d6a65dd56..706c75fab07 100644 --- a/htdocs/compta/sociales/index.php +++ b/htdocs/compta/sociales/index.php @@ -177,18 +177,7 @@ if ($resql) print '
    '; print '
    '; print ''; @@ -198,6 +187,17 @@ if ($result) print $searchpitco; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"id","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"cs.libelle","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PeriodEndDate"),$_SERVER["PHP_SELF"],"periode","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"cs.amount","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateDue"),$_SERVER["PHP_SELF"],"cs.date_ech","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cs.paye","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; // Ref print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"id","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"cs.libelle","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PeriodEndDate"),$_SERVER["PHP_SELF"],"periode","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"cs.amount","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateDue"),$_SERVER["PHP_SELF"],"cs.date_ech","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cs.paye","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $i=0; $totalarray=array(); while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); - $var = !$var; - print ""; + print ''; // Ref print '"; + print ""; // Photo - Name print ''; print '
    '; print ''; @@ -218,14 +207,24 @@ if ($resql) print '
    '; diff --git a/htdocs/compta/tva/reglement.php b/htdocs/compta/tva/reglement.php index 1a45b8a91c7..15a6df0a717 100644 --- a/htdocs/compta/tva/reglement.php +++ b/htdocs/compta/tva/reglement.php @@ -157,19 +157,10 @@ if ($result) print_barre_liste($langs->trans("VATPayments"),$page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$totalnboflines, 'title_accountancy', 0, '', '', $limit); + print '
    '; print ''; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"t.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"t.label","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateValue"),$_SERVER["PHP_SELF"],"dv","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"t.amount","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - print ''; + print ''; print ''; print ''; print ''; @@ -196,10 +187,20 @@ if ($result) print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"t.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"t.label","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateValue"),$_SERVER["PHP_SELF"],"dv","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"t.amount","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + while ($i < min($num,$limit)) { $obj = $db->fetch_object($result); - $var=!$var; if ($obj->payment_code <> '') { @@ -210,7 +211,7 @@ if ($result) $type = ''; } - print ""; + print ''; $tva_static->id=$obj->rowid; $tva_static->ref=$obj->rowid; @@ -254,7 +255,8 @@ if ($result) print ""; print "
     
     
    "; - + print '
    '; + print ''; $db->free($result); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 99b27c20822..a01d54f0bef 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1634,7 +1634,7 @@ class Form { if ($value['id'] == $ownerid) continue; $userstatic->fetch($value['id']); - $out.=$userstatic->getNomUrl(1); + $out.=$userstatic->getNomUrl(-1); if ($i == 0) { $ownerid = $value['id']; $out.=' ('.$langs->trans("Owner").')'; } if ($nbassignetouser > 1 && $action != 'view') $out.=' '; //$out.=' '.($value['mandatory']?$langs->trans("Mandatory"):$langs->trans("Optional")); diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index d8a7cb1b34c..fd80124e7df 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -93,11 +93,15 @@ print ' padding: 1em 15px 1em 40px; } li.lilevel1 { - padding: 1em 15px 0.5em 20px; - border-top: 1px solid #ccc; + padding: 1em 15px 0.5em 40px; + border-top: 1px solid #aaa; margin-right: 20px; border-right: 0px ! important; } + li.lilevel1:first-child { + margin-right: 0px; + margin-left: 0px; + } li.lilevel1 a { padding-bottom: 5px; } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index bbe9febd481..e6e154220b8 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -763,7 +763,6 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') while ($i < $num) { $obj = $db->fetch_object($result); - $var = !$var; $contactstatic->id = $obj->rowid; $contactstatic->ref = $obj->ref; @@ -789,7 +788,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') $contactstatic->setGenderFromCivility(); - print "
    '; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6028f9bcabc..e51541272bd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2038,12 +2038,12 @@ function dol_print_address($address, $htmlid, $mode, $id, $noprint=0, $charfornl if ($showgmap) { $url=dol_buildpath('/google/gmaps.php?mode='.$mode.'&id='.$id,1); - $out.=' '; + $out.=' '; } if ($showomap) { $url=dol_buildpath('/openstreetmap/maps.php?mode='.$mode.'&id='.$id,1); - $out.=' '; + $out.=' '; } } } diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 3874afb5198..7207f8f2189 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1005,18 +1005,25 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $i = 0; if ($numr > 0) - while ($i < $numr) { - $objp = $db->fetch_object($resql); - - if ($objp->nature == 1) $nature="sells"; - if ($objp->nature == 2) $nature="purchases"; - if ($objp->nature == 3) $nature="bank"; - if ($objp->nature == 4) $nature="various"; - if ($objp->nature == 9) $nature="hasnew"; - - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&code_journal='.$objp->code,dol_trunc($objp->label,25),2,$user->rights->accounting->comptarapport->lire); - $i++; + while ($i < $numr) + { + $objp = $db->fetch_object($resql); + + if ($objp->nature == 1) $nature="sells"; + if ($objp->nature == 2) $nature="purchases"; + if ($objp->nature == 3) $nature="bank"; + if ($objp->nature == 4) $nature="various"; + if ($objp->nature == 9) $nature="hasnew"; + + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&code_journal='.$objp->code,dol_trunc($objp->label,25),2,$user->rights->accounting->comptarapport->lire); + $i++; + } + } + else + { + // Should not happend. Entries are added + $newmenu->add('',$langs->trans("NoJournalDefined"), 2, $user->rights->accounting->comptarapport->lire); } } else dol_print_error($db); @@ -1075,7 +1082,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu // Fiscal year if ($conf->global->MAIN_FEATURES_LEVEL > 0) // Not yet used. In a future will lock some periods. { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"),1,$user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear'); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_periods", $langs->trans("FiscalPeriod"),1,$user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear'); } } diff --git a/htdocs/don/list.php b/htdocs/don/list.php index d925573b859..1e08cbae121 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -160,23 +160,8 @@ if ($resql) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"d.rowid","", $param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"d.societe","", $param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname","", $param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"d.datedon","", $param,'align="center"',$sortfield,$sortorder); - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - print_liste_field_titre($langs->trans("Project"),$_SERVER["PHP_SELF"],"fk_projet","", $param,"",$sortfield,$sortorder); - } - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"d.amount","", $param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"d.fk_statut","", $param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - // Filters lines - print ''; + print ''; print ''; @@ -203,12 +188,26 @@ if ($resql) print ''; print "\n"; - $var=True; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"d.rowid","", $param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"d.societe","", $param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname","", $param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"d.datedon","", $param,'align="center"',$sortfield,$sortorder); + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + print_liste_field_titre($langs->trans("Project"),$_SERVER["PHP_SELF"],"fk_projet","", $param,"",$sortfield,$sortorder); + } + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"d.amount","", $param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"d.fk_statut","", $param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); - $var=!$var; - print ""; + + print ''; $donationstatic->id=$objp->rowid; $donationstatic->ref=$objp->rowid; $donationstatic->lastname=$objp->lastname; diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index 8d55404659e..952d1e13dbd 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -700,20 +700,8 @@ if (empty($action)) print '
    '; print '
    '; print ''; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans('RefPayment'),$_SERVER["PHP_SELF"],'p.rowid','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'dp','',$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('ThirdParty'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Type'),$_SERVER["PHP_SELF"],'c.libelle','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Account'),$_SERVER["PHP_SELF"],'ba.label','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Amount'),$_SERVER["PHP_SELF"],'p.amount','',$param,'align="right"',$sortfield,$sortorder); - //print_liste_field_titre($langs->trans('Invoice'),$_SERVER["PHP_SELF"],'ref_supplier','',$param,'',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - // Lines for filters fields - print ''; + print ''; print ''; @@ -739,11 +727,23 @@ if (empty($action)) print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans('RefPayment'),$_SERVER["PHP_SELF"],'p.rowid','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'dp','',$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('ThirdParty'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Type'),$_SERVER["PHP_SELF"],'c.libelle','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Account'),$_SERVER["PHP_SELF"],'ba.label','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Amount'),$_SERVER["PHP_SELF"],'p.amount','',$param,'align="right"',$sortfield,$sortorder); + //print_liste_field_titre($langs->trans('Invoice'),$_SERVER["PHP_SELF"],'ref_supplier','',$param,'',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); $var=!$var; - print ''; + print ''; // Ref payment print ''; diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 4b1384aeedb..e063734cc51 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -98,13 +98,30 @@ if (empty($reshook)) $datestart = dol_mktime(12, 0, 0, GETPOST('startmonth','int'), GETPOST('startday','int'), GETPOST('startyear','int')); $dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); $capital = price2num(GETPOST('capital')); - + $rate = GETPOST('rate'); + if (! $capital) { + $error++; $action = 'create'; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("LoanCapital")), null, 'errors'); - $action = 'create'; } - else + if (! $datestart) + { + $error++; $action = 'create'; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateStart")), null, 'errors'); + } + if (! $dateend) + { + $error++; $action = 'create'; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateEnd")), null, 'errors'); + } + if ($rate == '') + { + $error++; $action = 'create'; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rate")), null, 'errors'); + } + + if (! $error) { $object->label = GETPOST('label'); $object->fk_bank = GETPOST('accountid'); @@ -112,7 +129,7 @@ if (empty($reshook)) $object->datestart = $datestart; $object->dateend = $dateend; $object->nbterm = GETPOST('nbterm'); - $object->rate = GETPOST('rate'); + $object->rate = $rate; $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); $object->fk_project = GETPOST('fk_project'); @@ -128,7 +145,9 @@ if (empty($reshook)) $id=$object->create($user); if ($id <= 0) { + $error++; setEventMessages($object->error, $object->errors, 'errors'); + $action = 'create'; } } } @@ -263,21 +282,21 @@ if ($action == 'create') // Date Start print ""; - print ''; // Date End print ""; - print ''; // Number of terms - print ''; + print ''; // Rate - print ''; + print ''; // Project if (! empty($conf->projet->enabled)) @@ -296,8 +315,8 @@ if ($action == 'create') // Note Private print ''; - print ''; - print ''; + print ''; - print ''; - print ''; + print ''; @@ -463,7 +482,7 @@ if ($id > 0) } // Date start - print ""; + print '"; print ""; // Date end - print ""; + print '"; print "'; print ''; }*/ - if ($user->admin) + + /*if ($user->admin) { $var = ! $var; print ''; - } + }*/ print '
    '; print ''; print '
    '.img_object($langs->trans('ShowPayment'),'payment').' '.$objp->pid.'
    '.$langs->trans("DateStart").''; + print ''.$langs->trans("DateStart").''; print $form->select_date($datestart?$datestart:-1,'start','','','','add',1,1,1); print '
    '.$langs->trans("DateEnd").''; + print ''.$langs->trans("DateEnd").''; print $form->select_date($dateend?$dateend:-1,'end','','','','add',1,1,1); print '
    '.$langs->trans("Nbterms").'
    '.$langs->trans("Nbterms").'
    '.$langs->trans("Rate").' %
    '.$langs->trans("Rate").' %
    '.$langs->trans('NotePrivate').''; + print ''.$langs->trans('NotePrivate').''; $doleditor = new DolEditor('note_private', GETPOST('note_private', 'alpha'), '', 160, 'dolibarr_notes', 'In', false, true, true, ROWS_6, '90%'); print $doleditor->Create(1); @@ -306,8 +325,8 @@ if ($action == 'create') // Note Public print '
    '.$langs->trans('NotePublic').''; + print ''.$langs->trans('NotePublic').''; $doleditor = new DolEditor('note_public', GETPOST('note_public', 'alpha'), '', 160, 'dolibarr_notes', 'In', false, true, true, ROWS_6, '90%'); print $doleditor->Create(1); print '
    ".$langs->trans("DateStart")."
    '.$langs->trans("DateStart").""; if ($action == 'edit') { @@ -476,7 +495,7 @@ if ($id > 0) print "
    ".$langs->trans("DateEnd")."
    '.$langs->trans("DateEnd").""; if ($action == 'edit') { diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index bb51cf3b8f1..d9d4da6fb20 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -129,7 +129,7 @@ class Loan extends CommonObject */ function create($user) { - global $conf; + global $conf, $langs; $error=0; @@ -155,7 +155,7 @@ class Loan extends CommonObject } if (($conf->accounting->enabled) && empty($this->account_capital) && empty($this->account_insurance) && empty($this->account_interest)) { - $this->error="ErrorAccountingParameter"; + $this->error=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Accounting")); return -2; } diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php index 575be293de0..3e0654ace3f 100644 --- a/htdocs/loan/document.php +++ b/htdocs/loan/document.php @@ -85,7 +85,7 @@ if ($object->id) $head = loan_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("Loan"), 0, 'bill'); + dol_fiche_head($head, 'documents', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
    '; // Ref loan diff --git a/htdocs/loan/index.php b/htdocs/loan/index.php index d2a60973a7f..fdc8cf67073 100644 --- a/htdocs/loan/index.php +++ b/htdocs/loan/index.php @@ -124,17 +124,8 @@ if ($resql) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"l.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"l.label","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("LoanCapital"),$_SERVER["PHP_SELF"],"l.capital","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"l.datestart","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"l.paid","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - // Filters lines - print ''; + print ''; print ''; print ''; print ''; @@ -146,6 +137,15 @@ if ($resql) print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"l.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"l.label","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("LoanCapital"),$_SERVER["PHP_SELF"],"l.capital","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"l.datestart","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"l.paid","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); @@ -154,7 +154,7 @@ if ($resql) $loan_static->label = $obj->label; $var = !$var; - print ""; + print ''; // Ref print ''; diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php index 87bd25fbe3b..f61b9312432 100644 --- a/htdocs/loan/info.php +++ b/htdocs/loan/info.php @@ -53,7 +53,7 @@ $object->info($id); $head = loan_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("Loan"), 0, 'bill'); +dol_fiche_head($head, 'info', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
    '; // Ref loan diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index b03880a832e..e28320470a2 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -70,7 +70,7 @@ if ($id > 0) $head = loan_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("Loan"), 0, 'bill'); + dol_fiche_head($head, 'note', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
    '; // Ref loan diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 913bcac5f30..e270cc3b030 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -590,7 +590,8 @@ div.myavailability { .checkallactions { vertical-align: text-bottom; margin-top: 6px; - margin-left: 4px; + margin-left: 4px; /* left must be same than right to keep checkbox centered */ + margin-right: 4px; /* left must be same than right to keep checkbox centered */ } .selectlimit, .marginrightonly { margin-right: 10px !important; @@ -1736,7 +1737,7 @@ div.vmenu, td.vmenu { } #menu_contenu_logo { padding-top: 0; } .companylogo { } -.searchform { padding-top: 4px; } +.searchform { padding-top: 10px; } a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active { white-space: nowrap; font-size:px; font-family: ; text-align: ; font-weight: bold; } font.vmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; } @@ -2434,18 +2435,7 @@ div.pagination li span:focus { -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); -webkit-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); - /* - color: #000; - background-color: #eee; - border-color: #ccc; - - background-image: -moz-linear-gradient(top, #eee, #ddd); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#eee), to(#ddd)); - background-image: -webkit-linear-gradient(top, #eee, #ddd); - background-image: -o-linear-gradient(top, #eee, #ddd); - background-image: linear-gradient(to bottom, #eee, #ddd); - background-repeat: repeat-x; -*/ + padding-top: 8px; } div.pagination li .active a, div.pagination li .active span, @@ -2622,7 +2612,7 @@ tr.liste_titre_topborder td { .liste_titre td a.notasortlink:hover { background: transparent; } -tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ +tr.liste_titre:last-child th.liste_titre, tr.liste_titre:last-child th.liste_titre_sel, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ border-bottom: 1px solid #ddd; } @@ -4316,6 +4306,7 @@ ul.ulmenu { } .alilevel0 { color: rgb() !important; + background: #f8f8f8 } .ulmenu { box-shadow: none !important; @@ -4339,24 +4330,9 @@ ul.ulmenu { color: # !important; text-shadow: none !important; } -/* -.ui-btn-up-c { - background: transparent; -} -*/ div.tabsElem a.tab { background: transparent; } - -/*.ui-controlgroup-horizontal .ui-btn.ui-first-child { --webkit-border-top-left-radius: 6px; -border-top-left-radius: 6px; -} -.ui-controlgroup-horizontal .ui-btn.ui-last-child { --webkit-border-top-right-radius: 6px; -border-top-right-radius: 6px; -}*/ - .alilevel1 { color: rgb() !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 947b8a57168..6885bfad144 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1768,7 +1768,7 @@ div.vmenu, td.vmenu { } #menu_contenu_logo { padding-right: 4px; } .companylogo { padding-top: 4px; } -.searchform { padding-top: 8px; } +.searchform { padding-top: 10px; } a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active { white-space: nowrap; font-size:px; font-family: ; text-align: ; font-weight: bold; } font.vmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; } @@ -2447,6 +2447,7 @@ div.pagination li { div.pagination li.pagination a, div.pagination li.pagination span { padding: 6px 12px; + padding-top: 8px; line-height: 1.42857143; color: #000; text-decoration: none; @@ -2486,9 +2487,10 @@ div.pagination li a:hover, div.pagination li span:hover, div.pagination li a:focus, div.pagination li span:focus { - color: #000; - background-color: #eee; - border-color: #ddd; + color: #000; + background-color: #eee; + border-color: #ddd; + padding-top: 8px; } div.pagination li .active a, div.pagination li .active span, @@ -2700,7 +2702,7 @@ tr.liste_titre_topborder td { .liste_titre td a.notasortlink:hover { background: transparent; } -tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ +tr.liste_titre:last-child th.liste_titre, tr.liste_titre:last-child th.liste_titre_sel, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ border-bottom: 1px solid rgb(); } From 17a1874e36810047f0ab66d9e3ea9b89f81e823f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 13:43:05 +0200 Subject: [PATCH 285/410] FIX Counter of notification of a thirdparty --- htdocs/core/class/notify.class.php | 80 ++++++++++++++++-------------- htdocs/societe/notify/card.php | 16 ++++-- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index fd3b1e7187d..1205f0c5c63 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -117,9 +117,10 @@ class Notify * @param int $socid Id of third party or 0 for all thirdparties or -1 for no thirdparties * @param Object $object Object the notification is about (need it to check threshold value of some notifications) * @param int $userid Id of user or 0 for all users or -1 for no users + * @param array $scope Scope where to search * @return array|int <0 if KO, array of notifications to send if OK */ - function getNotificationsArray($notifcode,$socid=0,$object=null,$userid=0) + function getNotificationsArray($notifcode, $socid=0, $object=null, $userid=0, $scope=array('thirdparty', 'user', 'global')) { global $conf, $user; @@ -131,7 +132,7 @@ class Notify if (! $error) { - if ($socid >= 0) + if ($socid >= 0 && in_array('thirdparty', $scope)) { $sql = "SELECT a.code, c.email, c.rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; @@ -178,7 +179,7 @@ class Notify if (! $error) { - if ($userid >= 0) + if ($userid >= 0 && in_array('user', $scope)) { $sql = "SELECT a.code, c.email, c.rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; @@ -223,42 +224,45 @@ class Notify if (! $error) { - // List of notifications enabled for fixed email - foreach($conf->global as $key => $val) + if (in_array('global', $scope)) { - if ($notifcode) - { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; - } - else - { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; - } - - $threshold = (float) $reg[1]; - if ($valueforthreshold < $threshold) continue; - - $tmpemail=explode(',',$val); - foreach($tmpemail as $key2 => $val2) - { - $newval2=trim($val2); - if ($newval2 == '__SUPERVISOREMAIL__') - { - if ($user->fk_user > 0) - { - $tmpuser=new User($this->db); - $tmpuser->fetch($user->fk_user); - if ($tmpuser->email) $newval2=trim($tmpuser->email); - else $newval2=''; - } - else $newval2=''; - } - if ($newval2) - { - $isvalid=isValidEmail($newval2, 0); - if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid); - } - } + // List of notifications enabled for fixed email + foreach($conf->global as $key => $val) + { + if ($notifcode) + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } + else + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } + + $threshold = (float) $reg[1]; + if ($valueforthreshold < $threshold) continue; + + $tmpemail=explode(',',$val); + foreach($tmpemail as $key2 => $val2) + { + $newval2=trim($val2); + if ($newval2 == '__SUPERVISOREMAIL__') + { + if ($user->fk_user > 0) + { + $tmpuser=new User($this->db); + $tmpuser->fetch($user->fk_user); + if ($tmpuser->email) $newval2=trim($tmpuser->email); + else $newval2=''; + } + else $newval2=''; + } + if ($newval2) + { + $isvalid=isValidEmail($newval2, 0); + if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid); + } + } + } } } diff --git a/htdocs/societe/notify/card.php b/htdocs/societe/notify/card.php index 63d33dcee1d..d7445233c71 100644 --- a/htdocs/societe/notify/card.php +++ b/htdocs/societe/notify/card.php @@ -188,11 +188,16 @@ if ($result > 0) print '
    '; } - print ''; + print ''; // Notification for this thirdparty print ''; print '
    '.$loan_static->getNomUrl(1, 42).'
    '.$langs->trans("NbOfActiveNotifications").'
    '.$langs->trans("NbOfActiveNotifications").''; + $nbofrecipientemails=0; $notify=new Notify($db); - $tmparray = $notify->getNotificationsArray('', $object->id); - print count($tmparray); + $tmparray = $notify->getNotificationsArray('', $object->id, null, 0, array('thirdparty')); + foreach($tmparray as $tmpkey => $tmpval) + { + if (! empty($tmpkey)) $nbofrecipientemails++; + } + print $nbofrecipientemails; print '
    '; @@ -394,13 +399,14 @@ if ($result > 0) print '
    '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).'
    '; print '+ '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).''; print '
    '; From ed898528071881d29380715d9903dd19e3da3fa9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 13:49:17 +0200 Subject: [PATCH 286/410] Work on look and feel v6 --- htdocs/user/document.php | 6 ++++-- htdocs/user/info.php | 2 +- htdocs/user/note.php | 4 +++- htdocs/user/notify/card.php | 30 +++--------------------------- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/htdocs/user/document.php b/htdocs/user/document.php index 081bf2bc408..5b86c7d490d 100644 --- a/htdocs/user/document.php +++ b/htdocs/user/document.php @@ -129,12 +129,13 @@ if ($object->id) $form=new Form($db); - dol_fiche_head($head, 'document', $langs->trans("User"),0,'user'); + dol_fiche_head($head, 'document', $langs->trans("User"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin); + print '
    '; print '
    '; // Construit liste des fichiers @@ -158,7 +159,8 @@ if ($object->id) print '
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    '; - + print '
    '; + dol_fiche_end(); diff --git a/htdocs/user/info.php b/htdocs/user/info.php index 5ea7200a0f7..ff4c44c6e23 100644 --- a/htdocs/user/info.php +++ b/htdocs/user/info.php @@ -65,7 +65,7 @@ llxHeader(); $head = user_prepare_head($object); $title = $langs->trans("User"); -dol_fiche_head($head, 'info', $title, 0, 'user'); +dol_fiche_head($head, 'info', $title, -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 38aef489b87..3f9be2b4142 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -88,7 +88,7 @@ if ($id) $head = user_prepare_head($object); $title = $langs->trans("User"); - dol_fiche_head($head, 'note', $title, 0, 'user'); + dol_fiche_head($head, 'note', $title, -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; @@ -99,6 +99,7 @@ if ($id) print "
    "; print ''; + print '
    '; print ''; // Login @@ -123,6 +124,7 @@ if ($id) print ""; print "
    "; + print '
    '; dol_fiche_end(); diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php index 4e84a8b83fa..305bb3d226b 100644 --- a/htdocs/user/notify/card.php +++ b/htdocs/user/notify/card.php @@ -135,36 +135,12 @@ if ($result > 0) $head = user_prepare_head($object); - dol_fiche_head($head, 'notify', $langs->trans("User"),0,'user'); + dol_fiche_head($head, 'notify', $langs->trans("User"), 0, 'user'); $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); - - /*print ''; - - // Ref - print ''; - print ''; - print ''."\n"; - - print ''; - print ''; - - // Firstname - print ''; - print ''; - print ''."\n"; - - // EMail - print ''; - print ''; - print "\n"; - - print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object,'id','',$user->rights->user->user->lire || $user->admin); - print '
    '.$langs->trans("Lastname").''.$object->lastname.'
    '.$langs->trans("Firstname").''.$object->firstname.'
    '.$langs->trans("EMail").''.dol_print_email($object->email,0,0,1).'
    ';*/ - + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 1, ''); + dol_fiche_end(); print "\n"; From 4d7b059eb33ecf74c8443f125d735c2df8c8767a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 18:50:34 +0200 Subject: [PATCH 287/410] Release 4.0.5 --- ChangeLog | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ChangeLog b/ChangeLog index cc6f1364f17..5fe3c741499 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,42 @@ Upgrading to any other version or any other database system is abolutely require make a Dolibarr upgrade. +***** ChangeLog for 4.0.5 to 4.0.4 ***** +FIX: #6234 +FIX: #6259 +FIX: #6330 +FIX: #6360 +FIX: #6411 +FIX: #6443 +FIX: #6444 +FIX: #6453 +FIX: #6503: SQL error in "Last pending payment invoices" +FIX: #6505 Project elements page shows greyed-out links even if the option to show actions not available is disabled +FIX: #6507: Statistics counter show wrong total Contract numbers when the user does not have full access +FIX: #6533 #6590 +FIX: #6619 Template invoices list do not respect restricted thirdparty user rights +FIX: #6621 Documents tab shows greyed out upload form even if the option to show actions not available is disabled +FIX: add entity param to document link +FIX: Can use quote into supplier ref on order line add +FIX: Change the customer code only if error on duplicate +FIX: Creation of credit note on invoice with deposit stole the discount. +FIX: delete bank class lines when we delete bank_categ +FIX: deletion of bank tag +FIX: detail of deposit and credit not was not visible into final invoice +FIX: Error management during bank account creation +FIX: error management in bank account deletion. +FIX: event status is not modified when assign an user +FIX: forgotten fk_facture_fourn attribute on supplierinvoice line object +FIX: If bank module on, field must be required to register payment of expense report. +FIX: load multicurrency informations on supplier order and bill lines fetch +FIX: Missing total on project overview. +FIX: multicurrency_subprice +FIX: param billed when we change page +FIX: protection against infinite loop on hierarchy +FIX: Supplier Order list filter by project +FIX: the dolCopyDir fails if target dir does not exists. +FIX: use param for http links + ***** ChangeLog for 4.0.4 to 4.0.3 ***** FIX: #6227 Document models table header "Unit" is shown in 2 lines in Spanish FIX: #6230 From 4902df7e3faf7d9ceb1018cecb28cef799129383 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 19:28:38 +0200 Subject: [PATCH 288/410] Work on look and feel v6 --- htdocs/langs/en_US/mails.lang | 4 +- htdocs/societe/agenda.php | 4 +- htdocs/societe/list.php | 2 +- htdocs/societe/notify/card.php | 62 +++++++++++++++-------- htdocs/user/card.php | 6 +-- htdocs/user/notify/card.php | 91 +++++++++++++++++++++++++++------- 6 files changed, 121 insertions(+), 48 deletions(-) diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 93c3e584ff6..e546965d60d 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -116,8 +116,8 @@ Notifications=Notifications NoNotificationsWillBeSent=No email notifications are planned for this event and company ANotificationsWillBeSent=1 notification will be sent by email SomeNotificationsWillBeSent=%s notifications will be sent by email -AddNewNotification=Activate a new email notification target -ListOfActiveNotifications=List all active targets for email notification +AddNewNotification=Activate a new email notification target/event +ListOfActiveNotifications=List all active targets/events for email notification ListOfNotificationsDone=List all email notifications sent MailSendSetupIs=Configuration of email sending has been setup to '%s'. This mode can't be used to send mass emailing. MailSendSetupIs2=You must first go, with an admin account, into menu %sHome - Setup - EMails%s to change parameter '%s' to use mode '%s'. With this mode, you can enter setup of the SMTP server provided by your Internet Service Provider and use Mass emailing feature. diff --git a/htdocs/societe/agenda.php b/htdocs/societe/agenda.php index 36fbe790bf3..e1dc1c12671 100644 --- a/htdocs/societe/agenda.php +++ b/htdocs/societe/agenda.php @@ -58,7 +58,7 @@ if ($page == -1) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if (! $sortfield) $sortfield='a.datep, a.id'; +if (! $sortfield) $sortfield='a.datep,a.id'; if (! $sortorder) $sortorder='DESC'; // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array @@ -190,7 +190,7 @@ if ($socid > 0) $filters=array(); $filters['search_agenda_label']=$search_agenda_label; - // TODO Replace this with smae code then into listactions.php + // TODO Replace this with same code than into listactions.php show_actions_done($conf,$langs,$db,$object,null,0,$actioncode, '', $filters, $sortfield, $sortorder); } } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 1a9980bbf12..9bde47887ed 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -88,7 +88,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) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/societe/notify/card.php b/htdocs/societe/notify/card.php index d7445233c71..8b77c8f52a4 100644 --- a/htdocs/societe/notify/card.php +++ b/htdocs/societe/notify/card.php @@ -44,15 +44,16 @@ $actionid=GETPOST('actionid'); if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'societe','',''); -$sortfield = GETPOST("sortfield",'alpha'); -$sortorder = GETPOST("sortorder",'alpha'); -$page = GETPOST("page",'int'); -if ($page == -1) { $page = 0; } -$offset = $conf->liste_limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; +$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; +$sortfield=GETPOST("sortfield",'alpha'); +$sortorder=GETPOST("sortorder",'alpha'); +$page=GETPOST("page",'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="n.daten"; +if (empty($page) || $page == -1) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; $now=dol_now(); @@ -188,7 +189,7 @@ if ($result > 0) print '
    '.$langs->trans("NbOfActiveNotifications").'
    '.$langs->trans("NbOfActiveNotifications").''; $nbofrecipientemails=0; $notify=new Notify($db); @@ -198,7 +199,8 @@ if ($result > 0) if (! empty($tmpkey)) $nbofrecipientemails++; } print $nbofrecipientemails; - print '
    '; print ''; @@ -286,7 +288,7 @@ if ($result > 0) $sql.= " WHERE a.rowid = n.fk_action"; $sql.= " AND c.rowid = n.fk_contact"; $sql.= " AND c.fk_soc = ".$object->id; - + $resql=$db->query($sql); if ($resql) { @@ -299,8 +301,7 @@ if ($result > 0) // List of active notifications print load_fiche_titre($langs->trans("ListOfActiveNotifications").' ('.$num.')','',''); - $var=true; - + // Line with titles print ''; print ''; @@ -321,14 +322,12 @@ if ($result > 0) while ($i < $num) { - $var = !$var; - $obj = $db->fetch_object($resql); $contactstatic->id=$obj->contactid; $contactstatic->lastname=$obj->lastname; $contactstatic->firstname=$obj->firstname; - print ''; print ''; print ''; From 00d485b2c5eff2416d621bb3ebf4c4791f0f5f14 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 22:09:06 +0200 Subject: [PATCH 290/410] Start 4.0.6 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index c0f95fe76f7..d2ca04278ff 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','4.0.5'); +if (! defined('DOL_VERSION')) define('DOL_VERSION','4.0.6'); if (! defined('EURO')) define('EURO',chr(128)); From da3fdbc9f0fe9dfdc3439ca93dba9f522df0d266 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 22:18:41 +0200 Subject: [PATCH 291/410] Prepare 5.0.1 --- ChangeLog | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8387c6a0e3..2b3e6e9d026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,8 +2,28 @@ English Dolibarr ChangeLog -------------------------------------------------------------- - - +***** ChangeLog for 5.0.1 compared to 5.0.0 ***** +FIX: #6503: SQL error in "Last pending payment invoices" +FIX: #6505 Project elements page shows greyed-out links even if the option to show actions not available is disabled +FIX: #6507: Statistics counter show wrong total Contract numbers when the user does not have full access +FIX: #6533 #6590 +FIX: #6535 +FIX: bank account not visible on payment card +FIX: colspan +FIX: Data lost during merge of thirdparties +FIX: Detection of color brightness +FIX: Filter on date lost after submit on time spent page +FIX: forgottent fk_unit field on llx_supplier_propaldet +FIX: list of projects +FIX: LOG_ERROR does not exists. Use LOG_ERR. +FIX: Missing total on project overview. +FIX: multicurrency management on supplier order/invoice +FIX: Notification sending was broken. +FIX: origin & origin id on supplier order line +FIX: param php doc +FIX: Picto of project on dol_banner and box +FIX: Some errors when downloading files. + ***** ChangeLog for 5.0.0 compared to 4.0.* ***** For users: NEW: Add module mulicurrency. From a5a09953138373dbf991e4fa8c5b9cc1be5a0349 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:11:29 +0200 Subject: [PATCH 292/410] More comments --- htdocs/core/class/extrafields.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 1211c334617..673f069d1b3 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -112,7 +112,7 @@ class ExtraFields * * @param string $attrname Code of attribute * @param string $label label of attribute - * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') + * @param int $type Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...) * @param int $pos Position of attribute * @param string $size Size/length of attribute * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...) @@ -164,7 +164,7 @@ class ExtraFields * This is a private method. For public method, use addExtraField. * * @param string $attrname code of attribute - * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') + * @param int $type Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...) * @param string $length Size/length of attribute ('5', '24,8', ...) * @param string $elementtype Element type ('member', 'product', 'thirdparty', 'contact', ...) * @param int $unique Is field unique or not From 9678c2128ec8de77de62766b65af14d255e04c80 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:29:20 +0200 Subject: [PATCH 293/410] Add field langs into extrafields definition table --- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 1 + htdocs/install/mysql/tables/llx_extrafields.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 3a2359fccb4..78f378e8c1a 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -24,6 +24,7 @@ -- -- VPGSQL8.2 DELETE FROM llx_usergroup_user WHERE fk_user NOT IN (SELECT rowid from llx_user); -- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); +ALTER TABLE llx_extrafields ADD COLUMN langs varchar(24); ALTER TABLE llx_supplier_proposaldet ADD COLUMN fk_unit integer DEFAULT NULL; diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index b7a7288980b..2cc144db092 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -34,5 +34,6 @@ create table llx_extrafields alwayseditable integer DEFAULT 0, -- 1 if field can be edited whatever is element status param text, -- extra parameters to define possible values of field list integer DEFAULT 0, -- list of values for field that are combo lists + langs varchar(24), -- example: fileofmymodule@mymodule ishidden integer DEFAULT 0 -- ??? example of use case ??? )ENGINE=innodb; From 6a69f9349b8372771f4b70140705c4b4eb16a631 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:43:04 +0200 Subject: [PATCH 294/410] Fix too much logs in list --- htdocs/core/class/hookmanager.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index b860e083469..24ba86c7115 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -126,7 +126,7 @@ class HookManager if (! is_array($this->hooks) || empty($this->hooks)) return ''; $parameters['context']=join(':',$this->contextarray); - dol_syslog(get_class($this).'::executeHooks method='.$method." action=".$action." context=".$parameters['context']); + //dol_syslog(get_class($this).'::executeHooks method='.$method." action=".$action." context=".$parameters['context']); // Define type of hook ('output' or 'addreplace'. 'returnvalue' is deprecated because a 'addreplace' hook can also return resPrint and resArray). $hooktype='output'; @@ -200,6 +200,9 @@ class HookManager // test to avoid running twice a hook, when a module implements several active contexts if (in_array($module,$modulealreadyexecuted)) continue; + + dol_syslog(get_class($this).'::executeHooks a qualified hook was found for method='.$method.' module='.$module." action=".$action." context=".$context); + $modulealreadyexecuted[$module]=$module; // Use the $currentcontext in method to avoid running twice // Clean class (an error may have been set from a previous call of another method for same module/hook) From 13587fa13e6e32139bc3c350ef8373e6900b9cc2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:44:55 +0200 Subject: [PATCH 295/410] Fix key were not translated --- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/societe/list.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 60ff30c6433..d432bf61d8a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5176,7 +5176,7 @@ class Form */ static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage) { - global $conf,$user; + global $conf,$langs,$user; if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return ''; @@ -5209,7 +5209,7 @@ class Form } if ($val['label']) { - $lis.='
  • '.dol_escape_htmltag($val['label']).'
  • '; + $lis.='
  • '.dol_escape_htmltag($langs->trans($val['label'])).'
  • '; $listcheckedstring.=(empty($val['checked'])?'':$key.','); } } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 4a0be451c45..82b29865233 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -624,7 +624,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } From d99b0461c714afe791632cd36f22b4735d223162 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:47:25 +0200 Subject: [PATCH 296/410] Extrafields multilanguage support. --- dev/skeletons/skeleton_list.php | 2 +- htdocs/adherents/list.php | 2 +- htdocs/comm/propal/list.php | 2 +- htdocs/commande/list.php | 2 +- htdocs/compta/bank/bankentries.php | 2 +- htdocs/compta/bank/index.php | 2 +- htdocs/compta/facture/list.php | 2 +- htdocs/contact/list.php | 2 +- htdocs/contrat/list.php | 2 +- htdocs/contrat/services.php | 2 +- htdocs/core/lib/functions.lib.php | 6 +++--- htdocs/expedition/list.php | 2 +- htdocs/expensereport/list.php | 2 +- htdocs/fichinter/list.php | 2 +- htdocs/fourn/commande/list.php | 2 +- htdocs/fourn/facture/list.php | 2 +- htdocs/modulebuilder/skeletons/skeleton_list.php | 14 +++++++------- htdocs/product/list.php | 2 +- htdocs/product/stock/mouvement.php | 2 +- htdocs/product/stock/productlot_list.php | 2 +- htdocs/projet/list.php | 2 +- htdocs/projet/tasks/list.php | 2 +- htdocs/projet/tasks/time.php | 2 +- htdocs/resource/list.php | 2 +- htdocs/societe/list.php | 2 +- htdocs/user/index.php | 2 +- 26 files changed, 34 insertions(+), 34 deletions(-) diff --git a/dev/skeletons/skeleton_list.php b/dev/skeletons/skeleton_list.php index 77485c6d638..ca66990a9f7 100644 --- a/dev/skeletons/skeleton_list.php +++ b/dev/skeletons/skeleton_list.php @@ -354,7 +354,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 8d00194993b..e492e31b440 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -583,7 +583,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index fdcbdde5ca8..d1ccf6547ce 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -726,7 +726,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 37170e0af84..fa94541cdbf 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1021,7 +1021,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index c7596a0aee2..ca786c1e3e0 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -826,7 +826,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 71397f695d6..e67441036c4 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -403,7 +403,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index eafd8900d37..03612cbb932 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -939,7 +939,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index e7d4f603618..917c59006f2 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -631,7 +631,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 0224da7d88c..af68e789da2 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -534,7 +534,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index 42ff4b04e83..62b9fddf743 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -371,7 +371,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e51541272bd..8c27b101fa4 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3106,7 +3106,7 @@ function print_liste_field_titre($name, $file="", $field="", $begin="", $morepar /** * Get title line of an array * - * @param string $name Label of field + * @param string $name Translation key of field * @param int $thead 0=To use with standard table format, 1=To use inside
    , 2=To use with
    * @param string $file Url used when we click on sort picto * @param string $field Field to use for new sorting. Empty if this field is not sortable. @@ -3120,7 +3120,7 @@ function print_liste_field_titre($name, $file="", $field="", $begin="", $morepar */ function getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="") { - global $conf; + global $conf, $langs; //print "$name, $file, $field, $begin, $options, $moreattrib, $sortfield, $sortorder
    \n"; $sortorder=strtoupper($sortorder); @@ -3154,7 +3154,7 @@ function getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $m } } - $out.=$name; + $out.=$langs->trans($name); if (empty($thead) && $field) // If this is a sort field { diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 4166bbb3791..29f6978b24e 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -446,7 +446,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 8e2b46459b0..9339b33ee7f 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -363,7 +363,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 2ec1eb2af70..4a24f0d0c6d 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -356,7 +356,7 @@ if ($result) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index f8062cc70bc..be3cb384e96 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -672,7 +672,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index dbfc9d8fd3c..52320ec9580 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -677,7 +677,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/modulebuilder/skeletons/skeleton_list.php b/htdocs/modulebuilder/skeletons/skeleton_list.php index 77485c6d638..561dc98da35 100644 --- a/htdocs/modulebuilder/skeletons/skeleton_list.php +++ b/htdocs/modulebuilder/skeletons/skeleton_list.php @@ -109,12 +109,12 @@ if (empty($user->socid)) $fieldstosearchall["t.note_private"]="NotePrivate"; // Definition of fields for list $arrayfields=array( - 't.field1'=>array('label'=>$langs->trans("Field1"), 'checked'=>1), - 't.field2'=>array('label'=>$langs->trans("Field2"), 'checked'=>1), - //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), - 't.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), - 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), + 't.field1'=>array('label'=>"Field1", 'checked'=>1), + 't.field2'=>array('label'=>"Field2", 'checked'=>1), + //'t.entity'=>array('label'=>"Entity", 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), + 't.datec'=>array('label'=>"DateCreationShort", 'checked'=>0, 'position'=>500), + 't.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), + //'t.statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), ); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -354,7 +354,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 69108a893d9..2e651398766 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -610,7 +610,7 @@ else if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index a3742dcc00d..45ace2031cb 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -888,7 +888,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 58bb6f6a3cb..ac6bc7b9948 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -422,7 +422,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index c8335676700..790dde6e1aa 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -603,7 +603,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index a6a4c855474..13e15eb7eb6 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -575,7 +575,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 22293039c86..4b2b0b4c21e 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -731,7 +731,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } }*/ diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 5a3d5390bb0..2d93a0ab2df 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -248,7 +248,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 9bde47887ed..ae77ec3148c 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -875,7 +875,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 3e1da6a7431..312416afa29 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -447,7 +447,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } From 17bd393965fe961b4f33484e5ef587141c09f684 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 12:48:09 +0200 Subject: [PATCH 297/410] Fix typo --- build/debian/dolibarr.postinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/debian/dolibarr.postinst b/build/debian/dolibarr.postinst index 4b946fda433..6ee2a89931f 100644 --- a/build/debian/dolibarr.postinst +++ b/build/debian/dolibarr.postinst @@ -61,7 +61,7 @@ apache_install() { # Enable dolibarr conf if which a2enconf >/dev/null 2>&1 ;then # a2enconf exists for ubuntu only - echo "Enable link for Apache config file with a3enconf" + echo "Enable link for Apache config file with a2enconf" a2enconf dolibarr else if [ -d /etc/$webserver/conf.d ] && [ ! -e /etc/$webserver/conf.d/dolibarr.conf ]; then From 5b5380659e1be3b2512a99a897afce05edb221fa Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Mon, 3 Apr 2017 15:58:48 +0200 Subject: [PATCH 298/410] ERROR Categories Bank vs categories transactions PB since 4.0, present in 5.0 and develop version There is a confusion between the categorization function of bank accounts and the categorization function of the records. The categorization of the entries has been removed or it is not replaced by the categorization of the bank accounts. I propose for the moment to restore the old category of writings but to envisage the creation of a new type of category "bank records" (or if it is not necessary with the new account) to leave so --- htdocs/core/menus/standard/eldy.lib.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 748a4532cb5..eab8f5a8c19 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1071,10 +1071,11 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (! empty($conf->categorie->enabled)) { $langs->load("categories"); - //$newmenu->add("/compta/bank/categ.php",$langs->trans("Rubriques"),1,$user->rights->banque->configurer); $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags'); $newmenu->add("/categories/card.php?action=create&type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer); - } + $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),1,$user->rights->banque->configurer); + + } // Prelevements if (! empty($conf->prelevement->enabled)) From 761ece3125000fec1827c02d3b6b296bceecdc63 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 16:59:22 +0200 Subject: [PATCH 299/410] Remove $maxfilenamelength replace with auto overflow. --- htdocs/core/class/html.formfile.class.php | 24 +++++++++++------------ htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 1dfb5a08855..258c2c9c962 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -229,7 +229,7 @@ class FormFile * @param integer $allowgenifempty Show warning if no model activated * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined) * @param int $iconPDF Show only PDF icon with link (1/0) - * @param int $maxfilenamelength Max length for filename shown + * @param int $notused Not used * @param integer $noform Do not output html form tags * @param string $param More param on http links * @param string $title Title to show on top of form @@ -238,10 +238,10 @@ class FormFile * @return int <0 if KO, number of shown files if OK * @deprecated Use print xxx->showdocuments() instead. */ - function show_documents($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='') + function show_documents($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='') { $this->numoffiles=0; - print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$maxfilenamelength,$noform,$param,$title,$buttonlabel,$codelang); + print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$notused,$noform,$param,$title,$buttonlabel,$codelang); return $this->numoffiles; } @@ -259,7 +259,7 @@ class FormFile * @param integer $allowgenifempty Allow generation even if list of template ($genallowed) is empty (show however a warning) * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined) * @param int $iconPDF Deprecated, see getDocumentsLink - * @param int $maxfilenamelength Max length for filename shown + * @param int $notused Not used * @param integer $noform Do not output html form tags * @param string $param More param on http links * @param string $title Title to show on top of form @@ -269,7 +269,7 @@ class FormFile * @param Object $object Object when method is called from an object card. * @return string Output string with HTML array of documents (might be empty string) */ - function showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$morepicto='',$object=null) + function showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$morepicto='',$object=null) { // Deprecation warning if (0 !== $iconPDF) { @@ -297,7 +297,6 @@ class FormFile $hookmanager->initHooks(array('formfile')); $forname='builddoc'; $out=''; - $var=true; $headershown=0; $showempty=0; @@ -691,27 +690,26 @@ class FormFile { foreach($file_list as $file) { - $var=!$var; - // Define relative path for download link (depends on module) $relativepath=$file["name"]; // Cas general if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"]; // Cas propal, facture... if ($modulepart == 'export') $relativepath = $file["name"]; // Other case - $out.= "
    "; + $out.= ''; $documenturl = DOL_URL_ROOT.'/document.php'; if (isset($conf->global->DOL_URL_ROOT_DOCUMENT_PHP)) $documenturl=$conf->global->DOL_URL_ROOT_DOCUMENT_PHP; // Show file name with link to download - $out.= ''; // Show file size diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index e270cc3b030..dac7cf43f5e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1068,7 +1068,7 @@ div.nopadding { .pictowarning, .pictopreview { padding-: 3px; } -.pictoedit, .pictowarning, .pictopreview, .pictodelete { +.pictoedit, .pictowarning, .pictodelete { vertical-align: text-bottom; } .colorthumb { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6885bfad144..f4b38d08012 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1112,7 +1112,7 @@ table.noborder tr.liste_titre td { .pictowarning, .pictopreview { padding-: 3px; } -.pictoedit, .pictowarning, .pictopreview, .pictodelete { +.pictoedit, .pictowarning, .pictodelete { vertical-align: text-bottom; } .colorthumb { From 422bdd1ef64b4416f4de41d47cf7426f4db58fd1 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Tue, 4 Apr 2017 09:06:29 +0200 Subject: [PATCH 300/410] FIX: Supplier is not the project customer --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 1efc4465d81..ee2fc06c2b2 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -308,7 +308,7 @@ $listofreferent=array( 'margin'=>'minus', 'table'=>'facture_fourn', 'datefieldname'=>'datef', - 'urlnew'=>DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id.'&socid='.$socid, + 'urlnew'=>DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id, 'lang'=>'suppliers', 'buttonnew'=>'AddSupplierInvoice', 'testnew'=>$user->rights->fournisseur->facture->creer, From 9df4bac2028e6f5d90b41ddae74da13dbd6f7b12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 11:56:19 +0200 Subject: [PATCH 301/410] NEW Bookmarks are into a combo list. --- htdocs/bookmarks/bookmarks.lib.php | 42 ++++++++++++++++++++--- htdocs/bookmarks/card.php | 10 ++++-- htdocs/bookmarks/list.php | 4 +-- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/lib/ajax.lib.php | 3 +- htdocs/core/menus/standard/eldy.lib.php | 20 +++++------ htdocs/langs/en_US/bookmarks.lang | 4 ++- htdocs/theme/eldy/style.css.php | 44 ++++++++++++++++--------- htdocs/theme/md/style.css.php | 36 ++++++++++++++------ 9 files changed, 116 insertions(+), 49 deletions(-) diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php index 3cee534e797..d84713d1e62 100644 --- a/htdocs/bookmarks/bookmarks.lib.php +++ b/htdocs/bookmarks/bookmarks.lib.php @@ -41,9 +41,12 @@ function printBookmarksList($aDb, $aLangs) $langs->load("bookmarks"); $url= $_SERVER["PHP_SELF"].(! empty($_SERVER["QUERY_STRING"])?'?'.$_SERVER["QUERY_STRING"]:''); - + // TODO Add post param to $url + $ret = ''; + // Menu bookmark + /* $ret.= '
    '.$contactstatic->getNomUrl(1); + print '
    '.$contactstatic->getNomUrl(1); if ($obj->type == 'email') { if (isValidEmail($obj->email)) @@ -425,6 +424,16 @@ if ($result > 0) $sql.= " AND n.fk_soc = ".$object->id; $sql.= $db->order($sortfield, $sortorder); + // Count total nb of records + $nbtotalofrecords = ''; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + { + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); + } + + $sql.= $db->plimit($limit+1, $offset); + $resql=$db->query($sql); if ($resql) { @@ -435,9 +444,20 @@ if ($result > 0) dol_print_error($db); } - // List of notifications done - print load_fiche_titre($langs->trans("ListOfNotificationsDone").' ('.$num.')','',''); - $var=true; + $param='&socid='.$object->id; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + + print ''; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + // List of active notifications + print_barre_liste($langs->trans("ListOfNotificationsDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, '', 0, '', '', $limit); // Line with titles print ''; @@ -457,11 +477,9 @@ if ($result > 0) while ($i < $num) { - $var = !$var; - $obj = $db->fetch_object($resql); - print '
    '; + print '
    '; if ($obj->id > 0) { $contactstatic->id=$obj->id; @@ -501,6 +519,8 @@ if ($result > 0) } print '
    '; + + print ''; } else dol_print_error('','RecordNotFound'); diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 37a0042c137..e213578b860 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -723,11 +723,10 @@ if (($action == 'create') || ($action == 'adduserldap')) print dol_set_focus('#lastname'); - print ''; - - print ''; + print '
    '; // Lastname + print ''; print ''; print ''; print ''; }*/ - if ($user->admin) + /*if ($user->admin) { $var = ! $var; print ''; - } + }*/ print '
    '.$langs->trans("Lastname").''; if (! empty($ldap_lastname)) @@ -1257,7 +1256,6 @@ else dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin); - print '
    '; print '
    '; diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php index 305bb3d226b..f18197dccc8 100644 --- a/htdocs/user/notify/card.php +++ b/htdocs/user/notify/card.php @@ -44,15 +44,16 @@ $actionid=GETPOST('actionid'); if ($user->societe_id) $id=$user->societe_id; $result = restrictedArea($user, 'societe','',''); -$sortfield = GETPOST("sortfield",'alpha'); -$sortorder = GETPOST("sortorder",'alpha'); -$page = GETPOST("page",'int'); -if ($page == -1) { $page = 0; } -$offset = $conf->liste_limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; +$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; +$sortfield=GETPOST("sortfield",'alpha'); +$sortorder=GETPOST("sortorder",'alpha'); +$page=GETPOST("page",'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="n.daten"; +if (empty($page) || $page == -1) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; $now=dol_now(); @@ -135,12 +136,45 @@ if ($result > 0) $head = user_prepare_head($object); - dol_fiche_head($head, 'notify', $langs->trans("User"), 0, 'user'); + dol_fiche_head($head, 'notify', $langs->trans("User"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 1, ''); + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 0, ''); + print '
    '; + + print '
    '; + print ''; + + // Login + print ''; + if (! empty($object->ldap_sid) && $object->statut==0) + { + print ''; + } + else + { + print ''; + } + print ''."\n"; + + /*print ''; // Notification for this thirdparty + print '';*/ + + print '
    '.$langs->trans("Login").''.$langs->trans("LoginAccountDisableInDolibarr").''.$object->login.'
    '.$langs->trans("NbOfActiveNotifications").''; + $nbofrecipientemails=0; + $notify=new Notify($db); + $tmparray = $notify->getNotificationsArray('', 0, null, $object->id, array('user')); + foreach($tmparray as $tmpkey => $tmpval) + { + $nbofrecipientemails++; + } + print $nbofrecipientemails; + print '
    '; + + print '
    '; + dol_fiche_end(); print "\n"; @@ -345,13 +379,13 @@ if ($result > 0) print '
    '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).'
    '; print '+ '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).''; print '
    '; @@ -364,12 +398,22 @@ if ($result > 0) $sql.= " c.rowid as id, c.lastname, c.firstname, c.email as contactemail,"; $sql.= " a.code, a.label"; $sql.= " FROM ".MAIN_DB_PREFIX."c_action_trigger as a,"; - $sql.= " ".MAIN_DB_PREFIX."notify as n "; + $sql.= " ".MAIN_DB_PREFIX."notify as n"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as c ON n.fk_user = c.rowid"; $sql.= " WHERE a.rowid = n.fk_action"; $sql.= " AND n.fk_user = ".$object->id; $sql.= $db->order($sortfield, $sortorder); + // Count total nb of records + $nbtotalofrecords = ''; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + { + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); + } + + $sql.= $db->plimit($limit+1, $offset); + $resql=$db->query($sql); if ($resql) { @@ -380,10 +424,21 @@ if ($result > 0) dol_print_error($db); } + $param='&id='.$object->id; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + + print '
    '; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + // List of notifications done - print_fiche_titre($langs->trans("ListOfNotificationsDone").' ('.$num.')','',''); - $var=true; - + print_barre_liste($langs->trans("ListOfNotificationsDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, '', 0, '', '', $limit); + // Line with titles print ''; print ''; @@ -402,11 +457,9 @@ if ($result > 0) while ($i < $num) { - $var = !$var; - $obj = $db->fetch_object($resql); - print '
    '; + print '
    '; if ($obj->id > 0) { $userstatic->id=$obj->id; @@ -446,6 +499,8 @@ if ($result > 0) } print '
    '; + + print '
    '; } else dol_print_error('','RecordNotFound'); From a2da0dab7dcfa8992a5617336e9c431ea238e9a1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 21:42:16 +0200 Subject: [PATCH 289/410] FIX bank account not visible on payment card --- htdocs/compta/paiement/card.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 31b4ea8e993..8a58b842ab6 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -236,7 +236,7 @@ $disable_delete = 0; // Bank account if (! empty($conf->banque->enabled)) { - if ($object->bank_account) + if ($object->fk_account > 0) { $bankline=new AccountLine($db); $bankline->fetch($object->bank_line); @@ -257,9 +257,8 @@ if (! empty($conf->banque->enabled)) print '
    '.$langs->trans('BankAccount').''; $accountstatic=new Account($db); - $accountstatic->id=$bankline->fk_account; - $accountstatic->label=$bankline->bank_account_ref.' - '.$bankline->bank_account_label; - print $accountstatic->getNomUrl(0); + $accountstatic->fetch($bankline->fk_account); + print $accountstatic->getNomUrl(1); print '
    '; - $out.= 'showPreview($file,$modulepart,$relativepath); + $out.= ($tmp?$tmp.' ':''); + $out.= 'trans("File").': '.$file["name"]).' '.dol_trunc($file["name"],$maxfilenamelength); + $out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]).' '.$file["name"]; $out.= ''."\n"; - $out.= $this->showPreview($file,$modulepart,$relativepath); $out.= '
    '; $ret.= ''.$langs->trans('Bookmarks').''; @@ -56,9 +59,18 @@ function printBookmarksList($aDb, $aLangs) } $ret.= '
    '; $ret.= ''; - + */ $ret.= ''."\n"; + $ret.= '
    '; + $ret.= ''; + $ret.= '
    '; + + $ret.=ajax_combobox('boxbookmark'); + + $ret.=''; $ret .= ''; return $ret; diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index cf5a52cf9c6..a9d4a39ef85 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -157,15 +157,19 @@ if ($action == 'create') print ''; - print ''; - - print ''; + print ''; + dol_set_focus('#titlebookmark'); + + // Url + print ''; + // Target print ''; + // Owner print ''; diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index d72fb19a6e5..b0cda58951c 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -71,9 +71,9 @@ if ($_GET["action"] == 'delete') $userstatic=new User($db); -llxHeader(); +llxHeader('', $langs->trans("ListOfBookmarks")); -print load_fiche_titre($langs->trans("Bookmarks")); +print load_fiche_titre($langs->trans("ListOfBookmarks")); $sql = "SELECT b.fk_soc as rowid, b.dateb, b.rowid as bid, b.fk_user, b.url, b.target, b.title, b.favicon, b.position,"; $sql.= " u.login, u.lastname, u.firstname"; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 2771161572f..f58bd0953ab 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5087,7 +5087,7 @@ class Form * @param string $morecss Add more class to css styles * @param int $callurlonselect If set to 1, some code is added so an url return by the ajax is called when value is selected. * @param string $placeholder String to use as placeholder - * @param integer $acceptdelayedhtml 1 if caller request to have html delayed content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) + * @param integer $acceptdelayedhtml 1 if caller request to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) * @return string HTML select string */ static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index a1041e9358b..942c17f5df9 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -401,7 +401,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ if ($forcefocus) $msg.= '.select2(\'focus\')'; $msg.= ';'."\n"; - if (count($events)) + if (count($events)) // If an array of js events to do were provided. { $msg.= ' jQuery("#'.$htmlname.'").change(function () { @@ -414,6 +414,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ }); function runJsCodeForEvent'.$htmlname.'(obj) { + console.log("Run runJsCodeForEvent'.$htmlname.'"); var id = $("#'.$htmlname.'").val(); var method = obj.method; var url = obj.url; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 7207f8f2189..f78a38d20b0 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -494,6 +494,16 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu print "\n"; } + if (is_array($moredata) && ! empty($moredata['bookmarks'])) + { + print "\n"; + print "\n"; + print '
    '."\n"; + print $moredata['bookmarks']; + print '
    '."\n"; + print "\n"; + } + /** * We update newmenu with entries found into database * -------------------------------------------------- @@ -1632,16 +1642,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($altok) print '
    '; } - if (is_array($moredata) && ! empty($moredata['bookmarks'])) - { - print "\n"; - print "\n"; - print '
    '."\n"; - print $moredata['bookmarks']; - print '
    '."\n"; - print "\n"; - } - return count($menu_array); } diff --git a/htdocs/langs/en_US/bookmarks.lang b/htdocs/langs/en_US/bookmarks.lang index e529130e1bc..0b6216c6be4 100644 --- a/htdocs/langs/en_US/bookmarks.lang +++ b/htdocs/langs/en_US/bookmarks.lang @@ -1,7 +1,9 @@ # Dolibarr language file - Source file is en_US - marque pages -AddThisPageToBookmarks=Add this page to bookmarks +AddThisPageToBookmarks=Add current page to bookmarks Bookmark=Bookmark Bookmarks=Bookmarks +ListOfBookmarks=List of bookmarks +EditBookmarks=Edit bookmarks NewBookmark=New bookmark ShowBookmark=Show bookmark OpenANewWindow=Open a new window diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index dac7cf43f5e..a797d6f760b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -349,6 +349,12 @@ span.timesheetalreadyrecorded input { select.flat, form.flat select { font-weight: normal; } +.optionblue { + color: rgb() !important; +} +.select2-results .select2-highlighted.optionblue { + color: #FFF !important; +} .optiongrey, .opacitymedium { opacity: 0.5; } @@ -906,14 +912,14 @@ div.blockvmenulogo { border-bottom: 0 !important; } -div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks { +div.blockvmenupair, div.blockvmenuimpair { border-top: none !important; border-left: none !important; border-right: none !important; border-bottom: 1px solid #e0e0e0; padding-left: 0 !important; } -div.blockvmenuend { +div.blockvmenuend, div.blockvmenubookmarks { border: none !important; padding-left: 0 !important; } @@ -1718,14 +1724,19 @@ div.vmenu, td.vmenu { } .vmenu { + width: 190px; margin-left: 4px; display: none; } +/* Force vmenusearchselectcombo with type=text differently than without because beautify with select2 affect vmenusearchselectcombo differently */ +input.vmenusearchselectcombo[type=text] { + width: 180px !important; +} .vmenusearchselectcombo { - width: 188px; + width: 188px; } .menu_contenu { @@ -1757,10 +1768,6 @@ a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { font-size: a.vsmenu.addbookmarkpicto { padding-right: 10px; } -.vmenu div.blockvmenubookmarks, .vmenu div.blockvmenuend, .vmenu div.blockvmenulogo, .vmenu div.blockvmenusearchphone -{ -/* border-bottom: 1px solid #BBB; */ -} div.blockvmenusearchphone { border-bottom: none !important; @@ -1771,7 +1778,7 @@ div.blockvmenusearchphone } .vmenu div.blockvmenusearch { - padding-bottom: 14px; + padding-bottom: 4px; /* border-bottom: 1px solid #e0e0e0; */ } .vmenu div.blockvmenuend @@ -1785,7 +1792,7 @@ div.blockvmenusearchphone } div.blockvmenubookmarks { - padding-bottom: 6px !important; + padding-bottom: 16px !important; } div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks, div.blockvmenuend { @@ -3862,14 +3869,19 @@ div.dataTables_length select { /* Select2 */ /* ============================================================================== */ +.select2-default { + color: #999 !important; + /*opacity: 0.2;*/ +} .select2-choice, .select2-container .select2-choice { - border-bottom: solid 1px rgba(0,0,0,.2); + border-bottom: solid 1px rgba(0,0,0,.4); } .select2-container .select2-choice > .select2-chosen { margin-right: 23px; } .select2-container .select2-choice .select2-arrow { border-radius: 0; + background: transparent; } .select2-container-multi .select2-choices { background-image: none; @@ -3988,18 +4000,18 @@ a span.select2-chosen /* Special case for the select2 add widget */ -#addbox .select2-container .select2-choice > .select2-chosen { +#addbox .select2-container .select2-choice > .select2-chosen, #actionbookmark .select2-container .select2-choice > .select2-chosen { text-align: left; - opacity: 0.2; + opacity: 0.4; } /* Style used before the select2 js is executed on boxcombo */ -#boxcombo.boxcombo { +#boxbookmark.boxcombo, #boxcombo.boxcombo { text-align: left; - opacity: 0.2; - border-bottom: 1px solid #000; + opacity: 0.4; + border-bottom: solid 1px rgba(0,0,0,.4) !important; height: 26px; line-height: 24px; - padding: 0 0 5px 5px; + padding: 0 0 2px 0; vertical-align: top; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f4b38d08012..6e85ca8eb7d 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -346,6 +346,12 @@ span.timesheetalreadyrecorded input { select.flat, form.flat select { font-weight: normal; } +.optionblue { + color: rgb() !important; +} +.select2-results .select2-highlighted.optionblue { + color: #FFF !important; +} .optiongrey, .opacitymedium { opacity: 0.5; } @@ -1782,7 +1788,7 @@ font.vsmenudisabledmargin { margin: 1px 1px 1px 8px; } a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { font-size:px; font-family: ; text-align: ; font-weight: normal; color: #666666; text-decoration: none; } -div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks +div.blockvmenupair, div.blockvmenuimpair { font-family: ; color: #000000; @@ -1797,11 +1803,21 @@ div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks padding-bottom: 10px; border-bottom: 1px solid #e0e0e0; } +div.blockvmenubookmarks +{ + padding-bottom: 16px !important; +} +div.blockvmenuend { + border: none !important; + padding-left: 0 !important; +} a.vsmenu.addbookmarkpicto { padding-right: 10px; } - -div.blockvmenusearch +div.blockvmenufirst { + padding-top: 10px; +} +div.blockvmenusearch, div.blockvmenubookmarks { font-family: ; color: #000000; @@ -1811,7 +1827,7 @@ div.blockvmenusearch padding-right: 1px; padding-top: 3px; padding-bottom: 3px; - margin: 1px 0px 12px 0px; + margin: 1px 0px 2px 0px; padding-bottom: 10px; /* border-bottom: 1px solid #f4f4f4; */ @@ -4103,15 +4119,15 @@ a span.select2-chosen /* Special case for the select2 add widget */ -#addbox .select2-container .select2-choice > .select2-chosen { +#addbox .select2-container .select2-choice > .select2-chosen, #actionbookmark .select2-container .select2-choice > .select2-chosen { text-align: left; - opacity: 0.2; + opacity: 0.3; } /* Style used before the select2 js is executed on boxcombo */ -#boxcombo.boxcombo { +#boxbookmark.boxcombo, #boxcombo.boxcombo { text-align: left; - opacity: 0.2; - border-bottom: 1px solid #000; + opacity: 0.3; + border-bottom: solid 1px rgba(0,0,0,.4) !important; height: 26px; line-height: 24px; padding: 0 0 5px 5px; @@ -4124,7 +4140,7 @@ a span.select2-chosen margin: 0 0 2px 3px; position: relative; line-height: 13px; - color: #333; + color: #444; cursor: default; border: 1px solid #ddd; border-radius: 3px; From 89716a86a5642d7506177b6cbce6068ac738dea4 Mon Sep 17 00:00:00 2001 From: Widee Date: Tue, 4 Apr 2017 12:22:51 +0200 Subject: [PATCH 302/410] Avoid (DEPOSIT) (1) & (2) descriptions When splitting a rebate into two parts, the word "DEPOSIT" is no longer translated on the invoices. --- htdocs/comm/remx.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 8c35c6c9e1f..6481c891d45 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -92,7 +92,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $newdiscount2->fk_facture=$discount->fk_facture; $newdiscount1->fk_facture_line=$discount->fk_facture_line; $newdiscount2->fk_facture_line=$discount->fk_facture_line; - if ($discount->description == '(CREDIT_NOTE)') + if ($discount->description == '(CREDIT_NOTE)' || $discount->description == '(DEPOSIT)') { $newdiscount1->description=$discount->description; $newdiscount2->description=$discount->description; From c4d48569970197784d07f114615871aa2548f35f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 12:23:44 +0200 Subject: [PATCH 303/410] FIX sql errors on user card --- htdocs/core/class/html.form.class.php | 28 +++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index f58bd0953ab..06405f28b01 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5547,20 +5547,24 @@ class Form if (! is_object($object->thirdparty)) $object->fetch_thirdparty(); - $possiblelinks=array( - 'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id) - ); - + $possiblelinks=array(); + if (is_object($object->thirdparty) && ! empty($object->thirdparty->id) && $object->thirdparty->id > 0) + { + $possiblelinks=array( + 'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id) + ); + } + global $action; - // Can complet the possiblelink array + // Can complete the possiblelink array $hookmanager->initHooks(array('commonobject')); $parameters=array(); $reshook=$hookmanager->executeHooks('showLinkToObjectBlock',$parameters,$object,$action); // Note that $action and $object may have been modified by hook From 01d69e4b58173750f314db3f5a1335fae7ad4e85 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 12:55:54 +0200 Subject: [PATCH 304/410] NEW Better reponsive design --- htdocs/core/lib/functions.lib.php | 4 +-- htdocs/theme/eldy/style.css.php | 43 +++++++++++++++++++++++-------- htdocs/theme/md/style.css.php | 4 +-- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8c27b101fa4..67713d7bd2c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5618,11 +5618,11 @@ function printCommonFooter($zone='private') if (empty($conf->dol_use_jmobile)) { - print ''."\n"; + print ''."\n"; print 'jQuery(".menuhider").click(function() {'; print ' console.log("We click on .menuhider");'."\n"; print " $('.side-nav').toggle();"; - if ($conf->theme == 'md') print " $('.login_block').toggle();"; + print " $('.login_block').toggle();"; print '});'."\n"; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a797d6f760b..a63593292b6 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -691,7 +691,7 @@ div.fiche>form>div.div-table-responsive { justify-content: flex-start; } .thumbstat { - flex: 1 1 120px; + flex: 1 1 114px; } .thumbstat150 { flex: 1 1 170px; @@ -4538,10 +4538,17 @@ div.tabsElem a.tab { /* rule to reduce top menu - 3rd reduction */ @media only screen and (max-width: px) /* reduction 3 */ { - /* Reduce login top right info */ - .usertextatoplogin { - display: none; + .side-nav { + z-index: 200; + background: #FFF; + padding-top: 70px; + } + #id-left { + z-index: 201; + background: #FFF; } + + /* Reduce login top right info */ .help { display: none; @@ -4551,19 +4558,33 @@ div.tabsElem a.tab { display:none; - padding-: 78px; + padding-: 0; } div.login_block_user { min-width: 0; + width: 100%; } div.login_block { - top: 2px; - - max-width: 100px; - - max-width: 82px; - + display: none; + top: inherit !important; + left: 0 !important; + text-align: center; + vertical-align: middle; + background: #FFF; + height: 42px; + padding-top: 20px; + padding-left: 20px; + padding-right: 20px; + z-index: 202; + min-width: 190px; + max-width: 190px; + width: 190px; + } + div.login_block_user, div.login_block_other { clear: both; } + .atoplogin, .atoplogin:hover + { + color: #000 !important; } .login_block_elem { padding: 0 !important; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6e85ca8eb7d..26c4c4d0a93 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -692,7 +692,7 @@ div.fiche>form>div.div-table-responsive { justify-content: flex-start; } .thumbstat { - flex: 1 1 120px; + flex: 1 1 114px; } .thumbstat150 { flex: 1 1 150px; @@ -1681,7 +1681,7 @@ div.login_block_other { padding-top: 3px; } height: 16px; } .login_block_elem_name { - margin-top: 5px; + margin-top: 1px; } .atoplogin, .atoplogin:hover { color: # !important; From 4f292d124737decc420f248f1b1c3761c7d0a8d8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 13:01:53 +0200 Subject: [PATCH 305/410] Prepare 5.0.2 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index f385fa2a524..427f428d652 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','5.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','5.0.2'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); From 13333ffd73ff9de16db36667684bd6ce20502595 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 00:39:32 +0200 Subject: [PATCH 306/410] Add multipart text version into html emails. --- htdocs/core/class/conf.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 1692b58c5f9..08763cc346b 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -390,7 +390,8 @@ class Conf // Set some default values $this->global->MAIN_ACTIVATE_HTML5=1; - + $this->global->MAIN_MAIL_USE_MULTI_PART=1; + // societe if (empty($this->global->SOCIETE_CODECLIENT_ADDON)) $this->global->SOCIETE_CODECLIENT_ADDON="mod_codeclient_leopard"; if (empty($this->global->SOCIETE_CODECOMPTA_ADDON)) $this->global->SOCIETE_CODECOMPTA_ADDON="mod_codecompta_panicum"; From 7c868888a50b74b351998072df11ec9882be7a93 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 01:01:43 +0200 Subject: [PATCH 307/410] FIX Add option MAIN_MAIL_USE_MULTI_PART to include text content into HTML email and add option MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS to restore the inline images feature. --- htdocs/core/class/CMailFile.class.php | 83 ++++++++++++++++----------- htdocs/core/class/smtps.class.php | 50 +++++++++++++--- 2 files changed, 92 insertions(+), 41 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 396952ace9c..878e0372ab3 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -55,7 +55,6 @@ class CMailFile var $eol; var $eol2; - var $atleastonefile=0; var $error=''; var $smtps; // Contains SMTPs object (if this method is used) @@ -74,7 +73,7 @@ class CMailFile // Image var $html; var $image_boundary; - var $atleastoneimage=0; + var $atleastoneimage=0; // at least one image file with file=xxx.ext into content (TODO Debug this. How can this case be tested. Remove if not used). var $html_images=array(); var $images_encoded=array(); var $image_types = array('gif' => 'image/gif', @@ -108,7 +107,7 @@ class CMailFile */ function __construct($subject,$to,$from,$msg,$filename_list=array(),$mimetype_list=array(),$mimefilename_list=array(),$addr_cc="",$addr_bcc="",$deliveryreceipt=0,$msgishtml=0,$errors_to='',$css='',$trackid='',$moreinheader='') { - global $conf; + global $conf, $dolibarr_main_data_root; // We define end of line (RFC 821). $this->eol="\r\n"; @@ -160,8 +159,12 @@ class CMailFile if ($this->msgishtml) { $this->html = $msg; - $findimg = $this->findHtmlImages($conf->fckeditor->dir_output); + if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS)) + { + $findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias'); + } + // Define if there is at least one file if ($findimg) { @@ -231,17 +234,6 @@ class CMailFile // Define body in text_body $text_body = $this->write_body($msg); - // Encode images - $images_encoded = ''; - if ($this->atleastoneimage) - { - $images_encoded.= $this->write_images($this->images_encoded); - // always end related and end alternative after inline images - $images_encoded.= "--" . $this->related_boundary . "--" . $this->eol; - $images_encoded.= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol; - $images_encoded.= $this->eol; - } - // Add attachments to text_encoded if ($this->atleastonefile) { @@ -255,8 +247,8 @@ class CMailFile // comme des injections mail par les serveurs de messagerie. $this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers); - $this->message = 'This is a message with multiple parts in MIME format.'.$this->eol; - $this->message.= $text_body . $images_encoded . $files_encoded; + $this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol; + $this->message.= $text_body . $files_encoded; $this->message.= "--" . $this->mixed_boundary . "--" . $this->eol; } else if ($conf->global->MAIN_MAIL_SENDMODE == 'smtps') @@ -917,7 +909,7 @@ class CMailFile $out.= "Content-Type: multipart/mixed; boundary=\"".$this->mixed_boundary."\"".$this->eol2; $out.= "Content-Transfer-Encoding: 8bit".$this->eol2; - + dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out); return $out; } @@ -973,23 +965,23 @@ class CMailFile $out.= "--" . $this->alternative_boundary . $this->eol; } - if ($this->msgishtml) - { - // Check if html header already in message - $strContent = $this->checkIfHTML($msgtext); - } - else - { - $strContent = $msgtext; - } - // Make RFC821 Compliant, replace bare linefeeds - $strContent = preg_replace("/(?global->MAIN_FIX_FOR_BUGGED_MTA)) { $strContent = preg_replace("/\r\n/si", "\n", $strContent); } + $strContentAltText = ''; + if ($this->msgishtml) + { + $strContentAltText = html_entity_decode(strip_tags($strContent)); + $strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n")); + + // Check if html header already in message, if not complete the message + $strContent = $this->checkIfHTML($strContent); + } + // Make RFC2045 Compliant, split lines //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content $strContent = rtrim(wordwrap($strContent)); // TODO Using this method creates unexpected line break on text/plain content. @@ -999,14 +991,30 @@ class CMailFile if ($this->atleastoneimage) { $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; - $out.= $this->eol.strip_tags($strContent).$this->eol; // Add plain text message + $out.= $this->eol.($strContentAltText?$strContentAltText:strip_tags($strContent)).$this->eol; // Add plain text message $out.= "--" . $this->alternative_boundary . $this->eol; $out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol; $out.= $this->eol; $out.= "--" . $this->related_boundary . $this->eol; } + + if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part + { + $out.= "Content-Type: multipart/alternative; boundary=\"".$this->alternative_boundary."\"".$this->eol; + $out.= $this->eol; + $out.= "--" . $this->alternative_boundary . $this->eol; + $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; + $out.= $this->eol.$strContentAltText.$this->eol; + $out.= "--" . $this->alternative_boundary . $this->eol; + } + $out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol; $out.= $this->eol.$strContent.$this->eol; + + if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part + { + $out.= "--" . $this->alternative_boundary . "--". $this->eol; + } } else { @@ -1016,6 +1024,16 @@ class CMailFile $out.= $this->eol; + // Encode images + if ($this->atleastoneimage) + { + $out .= $this->write_images($this->images_encoded); + // always end related and end alternative after inline images + $out .= "--" . $this->related_boundary . "--" . $this->eol; + $out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol; + $out .= $this->eol; + } + return $out; } @@ -1184,14 +1202,15 @@ class CMailFile $extensions = array_keys($this->image_types); - preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); + preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); // If "xxx.ext" or 'xxx.ext' found if ($matches) { $i=0; foreach ($matches[1] as $full) { - if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) + + if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) // If xxx is 'file=aaa' { $img = $regs[1]; diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index e7c7b343ac9..c99ca2c4850 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -1283,15 +1283,23 @@ class SMTPs // Make RFC821 Compliant, replace bare linefeeds $strContent = preg_replace("/(?_msgContent[$strType] = array(); $this->_msgContent[$strType]['mimeType'] = $strMimeType; $this->_msgContent[$strType]['data'] = $strContent; - + $this->_msgContent[$strType]['dataText'] = $strContentAltText; + if ( $this->getMD5flag() ) $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3); //} @@ -1304,6 +1312,8 @@ class SMTPs */ function getBodyContent() { + global $conf; + // Generate a new Boundary string $this->_setBoundary(); @@ -1318,7 +1328,7 @@ class SMTPs die ("Sorry, no content"); // If we have ONE, we can use the simple format - else if( $keyCount === 1 ) + else if( $keyCount === 1 && empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) { $_msgData = $this->_msgContent; $_msgData = $_msgData[$_types[0]]; @@ -1336,7 +1346,7 @@ class SMTPs } // If we have more than ONE, we use the multi-part format - else if( $keyCount > 1 ) + else if( $keyCount >= 1 || ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) { // Since this is an actual multi-part message // We need to define a content message Boundary @@ -1351,14 +1361,18 @@ class SMTPs $content .= "\r\n"; $content .= "--" . $this->_getBoundary('mixed') . "\r\n"; - - if (key_exists('image', $this->_msgContent)) + + if (key_exists('image', $this->_msgContent)) // If inline image found { $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n"; $content .= "\r\n"; $content .= "--" . $this->_getBoundary('alternative') . "\r\n"; } + + // $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment' + + // Loop through message content array foreach ($this->_msgContent as $type => $_content ) { @@ -1409,13 +1423,24 @@ class SMTPs if (key_exists('image', $this->_msgContent)) { $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n"; - $content.= "\r\n" . strip_tags($_content['data']) . "\r\n"; // Add plain text message + $content.= "\r\n" . ($_content['dataText']?$_content['dataText']:strip_tags($_content['data'])) . "\r\n"; // Add plain text message $content.= "--" . $this->_getBoundary('alternative') . "\r\n"; $content.= 'Content-Type: multipart/related; boundary="' . $this->_getBoundary('related') . '"' . "\r\n"; $content.= "\r\n"; $content.= "--" . $this->_getBoundary('related') . "\r\n"; } - + + if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part + { + $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n"; + $content .= "\r\n"; + $content .= "--" . $this->_getBoundary('alternative') . "\r\n"; + + $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n"; + $content.= "\r\n". $_content['dataText'] . "\r\n"; + $content.= "--" . $this->_getBoundary('alternative') . "\r\n"; + } + $content .= 'Content-Type: ' . $_content['mimeType'] . '; ' // . 'charset="' . $this->getCharSet() . '"'; . 'charset=' . $this->getCharSet() . ''; @@ -1431,7 +1456,14 @@ class SMTPs if ( $this->getMD5flag() ) $content .= 'Content-MD5: ' . $_content['md5'] . "\r\n"; - $content .= "\r\n" . $_content['data'] . "\r\n\r\n"; + $content .= "\r\n" . $_content['data'] . "\r\n"; + + if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part + { + $content.= "--" . $this->_getBoundary('alternative') . "--". "\r\n"; + } + + $content .= "\r\n"; } } From a6c60e4a9a84f413f19651a99bfcf1cf0a41469d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 11:14:02 +0200 Subject: [PATCH 308/410] FIX shared bank account with multicompany not visible in invoice setup --- htdocs/admin/facture.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 21ddabc1b65..b9c994fba28 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -638,7 +638,7 @@ if (! empty($conf->banque->enabled)) $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE clos = 0"; $sql.= " AND courant = 1"; - $sql.= " AND entity IN (".getEntity('bank', 1).")"; + $sql.= " AND entity IN (".getEntity('bank_account', 1).")"; $resql=$db->query($sql); if ($resql) { @@ -683,7 +683,7 @@ $sql = "SELECT rowid, label"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE clos = 0"; $sql.= " AND courant = 1"; -$sql.= " AND entity IN (".getEntity('bank', 1).")"; +$sql.= " AND entity IN (".getEntity('bank_account', 1).")"; $var=True; $resql=$db->query($sql); if ($resql) From 1dc2cae3a5f92bbf68afc2e6716d65e9fa4a9475 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 11:51:55 +0200 Subject: [PATCH 309/410] NEW Show company into combo list of projects --- htdocs/core/class/html.formprojet.class.php | 22 ++++++++++----------- htdocs/expensereport/card.php | 9 ++++----- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 7cdd745193e..30481497163 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -150,10 +150,9 @@ class FormProjets $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); } - // Search all projects - $sql = 'SELECT p.rowid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public'; - $sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p'; + $sql = 'SELECT p.rowid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public, s.nom as name, s.name_alias'; + $sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p LEFT JOIN '.MAIN_DB_PREFIX .'societe as s ON s.rowid = p.fk_soc'; $sql.= " WHERE p.entity IN (".getEntity('project', 1).")"; if ($projectsListId !== false) $sql.= " AND p.rowid IN (".$projectsListId.")"; if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)"; @@ -165,15 +164,9 @@ class FormProjets $sql.= " AND (p.fk_soc IN (".$socid.", ".$conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY.") OR p.fk_soc IS NULL)"; } } - if (!empty($filterkey)) { - $sql .= ' AND ('; - $sql .= ' p.title LIKE "%'.$this->db->escape($filterkey).'%"'; - $sql .= ' OR p.ref LIKE "%'.$this->db->escape($filterkey).'%"'; - $sql .= ')'; - } + if (!empty($filterkey)) $sql .= natural_search(array('p.title', 'p.ref'), $filterkey); $sql.= " ORDER BY p.ref ASC"; - dol_syslog(__METHOD__, LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { @@ -219,8 +212,13 @@ class FormProjets $labeltoshow=dol_trunc($obj->ref,18); //if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')'; //else $labeltoshow.=' ('.$langs->trans("Private").')'; - $labeltoshow.=' '.dol_trunc($obj->title,$maxlength); - + $labeltoshow.=', '.dol_trunc($obj->title, $maxlength); + if ($obj->name) + { + $labeltoshow.=' - '.$obj->name; + if ($obj->name_alias) $labeltoshow.=' ('.$obj->name_alias.')'; + } + $disabled=0; if ($obj->fk_statut == 0) { diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index fa6018fcd07..488c4c547ed 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1896,15 +1896,15 @@ else } print ''; - $var=true; while ($i < $num_lignes) { $piece_comptable = $i + 1; $objp = $db->fetch_object($resql); - $var=!$var; + if ($action != 'editline' || $objp->rowid != GETPOST('rowid')) { - print ''; + print ''; + print ''; @@ -1953,8 +1953,7 @@ else if ($action == 'editline' && $objp->rowid == GETPOST('rowid')) { - //modif ligne!!!!! - print ''; + print ''; print ''; From e2b96abd0bfcaa5198cbeb2fd4f545885f102a33 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 13:34:52 +0200 Subject: [PATCH 310/410] Fix translation --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 7cd29345e98..d305eb5e540 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -208,7 +208,7 @@ MainDbPasswordFileConfEncrypted=Database password encrypted in conf.php (Activat InstrucToEncodePass=To have password encoded into the conf.php file, replace the line
    $dolibarr_main_db_pass="...";
    by
    $dolibarr_main_db_pass="crypted:%s"; InstrucToClearPass=To have password decoded (clear) into the conf.php file, replace the line
    $dolibarr_main_db_pass="crypted:...";
    by
    $dolibarr_main_db_pass="%s"; ProtectAndEncryptPdfFiles=Protection of generated pdf files (Activated NOT recommended, breaks mass pdf generation) -ProtectAndEncryptPdfFilesDesc=Protection of a PDF document keeps it available to read and print with any PDF browser. However, editing and copying is not possible anymore. Note that using this feature make building of a global cumulated pdf not working (like unpaid invoices). +ProtectAndEncryptPdfFilesDesc=Protection of a PDF document keeps it available to read and print with any PDF browser. However, editing and copying is not possible anymore. Note that using this feature makes building of a global merged PDFs not working. Feature=Feature DolibarrLicense=License Developpers=Developers/contributors From dc14268ac6699d8ea0ee8ab2b6cdd6758914dcbf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 15:24:41 +0200 Subject: [PATCH 311/410] FIX complete hourly rate when not defined into table of time spent --- htdocs/install/repair.php | 76 ++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index cdaa0b22b7f..0338945df0f 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -76,6 +76,7 @@ print 'Option restore_thirdparties_logos is '.(GETPOST('restore_thirdparties_log print 'Option clean_linked_elements is '.(GETPOST('clean_linked_elements')?GETPOST('clean_linked_elements'):'0').'
    '."\n"; print 'Option clean_orphelin_dir (1 or confirmed) is '.(GETPOST('clean_orphelin_dir')?GETPOST('clean_orphelin_dir'):'0').'
    '."\n"; print 'Option clean_product_stock_batch (1 or confirmed) is '.(GETPOST('clean_product_stock_batch')?GETPOST('clean_product_stock_batch'):'0').'
    '."\n"; +print 'Option set_empty_time_spent_amount (1 or confirmed) is '.(GETPOST('set_empty_time_spent_amount')?GETPOST('set_empty_time_spent_amount'):'0').'
    '."\n"; print '
    '; print '
    '.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("BehaviourOnClick").''; $liste=array(0=>$langs->trans("ReplaceWindow"),1=>$langs->trans("OpenANewWindow")); print $form->selectarray('target',$liste,1); print ''.$langs->trans("ChooseIfANewWindowMustBeOpenedOnClickOnBookmark").'
    '.$langs->trans("Owner").''; print $form->select_dolusers(isset($_POST['userid'])?$_POST['userid']:$user->id, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); print ' 
    '; print img_picto($langs->trans("Document"), "object_generic"); print ' '.$piece_comptable.'
    '; @@ -151,7 +152,7 @@ if ($ok) } // Show wait message -print ''; +print ''; flush(); @@ -190,7 +191,7 @@ if ($ok) // Loop on each file foreach($filelist as $file) { - print ''; $name = substr($file, 0, dol_strlen($file) - 4); @@ -210,7 +211,7 @@ if ($ok) 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', 'commande_fournisseur'=>'commande_fournisseur', 'actioncomm'=>'actioncomm', 'adherent_type'=>'adherent_type','user'=>'user','projet'=>'projet', 'projet_task'=>'projet_task'); - print ''; + print ''; foreach($listofmodulesextra as $tablename => $elementtype) { // Get list of fields @@ -324,7 +325,7 @@ if ($ok && GETPOST('restore_thirdparties_logos')) $ext=''; - print ''; + print ''; // propal => order print '\n"; @@ -435,7 +436,7 @@ if ($ok && GETPOST('clean_orphelin_dir')) if (empty($upload_dir)) continue; - print ''; + print ''; $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','(\.meta|_preview\.png)$','^temp$','^payments$','^CVS$','^thumbs$'),'',SORT_DESC,1,true); @@ -546,7 +547,7 @@ if ($ok && GETPOST('clean_orphelin_dir')) // clean_linked_elements: Check and clean linked elements if ($ok && GETPOST('clean_product_stock_batch')) { - print ''; + print ''; $sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch"; $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb"; @@ -636,12 +637,69 @@ if ($ok && GETPOST('clean_product_stock_batch')) { dol_print_error($db); } - - } +// clean_linked_elements: Check and clean linked elements +if ($ok && GETPOST('set_empty_time_spent_amount')) +{ + print ''; + + $sql ="SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm"; + $sql.=" FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."user as u"; + $sql.=" WHERE ptt.fk_user = u.rowid"; + $sql.=" AND ptt.thm IS NULL and u.thm > 0"; + $sql.=" GROUP BY u.rowid, u.login, u.thm"; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + + if ($num) + { + $i = 0; + while ($i < $num) + { + $obj=$db->fetch_object($resql); + print ''; + + if ($error) break; + + $i++; + } + } + else + { + print ''; + } + } + else + { + dol_print_error($db); + } + + +} + + print '
    '.$langs->trans("PleaseBePatient").'
    '.$langs->trans("PleaseBePatient").'

    '; + print '
    *** '; print $langs->trans("Script").''.$file.'

    Check fields into extra table structure match table of definition. If not add column into table

    *** Check fields into extra table structure match table of definition. If not add column into table

    '; + print '

    *** Restore thirdparties logo
    '; //foreach($exts as $ext) //{ $sql="SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX."societe as s ORDER BY s.nom"; @@ -395,7 +396,7 @@ if ($ok && GETPOST('restore_thirdparties_logos')) // clean_linked_elements: Check and clean linked elements if ($ok && GETPOST('clean_linked_elements')) { - print '

    Check table of linked elements and delete orphelins links

    *** Check table of linked elements and delete orphelins links
    '.checkLinkedElements('propal', 'commande')."

    Clean orphelins files into files '.$upload_dir.'

    *** Clean orphelins files into files '.$upload_dir.'

    Clean table product_batch

    *** Clean table product_batch

    *** Set value of time spent without amount
    '.$obj->login.'-'.$obj->user_id.' ('.$obj->nb.' lines to fix) -> '.$obj->user_thm; + + $db->begin(); + + $sql2 ="UPDATE ".MAIN_DB_PREFIX."projet_task_time"; + $sql2.=" SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".$obj->user_id; + $resql2=$db->query($sql2); + if (! $resql2) + { + $error++; + dol_print_error($db); + } + + if (!$error) $db->commit(); + else $db->rollback(); + + print'
    No time spent with empty line on users with a hourly rate defined
    '; From ae2e40e5e760ff34d6c80dd6bfac831eaf85cb75 Mon Sep 17 00:00:00 2001 From: De Coninck Laurent Date: Wed, 5 Apr 2017 19:06:21 +0200 Subject: [PATCH 312/410] mark expense report as paid if payement set the remaining sold to 0 --- htdocs/expensereport/payment/payment.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php index ebcc1056fe4..56a5b1c7fb3 100644 --- a/htdocs/expensereport/payment/payment.php +++ b/htdocs/expensereport/payment/payment.php @@ -134,6 +134,18 @@ if ($action == 'add_payment') } } + if (!$error) { + $payment->fetch($paymentid); + if ($expensereport->total_ttc - $payment->amount == 0) { + $result = $expensereport->set_paid($expensereport->id, $user); + if (!$result > 0) { + $errmsg = $payment->error; + $error++; + } + } + + } + if (! $error) { $db->commit(); From dae08285433bd6170f883565723c03b82970e388 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Wed, 5 Apr 2017 20:50:18 +0200 Subject: [PATCH 313/410] NEW : show files in the bank statement + download --- htdocs/compta/bank/releve.php | 134 +++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index ffadceafb2e..2ab6df9047f 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2017 Patrick Delcroix * * 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 @@ -34,6 +35,9 @@ require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; +//show files +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; $langs->load("banks"); $langs->load("categories"); @@ -88,7 +92,36 @@ if ($id > 0 || ! empty($ref)) // Initialize technical object to manage context to save list fields $contextpage='banktransactionlist'.(empty($object->ref)?'':'-'.$object->id); +/* +*ZIP creation +*/ +if($action=="dl" && $num>0 && isset($_SESSION["releve"][$num])){ + unset($zip); + $log=''; + $filearray=$_SESSION["releve"][$num]; + $zipname = $num.'.zip'; + $zip = new ZipArchive; + $zip->open($zipname, ZipArchive::OVERWRITE); + foreach ($filearray as $key=> $files) { + if(is_array($files)){ + foreach ($files as $file) { + $zip->addFile($file["fullname"],$file["name"]);// + $log.=$key.','.$file["name"]."\n"; + } + }else{ + $log.=$key.','.$langs->trans("Nofile")."\n"; + } + } + $zip->addFromString('log.csv', $log); + $zip->close(); + ///Then download the zipped file. + header('Content-Type: application/zip'); + header('Content-disposition: attachment; filename='.$zipname); + header('Content-Length: ' . filesize($zipname)); + readfile($zipname); +} +unset($_SESSION["releve"][$num]); /* * View @@ -519,7 +552,7 @@ else dol_print_error($db); } } - + print Get_attach_files($db,$objp->rowid,$objp->label); print "
    "; - print $memberstatic->getNomUrl(1); + print $memberstatic->getNomUrl(-1); print "
    '; @@ -146,7 +147,8 @@ if ($object->id) print ''; print "
    \n"; - + print '
    '; + print dol_fiche_end(); @@ -198,7 +200,7 @@ if ($object->id) $dir = $upload_dir.'/'.$pdir; print '
    '; - print ''; + print '
    '; foreach ($object->liste_photos($dir) as $key => $obj) { @@ -255,14 +257,12 @@ if ($object->id) $nbphoto++; } + print '
    '; + if ($nbphoto < 1) { - print '
    '; - print "
    ".$langs->trans("NoPhotoYet")."

    "; - print '
    '; } } else diff --git a/htdocs/categories/traduction.php b/htdocs/categories/traduction.php index a239b357045..7dbe6325e1d 100644 --- a/htdocs/categories/traduction.php +++ b/htdocs/categories/traduction.php @@ -167,7 +167,7 @@ if (! empty($object->multilangs)) } } -dol_fiche_head($head, 'translation', $title, 0, 'category'); +dol_fiche_head($head, 'translation', $title, -1, 'category'); $linkback = ''.$langs->trans("BackToList").''; @@ -184,6 +184,7 @@ dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', 'ref', print '
    '; +print '
    '; print '
    '; print ''; @@ -201,6 +202,7 @@ print $formother->showColor($object->color); print ''; print '
    '; +print '
    '; dol_fiche_end(); diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index a1c33c568f3..a256b362361 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -192,7 +192,7 @@ else $title=$langs->trans("Category"); $head = categories_prepare_head($object,$type); -dol_fiche_head($head, 'card', $title, 0, 'category'); +dol_fiche_head($head, 'card', $title, -1, 'category'); $linkback = ''.$langs->trans("BackToList").''; @@ -219,6 +219,7 @@ if ($action == 'delete') print '
    '; +print '
    '; print '
    '; print ''; @@ -241,6 +242,7 @@ if (empty($reshook) && ! empty($extrafields->attribute_label)) } print '
    '; +print '
    '; dol_fiche_end(); diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index f403f676f07..f77ac86af7f 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -228,7 +228,6 @@ $tabs = array( ) ); -dol_fiche_head($tabs, 0, $langs->trans('LineRecord'), 0, 'account'); $sql = "SELECT b.rowid,b.dateo as do,b.datev as dv, b.amount, b.label, b.rappro,"; $sql.= " b.num_releve, b.fk_user_author, b.num_chq, b.fk_type, b.fk_account, b.fk_bordereau as receiptid,"; @@ -269,11 +268,14 @@ if ($result) print ''; print ''; + dol_fiche_head($tabs, 0, $langs->trans('LineRecord'), 0, 'account'); + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($bankline, 'rowid', $linkback); + print '
    '; print ''; @@ -542,8 +544,10 @@ if ($result) print ""; print "
    "; - - print '
    '; + + dol_fiche_end(); + + print '

    '; print ""; @@ -596,7 +600,7 @@ if ($result) print ''; print ''; - print '
    '; + print '

    '; print ''; } @@ -606,7 +610,6 @@ if ($result) $db->free($result); } else dol_print_error($db); -print '
    '; @@ -641,8 +644,7 @@ if ($result) { $objp = $db->fetch_object($result); - $var=!$var; - print ""; + print ''; print "".$objp->label.""; print "rowid."\">".$langs->trans("ListBankTransactions").""; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e6a5b5d6b92..634f27b1985 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -781,7 +781,7 @@ abstract class CommonObject $tab=array(); $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user - if ($source == 'internal') $sql.=", '-1' as socid, t.statut as statuscontact"; + if ($source == 'internal') $sql.=", '-1' as socid, t.statut as statuscontact, t.login, t.photo"; if ($source == 'external' || $source == 'thirdparty') $sql.=", t.fk_soc as socid, t.statut as statuscontact"; $sql.= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; $sql.= ", tc.source, tc.element, tc.code, tc.libelle"; @@ -815,7 +815,7 @@ abstract class CommonObject $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle); $tab[$i]=array('source'=>$obj->source,'socid'=>$obj->socid,'id'=>$obj->id, 'nom'=>$obj->lastname, // For backward compatibility - 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email, 'statuscontact'=>$obj->statuscontact, + 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email, 'login'=>$obj->login, 'photo'=>$obj->photo, 'statuscontact'=>$obj->statuscontact, 'rowid'=>$obj->rowid, 'code'=>$obj->code, 'libelle'=>$libelle_type, 'status'=>$obj->statuslink, 'fk_c_type_contact'=>$obj->fk_c_type_contact); } else diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 06405f28b01..eba2fda5049 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4920,7 +4920,7 @@ class Form } elseif ($typehour=='text' || $typehour=='textselect') { - $retstring.=''; + $retstring.=''; } else return 'BadValueForParameterTypeHour'; @@ -4944,7 +4944,7 @@ class Form } elseif ($typehour=='text' ) { - $retstring.=''; + $retstring.=''; } if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 258c2c9c962..3eef315d48a 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1103,19 +1103,16 @@ class FormFile // Do we have entry into database ? print ''."\n"; print ''; - print ''; + print ''; + + $filepath=$relativepath.$file['name']; + + if (! $editline) print $this->showPreview($file,$modulepart,$filepath); //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; @@ -1135,10 +1132,10 @@ class FormFile print ''; } - if (! $editline) print $this->showPreview($file,$modulepart,$filepath); - print "\n"; + print ''.dol_print_size($file['size'],1,1).''; + print ''.dol_print_date($file['date'],"dayhour","tzuser").''; // Preview diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 67713d7bd2c..66eca2409f3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1176,7 +1176,8 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r } if (! empty($object->name_alias)) $morehtmlref.='
    '.$object->name_alias.'
    '; // For thirdparty - if ($object->element == 'product' || $object->element == 'bank_account') + // Add label + if ($object->element == 'product' || $object->element == 'bank_account' || $object->element == 'project_task') { if (! empty($object->label)) $morehtmlref.='
    '.$object->label.'
    '; } diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 0a17a8c07c2..3077e49bf89 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -196,7 +196,9 @@ if ($permission) { $userstatic->id=$tab[$i]['id']; $userstatic->lastname=$tab[$i]['lastname']; $userstatic->firstname=$tab[$i]['firstname']; - echo $userstatic->getNomUrl(1); + $userstatic->photo=$tab[$i]['photo']; + $userstatic->login=$tab[$i]['login']; + echo $userstatic->getNomUrl(-1); } if ($tab[$i]['source']=='external') { diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 074f626f299..f44f2f70acf 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -848,7 +848,7 @@ if (! defined('NOREQUIRETRAN')) // Define some constants used for style of arrays $bc=array(0=>'class="impair"',1=>'class="pair"'); -$bcdd=array(0=>'class="drag drop"',1=>'class="drag drop"'); +$bcdd=array(0=>'class="drag drop oddeven"',1=>'class="drag drop oddeven"'); $bcnd=array(0=>'class="nodrag nodrop nohover"',1=>'class="nodrag nodrop nohoverpair"'); // Used for tr to add new lines $bctag=array(0=>'class="tagtr"',1=>'class="pair tagtr"'); diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 9407fc716c1..791cd6855f0 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -892,13 +892,12 @@ elseif ($object->id > 0) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) - { - print ' - '.$end; - if ($object->hasDelay()) print img_warning($langs->trans('Late')); - } + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 7c986e4d9a2..a5e4cb69492 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1635,6 +1635,17 @@ class Task extends CommonObject if ($statut==4) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6'); if ($statut==5) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5'); } + if ($mode == 6) + { + /*if ($statut==0) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut0'); + if ($statut==1) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut1'); + if ($statut==2) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut3'); + if ($statut==3) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut4'); + if ($statut==4) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6'); + if ($statut==5) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5');*/ + //return $this->progress.' %'; + return ' '; + } } /** diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php index e9de1f7f787..e843d4951e4 100644 --- a/htdocs/projet/contact.php +++ b/htdocs/projet/contact.php @@ -146,7 +146,7 @@ if ($id > 0 || ! empty($ref)) //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; $head = project_prepare_head($object); - dol_fiche_head($head, 'contact', $langs->trans("Project"), 0, ($object->public?'projectpub':'project')); + dol_fiche_head($head, 'contact', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); // Project card @@ -206,9 +206,12 @@ if ($id > 0 || ! empty($ref)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) print ' - '.$end; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget @@ -235,7 +238,7 @@ if ($id > 0 || ! empty($ref)) print ''; // Categories - if($conf->categorie->enabled) { + if ($conf->categorie->enabled) { print ''.$langs->trans("Categories").''; print $form->showCategories($object->id,'project',1); print ""; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 1efc4465d81..7be3cebd46c 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -183,9 +183,12 @@ if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; -print dol_print_date($object->date_start,'day'); -$end=dol_print_date($object->date_end,'day'); -if ($end) print ' - '.$end; +$start = dol_print_date($object->date_start,'dayhour'); +print ($start?$start:'?'); +$end = dol_print_date($object->date_end,'dayhour'); +print ' - '; +print ($end?$end:'?'); +if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget @@ -770,7 +773,6 @@ foreach ($listofreferent as $key => $value) $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee); if (is_array($elementarray) && count($elementarray)>0) { - $var=true; $total_ht = 0; $total_ttc = 0; @@ -813,7 +815,6 @@ foreach ($listofreferent as $key => $value) if ($breakline && $saved_third_id != $element->thirdparty->id) { print $breakline; - $var = true; $saved_third_id = $element->thirdparty->id; $breakline = ''; @@ -829,8 +830,7 @@ foreach ($listofreferent as $key => $value) if (! empty($element->close_code) && $element->close_code == 'replaced') $qualifiedfortotal=false; // Replacement invoice, do not include into total } - $var=!$var; - print ""; + print ''; // Remove link print ''; if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') @@ -909,7 +909,9 @@ foreach ($listofreferent as $key => $value) else if (in_array($tablename, array('projet_task'))) { $tmpprojtime = $element->getSumOfAmount($elementuser, $dates, $datee); // $element is a task. $elementuser may be empty + print ''; print convertSecondToTime($tmpprojtime['nbseconds'], 'allhourmin'); + print ''; $total_time_by_line = $tmpprojtime['nbseconds']; } else print dol_print_date($date,'day'); @@ -935,7 +937,7 @@ foreach ($listofreferent as $key => $value) } else if ($tablename == 'projet_task' && $key == 'project_task_time') // if $key == 'project_task', we don't want details per user { - print $elementuser->getNomUrl(1); + print $elementuser->getNomUrl(1); } print ''; diff --git a/htdocs/projet/ganttchart.inc.php b/htdocs/projet/ganttchart.inc.php index f60ada41bb1..4e1b53d3f24 100644 --- a/htdocs/projet/ganttchart.inc.php +++ b/htdocs/projet/ganttchart.inc.php @@ -167,8 +167,8 @@ function constructGanttLine($tarr,$task,$project_dependencies,$level=0,$project_ $parent = $task["task_parent"]; // Define percent $percent = $task['task_percent_complete']?$task['task_percent_complete']:0; - // Link - $link=DOL_URL_ROOT.'/projet/tasks/task.php?withproject=1&id='.$task["task_id"]; + // Link (more information) + $link=DOL_URL_ROOT.'/projet/tasks/contact.php?withproject=1&id='.$task["task_id"]; // Name $name=$task['task_name']; diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index d96e21cf194..36fbfccca77 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -94,7 +94,7 @@ if ($id > 0 || ! empty($ref)) $tab='gantt'; $head=project_prepare_head($object); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($object->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -138,9 +138,12 @@ if ($id > 0 || ! empty($ref)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) print ' - '.$end; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget @@ -253,7 +256,7 @@ if (count($tasksarray)>0) $tasks[$taskcursor]['task_percent_complete']=$val->progress; //$tasks[$taskcursor]['task_name']=$task->getNomUrl(1); //print dol_print_date($val->date_start).dol_print_date($val->date_end).'
    '."\n"; - $tasks[$taskcursor]['task_name']=$val->label; + $tasks[$taskcursor]['task_name']=$val->ref.' - '.$val->label; $tasks[$taskcursor]['task_start_date']=$val->date_start; $tasks[$taskcursor]['task_end_date']=$val->date_end; $tasks[$taskcursor]['task_color']='b4d1ea'; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index b742b5a3acb..8b72a6448ec 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -207,7 +207,7 @@ if ($id > 0 || ! empty($ref)) $tab=GETPOST('tab')?GETPOST('tab'):'tasks'; $head=project_prepare_head($object); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($object->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -268,9 +268,12 @@ if ($id > 0 || ! empty($ref)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) print ' - '.$end; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index 060155d6507..02b31ea83ff 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -279,35 +279,31 @@ if ($id > 0 || ! empty($ref)) //$arrayofuseridoftask=$object->getListContactId('internal'); $head = task_prepare_head($object); - dol_fiche_head($head, 'task_contact', $langs->trans("Task"), 0, 'projecttask'); + dol_fiche_head($head, 'task_contact', $langs->trans("Task"), -1, 'projecttask'); - /* - * Projet synthese pour rappel - */ - print ''; - $param=(GETPOST('withproject')?'&withproject=1':''); $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; - - // Ref - print ''; - - // Label - print ''; - - // Project - if (empty($withproject)) + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param, 0, '', '', 1); + + if (empty($withproject)) { - print '
    '.$langs->trans('Ref').''; + if (! GETPOST('withproject') || empty($projectstatic->id)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; } else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; - print $form->showrefnav($object,'ref',$linkback,1,'ref','ref','',$param); - print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Project").''; + print '
    '; + + print '
    '; + print ''; + + // Project + print ''; @@ -317,16 +313,18 @@ if ($id > 0 || ! empty($ref)) if ($projectstatic->thirdparty->id > 0) print $projectstatic->thirdparty->getNomUrl(1); else print ' '; print ''; + + print "
    '.$langs->trans("Project").''; print $projectstatic->getNomUrl(1); print '
    "; + + print '
    '; } - print "
    "; - + dol_fiche_end(); /* * Lignes de contacts */ - print '
    '; /* // Contacts lines (modules that overwrite templates must declare this into descriptor) $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl')); @@ -481,7 +479,9 @@ if ($id > 0 || ! empty($ref)) $userstatic->id=$tab[$i]['id']; $userstatic->lastname=$tab[$i]['lastname']; $userstatic->firstname=$tab[$i]['firstname']; - print $userstatic->getNomUrl(1); + $userstatic->photo=$tab[$i]['photo']; + $userstatic->login=$tab[$i]['login']; + print $userstatic->getNomUrl(-1); } if ($tab[$i]['source']=='external') { diff --git a/htdocs/projet/tasks/document.php b/htdocs/projet/tasks/document.php index d985454119d..af7d35ab378 100644 --- a/htdocs/projet/tasks/document.php +++ b/htdocs/projet/tasks/document.php @@ -218,10 +218,7 @@ if ($object->id > 0) } $head = task_prepare_head($object); - dol_fiche_head($head, 'task_document', $langs->trans("Task"), 0, 'projecttask'); - - $param=(GETPOST('withproject')?'&withproject=1':''); - $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; + dol_fiche_head($head, 'task_document', $langs->trans("Task"), -1, 'projecttask'); // Files list constructor $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); @@ -230,10 +227,27 @@ if ($object->id > 0) { $totalsize+=$file['size']; } + + $param=(GETPOST('withproject')?'&withproject=1':''); + $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; + if (! GETPOST('withproject') || empty($projectstatic->id)) + { + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); + $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; + } + else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + + print '
    '; + + print '
    '; print ''; // Ref + /* print ''; - + */ + // Project if (empty($withproject)) { - print ''; @@ -265,11 +280,13 @@ if ($object->id > 0) } // Files infos - print ''; + print ''; print ''; print "
    '; print $langs->trans("Ref"); print ''; @@ -249,11 +263,12 @@ if ($object->id > 0) // Label print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Project").''; + print '
    '.$langs->trans("Project").''; print $projectstatic->getNomUrl(1); print '
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    \n"; + print '
    '; + dol_fiche_end(); print '
    '; diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php index f595f43bc2b..ebdd3d0c5a3 100644 --- a/htdocs/projet/tasks/note.php +++ b/htdocs/projet/tasks/note.php @@ -110,7 +110,7 @@ if ($object->id > 0) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), 0, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); // Project card @@ -197,13 +197,27 @@ if ($object->id > 0) } $head = task_prepare_head($object); - dol_fiche_head($head, 'task_notes', $langs->trans('Task'), 0, 'projecttask'); - - print ''; + dol_fiche_head($head, 'task_notes', $langs->trans('Task'), -1, 'projecttask'); + $param=(GETPOST('withproject')?'&withproject=1':''); $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; - + + if (! GETPOST('withproject') || empty($projectstatic->id)) + { + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); + $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; + } + else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + + print '
    '; + + print '
    '; + print '
    '; + /* // Ref print ''; - + */ + // Project if (empty($withproject)) { @@ -234,12 +249,12 @@ if ($object->id > 0) print "
    '.$langs->trans("Ref").''; if (empty($withproject) || empty($projectstatic->id)) @@ -217,7 +231,8 @@ if ($object->id > 0) // Label print '
    '.$langs->trans("Label").''.$object->label.'
    "; - print '
    '; - $cssclass='titlefield'; $moreparam=$param; include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + print '
    '; + dol_fiche_end(); } diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 2665b0b33b5..3e6d658bcc1 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -221,7 +221,7 @@ if ($id > 0 || ! empty($ref)) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -306,6 +306,8 @@ if ($id > 0 || ! empty($ref)) print '
    '; dol_fiche_end(); + + print '
    '; } /* @@ -437,9 +439,22 @@ if ($id > 0 || ! empty($ref)) print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$_GET["id"].'&withproject='.$withproject,$langs->trans("DeleteATask"),$langs->trans("ConfirmDeleteATask"),"confirm_delete"); } + if (! GETPOST('withproject') || empty($projectstatic->id)) + { + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); + $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; + } + else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + print '
    '; + + print '
    '; print ''; + /* // Ref print ''; - + */ + // Project if (empty($withproject)) { - print ''; @@ -471,15 +487,14 @@ if ($id > 0 || ! empty($ref)) print ''; } - // Date start - print ''; - - // Date end - print ''; // Planned workload @@ -523,7 +538,8 @@ if ($id > 0 || ! empty($ref)) } print '
    '; print $langs->trans("Ref"); @@ -456,11 +471,12 @@ if ($id > 0 || ! empty($ref)) // Label print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Project").''; + print '
    '.$langs->trans("Project").''; print $projectstatic->getNomUrl(1); print '
    '.$langs->trans("DateStart").''; - print dol_print_date($object->date_start,'dayhour'); - print '
    '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_end,'dayhour'); - if ($object->hasDelay()) print img_warning("Late"); + // Date start - Date end + print '
    '.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print '
    '; - print '
    '; + + print '
    '; dol_fiche_end(); } diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 4b2b0b4c21e..73aba634c4d 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -49,6 +49,9 @@ $search_datewithhour=''; $search_note=GETPOST('search_note','alpha'); $search_duration=GETPOST('search_duration','int'); $search_value=GETPOST('search_value','int'); +$search_task_ref=GETPOST('search_task_ref','alpha'); +$search_task_label=GETPOST('search_task_label','alpha'); +$search_user=GETPOST('search_user','int'); // Security check $socid=0; @@ -103,6 +106,9 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") ||GETPO $search_value=''; $search_date_creation=''; $search_date_update=''; + $search_task_ref=''; + $search_task_label=''; + $search_user=0; $toselect=''; $search_array_options=array(); $action=''; @@ -299,7 +305,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), 0, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -418,43 +424,51 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) if (empty($projectidforalltimes)) { $head=task_prepare_head($object); - dol_fiche_head($head, 'task_time', $langs->trans("Task"),0,'projecttask'); + dol_fiche_head($head, 'task_time', $langs->trans("Task"), -1, 'projecttask'); if ($action == 'deleteline') { print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id.'&lineid='.$_GET["lineid"].($withproject?'&withproject=1':''),$langs->trans("DeleteATimeSpent"),$langs->trans("ConfirmDeleteATimeSpent"),"confirm_delete",'','',1); } - print '
    '; - print ''; - $param=($withproject?'&withproject=1':''); $linkback=$withproject?''.$langs->trans("BackToList").'':''; - // Ref - print '
    '; - print $langs->trans("Ref"); - print ''; if (! GETPOST('withproject') || empty($projectstatic->id)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; } else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + + print '
    '; + + print '
    '; + print ''; + + // Ref + /* + print ''; // Label print ''; - - // Date start - print ''; - - // Date end - print ''; // Planned workload @@ -517,11 +531,12 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print ''; print ''; print ''; + print ''; print ''; - print ''; + print ''; print "\n"; - print ''; + print ''; // Date print ''; + // Duration - Time spent + print ''; + // Progress declared print ''; - // Duration - Time spent - print ''; - print ''; @@ -609,13 +624,16 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) $sql = "SELECT t.rowid, t.fk_task, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note, t.thm,"; $sql .= " pt.ref, pt.label,"; - $sql .= " u.lastname, u.firstname"; + $sql .= " u.lastname, u.firstname, u.login, u.photo"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid"; if (empty($projectidforalltimes)) $sql .= " AND t.fk_task =".$object->id; else $sql.= " AND pt.fk_projet IN (".$projectidforalltimes.")"; if ($search_ref) $sql .= natural_search('c.ref', $search_ref); if ($search_note) $sql .= natural_search('t.note', $search_note); + if ($search_task_ref) $sql .= natural_search('pt.ref', $search_task_ref); + if ($search_task_label) $sql .= natural_search('pt.label', $search_task_label); + if ($search_user > 0) $sql .= natural_search('t.fk_user', $search_user); $sql .= $db->order($sortfield, $sortorder); $var=true; @@ -711,50 +729,23 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print '
    '; print '
    '; + print $langs->trans("Ref"); + print ''; print $form->showrefnav($object,'ref',$linkback,1,'ref','ref','',$param); print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("DateStart").''; - print dol_print_date($object->date_start,'dayhour'); - print '
    '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_end,'dayhour'); + */ + + // Date start - Date end + print '
    '.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print '
    '.$langs->trans("Date").''.$langs->trans("By").''.$langs->trans("Note").''.$langs->trans("NewTimeSpent").''.$langs->trans("ProgressDeclared").''.$langs->trans("NewTimeSpent").'
    '; @@ -550,16 +565,16 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print ''; print ''; + print $form->select_duration('timespent_duration', ($_POST['timespent_duration']?$_POST['timespent_duration']:''), 0, 'text'); + print ''; print $formother->select_percent(GETPOST('progress')?GETPOST('progress'):$object->progress,'progress'); print ''; - print $form->select_duration('timespent_duration', ($_POST['timespent_duration']?$_POST['timespent_duration']:''), 0, 'text'); - print ''; print ''; print '
    '."\n"; - print ''; - if (! empty($arrayfields['t.task_date']['checked'])) print_liste_field_titre($arrayfields['t.task_date']['label'],$_SERVER['PHP_SELF'],'t.task_date,t.task_datehour,t.rowid','',$params,'',$sortfield,$sortorder); - if ((empty($id) && empty($ref)) || ! empty($projectidforalltimes)) // Not a dedicated task - { - if (! empty($arrayfields['t.task_ref']['checked'])) print_liste_field_titre($arrayfields['t.task_ref']['label'],$_SERVER['PHP_SELF'],'pt.ref','',$params,'',$sortfield,$sortorder); - if (! empty($arrayfields['t.task_label']['checked'])) print_liste_field_titre($arrayfields['t.task_label']['label'],$_SERVER['PHP_SELF'],'pt.label','',$params,'',$sortfield,$sortorder); - } - if (! empty($arrayfields['author']['checked'])) print_liste_field_titre($arrayfields['author']['label'],$_SERVER['PHP_SELF'],'','',$params,'',$sortfield,$sortorder); - if (! empty($arrayfields['t.note']['checked'])) print_liste_field_titre($arrayfields['t.note']['label'],$_SERVER['PHP_SELF'],'t.note','',$params,'',$sortfield,$sortorder); - if (! empty($arrayfields['t.task_duration']['checked'])) print_liste_field_titre($arrayfields['t.task_duration']['label'],$_SERVER['PHP_SELF'],'t.task_duration','',$params,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['value']['checked'])) print_liste_field_titre($arrayfields['value']['label'],$_SERVER['PHP_SELF'],'','',$params,'align="right"',$sortfield,$sortorder); - // Extra fields - /* - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - }*/ - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Fields title search - print ''; - // LIST_OF_TD_TITLE_SEARCH + print ''; + // Date if (! empty($arrayfields['t.task_date']['checked'])) print ''; if ((empty($id) && empty($ref)) || ! empty($projectidforalltimes)) // Not a dedicated task { - if (! empty($arrayfields['t.task_ref']['checked'])) print ''; - if (! empty($arrayfields['t.task_label']['checked'])) print ''; + if (! empty($arrayfields['t.task_ref']['checked'])) print ''; + if (! empty($arrayfields['t.task_label']['checked'])) print ''; } - if (! empty($arrayfields['author']['checked'])) print ''; - if (! empty($arrayfields['t.note']['checked'])) print ''; - if (! empty($arrayfields['t.task_duration']['checked'])) print ''; - if (! empty($arrayfields['value']['checked'])) print ''; + // Author + if (! empty($arrayfields['author']['checked'])) print ''; + // Note + if (! empty($arrayfields['t.note']['checked'])) print ''; + // Duration + if (! empty($arrayfields['t.task_duration']['checked'])) print ''; + // Value in currency + if (! empty($arrayfields['value']['checked'])) print ''; // Extra fields /* if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -784,11 +775,42 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column - print ''; - print ''."\n"; + print ''."\n"; + + print ''; + if (! empty($arrayfields['t.task_date']['checked'])) print_liste_field_titre($arrayfields['t.task_date']['label'],$_SERVER['PHP_SELF'],'t.task_date,t.task_datehour,t.rowid','',$params,'',$sortfield,$sortorder); + if ((empty($id) && empty($ref)) || ! empty($projectidforalltimes)) // Not a dedicated task + { + if (! empty($arrayfields['t.task_ref']['checked'])) print_liste_field_titre($arrayfields['t.task_ref']['label'],$_SERVER['PHP_SELF'],'pt.ref','',$params,'',$sortfield,$sortorder); + if (! empty($arrayfields['t.task_label']['checked'])) print_liste_field_titre($arrayfields['t.task_label']['label'],$_SERVER['PHP_SELF'],'pt.label','',$params,'',$sortfield,$sortorder); + } + if (! empty($arrayfields['author']['checked'])) print_liste_field_titre($arrayfields['author']['label'],$_SERVER['PHP_SELF'],'','',$params,'',$sortfield,$sortorder); + if (! empty($arrayfields['t.note']['checked'])) print_liste_field_titre($arrayfields['t.note']['label'],$_SERVER['PHP_SELF'],'t.note','',$params,'',$sortfield,$sortorder); + if (! empty($arrayfields['t.task_duration']['checked'])) print_liste_field_titre($arrayfields['t.task_duration']['label'],$_SERVER['PHP_SELF'],'t.task_duration','',$params,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['value']['checked'])) print_liste_field_titre($arrayfields['value']['label'],$_SERVER['PHP_SELF'],'','',$params,'align="right"',$sortfield,$sortorder); + // Extra fields + /* + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + }*/ + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center" width="80"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; $tasktmp = new Task($db); @@ -802,7 +824,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) foreach ($tasks as $task_time) { $var=!$var; - print ""; + print ''; $date1=$db->jdate($task_time->task_date); $date2=$db->jdate($task_time->task_datehour); @@ -873,7 +895,8 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) $userstatic->id = $task_time->fk_user; $userstatic->lastname = $task_time->lastname; $userstatic->firstname = $task_time->firstname; - print $userstatic->getNomUrl(1); + $userstatic->photo = $task_time->photo; + print $userstatic->getNomUrl(-1); } print ''; if (! $i) $totalarray['nbfield']++; @@ -932,7 +955,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print $hookmanager->resPrint; // Action column - print ''; print ''; print ''; diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index ffadceafb2e..cfe05e28ec3 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -44,7 +44,7 @@ $action=GETPOST('action', 'alpha'); $id=GETPOST('account'); $ref=GETPOST('ref'); $dvid=GETPOST('dvid'); -$num=GETPOST('num'); +$numref=GETPOST('num'); // Security check $fieldid = (! empty($ref)?$ref:$id); @@ -116,7 +116,7 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($id > 0) $param.='&id='.urlencode($id); -if (empty($num)) +if (empty($numref)) { /* * Vue liste tous releves confondus @@ -176,14 +176,14 @@ if (empty($num)) while ($i < min($numrows,$conf->liste_limit)) { $objp = $db->fetch_object($result); - $var=!$var; + if (! isset($objp->numr)) { // } else { - print ''; + print ''; // Calculate start amount $sql = "SELECT sum(b.amount) as amount"; @@ -240,7 +240,7 @@ else // Recherche valeur pour num = numero releve precedent $sql = "SELECT DISTINCT(b.num_releve) as num"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; - $sql.= " WHERE b.num_releve < '".$db->escape($num)."'"; + $sql.= " WHERE b.num_releve < '".$db->escape($numref)."'"; $sql.= " AND b.fk_account = ".$object->id; $sql.= " ORDER BY b.num_releve DESC"; @@ -252,7 +252,7 @@ else if ($numrows > 0) { $obj = $db->fetch_object($resql); - $num = $obj->num; + $numref = $obj->num; $found=true; } } @@ -262,7 +262,7 @@ else // Recherche valeur pour num = numero releve precedent $sql = "SELECT DISTINCT(b.num_releve) as num"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; - $sql.= " WHERE b.num_releve > '".$db->escape($num)."'"; + $sql.= " WHERE b.num_releve > '".$db->escape($numref)."'"; $sql.= " AND b.fk_account = ".$object->id; $sql.= " ORDER BY b.num_releve ASC"; @@ -274,7 +274,7 @@ else if ($numrows > 0) { $obj = $db->fetch_object($resql); - $num = $obj->num; + $numref = $obj->num; $found=true; } } @@ -286,13 +286,16 @@ else $mesprevnext=''; $mesprevnext.=''; - print load_fiche_titre($langs->trans("AccountStatement").' '.$num.', '.$langs->trans("BankAccount").' : '.$object->getNomUrl(0, 'receipts'), $mesprevnext, 'title_bank.png'); + + $title=$langs->trans("AccountStatement").' '.$numref.', '.$langs->trans("BankAccount").' : '.$object->getNomUrl(0, 'receipts'); + print load_fiche_titre($title, $mesprevnext, 'title_bank.png'); + //print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, 0, $nbtotalofrecords, 'title_bank.png', 0, '', '', 0, 1); print '
    '; print ""; @@ -315,7 +318,7 @@ else // Calcul du solde de depart du releve $sql = "SELECT sum(b.amount) as amount"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; - $sql.= " WHERE b.num_releve < '".$db->escape($num)."'"; + $sql.= " WHERE b.num_releve < '".$db->escape($numref)."'"; $sql.= " AND b.fk_account = ".$object->id; $resql=$db->query($sql); @@ -335,8 +338,8 @@ else $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= ", ".MAIN_DB_PREFIX."bank as b"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bordereau_cheque as bc ON bc.rowid=b.fk_bordereau'; - $sql.= " WHERE b.num_releve='".$db->escape($num)."'"; - if (!isset($num)) $sql.= " OR b.num_releve is null"; + $sql.= " WHERE b.num_releve='".$db->escape($numref)."'"; + if (!isset($numref)) $sql.= " OR b.num_releve is null"; $sql.= " AND b.fk_account = ".$object->id; $sql.= " AND b.fk_account = ba.rowid"; $sql.= $db->order("b.datev, b.datec", "ASC"); // We add date of creation to have correct order when everything is done the same day @@ -368,9 +371,9 @@ else // Date de valeur print '\n"; print ''; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 66eca2409f3..7c428968c34 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3347,20 +3347,20 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so if ($cpt>=1) { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page=0'.$options.'">1'; - if ($cpt > 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'data-role="button"').'>...'; - else if ($cpt == 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page=1'.$options.'">2'; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>1'; + if ($cpt > 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'').'>...'; + else if ($cpt == 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>2'; } do { if ($cpt==$page) { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'data-role="button"').'>'.($page+1).''; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'').'>'.($page+1).''; } else { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page='.$cpt.$options.'">'.($cpt+1).''; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>'.($cpt+1).''; } $cpt++; } @@ -3368,14 +3368,14 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so if ($cpt<$nbpages) { - if ($cpt<$nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'data-role="button"').'>...'; - else if ($cpt == $nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page='.($nbpages-2).$options.'">'.($nbpages - 1).''; - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page='.($nbpages-1).$options.'">'.$nbpages.''; + if ($cpt<$nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'').'>...'; + else if ($cpt == $nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>'.($nbpages - 1).''; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>'.$nbpages.''; } } else { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'data-role="button"').'>'.($page+1).""; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'').'>'.($page+1).""; } } print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtml, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a63593292b6..77c779b268e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2469,6 +2469,7 @@ div.pagination .disabled a:focus { } div.pagination li.pagination .active { text-decoration: underline; + box-shadow: none; } div.pagination li.paginationafterarrows { margin-left: 10px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 26c4c4d0a93..553d2560790 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2533,6 +2533,7 @@ div.pagination .disabled a:focus { } div.pagination li.pagination .active { text-decoration: underline; + box-shadow: none; } div.pagination li.paginationafterarrows { margin-left: 10px; From 216bce608d38fa3c88ab1341e714c08dc43ccf4c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 23:28:06 +0200 Subject: [PATCH 321/410] Work on v6 look and feel --- htdocs/compta/bank/releve.php | 268 ++++++++++-------- .../compta/paiement/class/paiement.class.php | 12 +- htdocs/compta/salaries/card.php | 26 +- .../salaries/class/paymentsalary.class.php | 91 +++++- htdocs/fourn/class/paiementfourn.class.php | 12 +- htdocs/fourn/paiement/card.php | 18 +- 6 files changed, 268 insertions(+), 159 deletions(-) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index fdf1ac27e7a..9d9826d0729 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -92,36 +92,46 @@ if ($id > 0 || ! empty($ref)) // Initialize technical object to manage context to save list fields $contextpage='banktransactionlist'.(empty($object->ref)?'':'-'.$object->id); -/* -*ZIP creation -*/ -if($action=="dl" && $num>0 && isset($_SESSION["releve"][$num])){ - unset($zip); - $log=''; - $filearray=$_SESSION["releve"][$num]; - $zipname = $num.'.zip'; - $zip = new ZipArchive; - $zip->open($zipname, ZipArchive::OVERWRITE); - foreach ($filearray as $key=> $files) { - if(is_array($files)){ - foreach ($files as $file) { - $zip->addFile($file["fullname"],$file["name"]);// - $log.=$key.','.$file["name"]."\n"; - } - }else{ - $log.=$key.','.$langs->trans("Nofile")."\n"; - } - } - $zip->addFromString('log.csv', $log); - $zip->close(); - ///Then download the zipped file. - header('Content-Type: application/zip'); - header('Content-disposition: attachment; filename='.$zipname); - header('Content-Length: ' . filesize($zipname)); - readfile($zipname); + +// ZIP creation +if ($action=="dl" && $numref > 0) +{ + // TODO Replace this with a standard builddoc action that use a document generation module to build the ZIP + $log = ''; + + getAttachedFiles($db, $numref); // Build array $_SESSION["releve"][$numref] with all files to includes + + $filearray = $_SESSION["releve"][$numref]; + $zipname = $numref . '.zip'; + + $zip = new ZipArchive(); + $zip->open($zipname, ZipArchive::OVERWRITE); + foreach ($filearray as $key => $files) { + if (is_array($files)) { + foreach ($files as $file) { + $zip->addFile($file["fullname"], $file["name"]); // + $log .= $key . ',' . $file["name"] . "\n"; + } + } else { + $log .= $key . ',' . $langs->trans("Nofile") . "\n"; + } + } + $zip->addFromString('log '.$numref.'.csv', $log); + $zip->close(); + + // /Then download the zipped file. + header('Content-Type: application/zip'); + header('Content-disposition: attachment; filename=' . $zipname); + header('Content-Length: ' . filesize($zipname)); + + readfile($zipname); + + unset($_SESSION["releve"][$numref]); + + exit; } -unset($_SESSION["releve"][$num]); + /* * View @@ -151,9 +161,7 @@ if ($id > 0) $param.='&id='.urlencode($id); if (empty($numref)) { - /* - * Vue liste tous releves confondus - */ + // List of all standing receipts $sql = "SELECT DISTINCT(b.num_releve) as numr"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql.= " WHERE b.fk_account = ".$object->id; @@ -470,6 +478,14 @@ else $paymentvatstatic->ref=$langs->trans("Payment"); print ' '.$paymentvatstatic->getNomUrl(1); } + elseif ($links[$key]['type']=='payment_salary') + { + print ''; + print ' '.img_object($langs->trans('ShowPayment'),'payment').' '; + print $langs->trans("Payment"); + print ''; + $newline=0; + } elseif ($links[$key]['type']=='banktransfert') { // Do not show link to transfer since there is no transfer card (avoid confusion). Can already be accessed from transaction detail. if ($objp->amount > 0) @@ -512,6 +528,13 @@ else print ''; $newline=0; } + elseif ($links[$key]['type']=='user') { + print ''; + print img_object($langs->trans('ShowUser'),'user').' '; + print $links[$key]['label']; + print ''; + $newline=0; + } elseif ($links[$key]['type']=='sc') { print ''; print img_object($langs->trans('ShowBill'),'bill').' '; @@ -555,7 +578,6 @@ else dol_print_error($db); } } - print Get_attach_files($db,$objp->rowid,$num,$objp->label); print ""; if ($objp->amount < 0) @@ -598,9 +620,13 @@ else print ""; print "\n"; - // download button - echo ''.$langs->trans('DownloadFile')." \n"; - + + // Add a download button + if ($conf->global->MAIN_FEATURES_LEVEL >= 2) // Started a rewrite to make this feature more Dolibarr compliant. Still need dev to be completed. + { + // TODO Replace this with standard box to generate document. + print ''.$langs->trans('DownloadPackageWithAllDocuments')." \n"; + } } @@ -608,102 +634,102 @@ llxFooter(); $db->close(); -/*Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line - * @param $db Object database object - * @param $bankId int bank line id - * @param $num int bank statement - * @param $label string label used to optimise the sql querry + + + +/** + * Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line * + * @param DoliDB $db database object + * @param int $bankId bank line id + * @param int $num bank statement + * @param string $label label used to optimise the sql querry */ -function Get_attach_files($db, $bankId,$num,$label=''){ - $out=''; - global$conf; - $sql='SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; - $sql.=' e.`ref` AS refe, sp.rowid AS ids, d.rowid AS idd'; - $sql.=' FROM '.MAIN_DB_PREFIX.'bank_url AS u'; - if ( !empty($label) || $label=='(CustomerInvoicePayment)'){ - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement AS p ON p.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture AS pf ON pf.fk_paiement = p.rowid'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture AS f ON f.rowid = pf.fk_facture'; +function getAttachedFiles($db, $numref, $label='') +{ + $out = ''; + global $conf; + $sql = 'SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; + $sql .= ' e.`ref` AS refe, sp.rowid AS ids, d.rowid AS idd'; + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'bank_url AS u, ' . MAIN_DB_PREFIX . 'bank AS b'; + if (! empty($label) || $label == '(CustomerInvoicePayment)') { + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiement AS p ON p.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiement_facture AS pf ON pf.fk_paiement = p.rowid'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'facture AS f ON f.rowid = pf.fk_facture'; } - if( !empty($label) || $label=='(SupplierInvoicePayment)'){ - //invoice suplier (SupplierInvoicePayment) - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn AS fp ON fp.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS fpf ON fpf.fk_paiementfourn = fp.rowid'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS ff ON ff.rowid = fpf.fk_facturefourn'; + if (! empty($label) || $label == '(SupplierInvoicePayment)') { + // invoice suplier (SupplierInvoicePayment) + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiementfourn AS fp ON fp.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiementfourn_facturefourn AS fpf ON fpf.fk_paiementfourn = fp.rowid'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'facture_fourn AS ff ON ff.rowid = fpf.fk_facturefourn'; } - if( !empty($label) || $label=='(ExpenseReportPayment)'){ - //EXPENSEs (ExpenseReportPayment) - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_expensereport AS ep ON ep.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport AS e ON e.rowid = ep.fk_expensereport'; + if (! empty($label) || $label == '(ExpenseReportPayment)') { + // EXPENSEs (ExpenseReportPayment) + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'payment_expensereport AS ep ON ep.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'expensereport AS e ON e.rowid = ep.fk_expensereport'; } - if( !empty($label) || $label=='(DonationPayment)'){ - //donation - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_donation AS dp ON dp.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'don AS d ON d.rowid = dp.fk_donation'; + if (! empty($label) || $label == '(DonationPayment)') { + // donation + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'payment_donation AS dp ON dp.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'don AS d ON d.rowid = dp.fk_donation'; } - if( !empty($label) || $label=='(SalaryPayment)'){ - //loan -// $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_loan AS lp ON lp.fk_bank = u.fk_bank'; - //salary - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_salary AS sp ON sp.fk_bank = u.fk_bank'; + if (! empty($label) || $label == '(SalaryPayment)') { + // loan + // $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_loan AS lp ON lp.fk_bank = u.fk_bank'; + // salary + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'payment_salary AS sp ON sp.fk_bank = u.fk_bank'; } - //END SQL - $sql.=" WHERE u.fk_bank in('".$bankId."')AND u.type in ('payment','payment_supplier','payment_expensereport','payment_salary','payment_donation' )"; + // END SQL + $sql .= " WHERE u.fk_bank = b.rowid AND u.type in ('payment','payment_supplier','payment_expensereport','payment_salary','payment_donation' )"; $resd = $db->query($sql); - $files=array(); - $link=''; - if ($resd) - { - $numd = $db->num_rows($resd); - $upload_dir =''; - $i=0; - if($numd>0) - { - - + $files = array(); + $link = ''; + if ($resd) { + $numd = $db->num_rows($resd); + $upload_dir = ''; + $i = 0; + if ($numd > 0) + { $objd = $db->fetch_object($resd); - - switch($objd->type){ - case "payment": - $subdir=dol_sanitizeFileName($objd->ref); - $upload_dir = $conf->facture->dir_output.'/'.$subdir; - $link="../../document.php?modulepart=facture&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - - case "payment_supplier": - $subdir=get_exdir($objd->id,2,0,0,$objd,'invoice_supplier').$objd->reff; - $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; - $link="../../document.php?modulepart=facture_fournisseur&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - case "payment_expensereport": - $subdir=dol_sanitizeFileName($objd->refe); - $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; - $link="../../document.php?modulepart=expensereport&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - case "payment_salary": - $subdir=dol_sanitizeFileName($objd->ids); - $upload_dir = $conf->salaries->dir_output.'/'.$subdir; - $link="../../document.php?modulepart=salaries&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - case "payment_donation": - $subdir=get_exdir(null,2,0,1,$objd,'donation'). '/'. dol_sanitizeFileName($objd->idd); - $upload_dir = $conf->don->dir_output . '/' . $subdir; - $link="../../document.php?modulepart=don&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - default: - break; + + switch ($objd->type) { + case "payment": + $subdir = dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->facture->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=facture&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_supplier": + $subdir = get_exdir($objd->id, 2, 0, 0, $objd, 'invoice_supplier') . $objd->reff; + $upload_dir = $conf->fournisseur->facture->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=facture_fournisseur&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_expensereport": + $subdir = dol_sanitizeFileName($objd->refe); + $upload_dir = $conf->expensereport->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=expensereport&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_salary": + $subdir = dol_sanitizeFileName($objd->ids); + $upload_dir = $conf->salaries->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=salaries&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_donation": + $subdir = get_exdir(null, 2, 0, 1, $objd, 'donation') . '/' . dol_sanitizeFileName($objd->idd); + $upload_dir = $conf->don->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=don&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + default: + break; } - if(!empty($upload_dir)){ - $files=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$','',SORT_ASC,1); - foreach ($files as $key => $file){ - $out.= '
    '.$file['name'].''; - } - $_SESSION["releve"][$num][]=$files; + if (! empty($upload_dir)) + { + $files = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview\.png)$', '', SORT_ASC, 1); + $_SESSION["releve"][$numref][] = $files; } - } - } - $db->free($resd); - return $out; + } + } + + $db->free($resd); + return $out; } diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 099d05cfa84..61d2b5a3b8a 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -37,7 +37,8 @@ class Paiement extends CommonObject { public $element='payment'; public $table_element='paiement'; - + public $picto = 'payment'; + var $facid; var $datepaye; /** @@ -1016,7 +1017,7 @@ class Paiement extends CommonObject global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage $langs->load('compta'); - if ($mode == 0) + /*if ($mode == 0) { if ($status == 0) return $langs->trans('ToValidate'); if ($status == 1) return $langs->trans('Validated'); @@ -1046,7 +1047,12 @@ class Paiement extends CommonObject if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); } - return $langs->trans('Unknown'); + if ($mode == 6) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + }*/ + return ''; } } diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index df83f5b9958..569aa81629e 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -202,11 +202,7 @@ if ($id) } } -/* ************************************************************************** */ -/* */ -/* create mode */ -/* */ -/* ************************************************************************** */ +// Create if ($action == 'create') { $year_current = strftime("%Y",dol_now()); @@ -332,19 +328,19 @@ if ($id) $head=salaries_prepare_head($object); - dol_fiche_head($head, 'card', $langs->trans("SalaryPayment"), 0, 'payment'); - - print '
    '.$form->select_dolusers($search_user > 0 ? $search_user : -1, 'search_user', 1).''; + print ''; $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); print $searchpitco; print '
    '; + print ''; if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) { print ''; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 112609ce521..8529a0c0cfc 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1987,7 +1987,7 @@ class User extends CommonObject if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; $result=''; $label=''; - $linkstart=''; $linkend=''; + $link=''; $linkstart=''; $linkend=''; if (! empty($this->photo)) { @@ -2086,7 +2086,9 @@ class User extends CommonObject } $result.=$linkend; //if ($withpictoimg == -1) $result.=''; + $result.=$companylink; + return $result; } From fe4f71296f13a2231bfbe603d8ed9dd256026cfd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 21:55:23 +0200 Subject: [PATCH 319/410] FIX #6636 Complete fix --- htdocs/compta/bank/categ.php | 2 +- htdocs/core/menus/standard/eldy.lib.php | 4 ++-- htdocs/langs/en_US/categories.lang | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/bank/categ.php b/htdocs/compta/bank/categ.php index 51030242fce..ae35eee80fa 100644 --- a/htdocs/compta/bank/categ.php +++ b/htdocs/compta/bank/categ.php @@ -80,7 +80,7 @@ if ($categid) { llxHeader(); -print load_fiche_titre($langs->trans("Rubriques"), '', 'title_bank.png'); +print load_fiche_titre($langs->trans("RubriquesTransactions"), '', 'title_bank.png'); print '
    '; print ''; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index eab8f5a8c19..aa98f23b2ad 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1073,8 +1073,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $langs->load("categories"); $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags'); $newmenu->add("/categories/card.php?action=create&type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer); - $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),1,$user->rights->banque->configurer); - + $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags'); + $newmenu->add("/compta/bank/categ.php",$langs->trans("NewCategory"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags'); } // Prelevements diff --git a/htdocs/langs/en_US/categories.lang b/htdocs/langs/en_US/categories.lang index 976c8a50d93..b8a1e5ef58b 100644 --- a/htdocs/langs/en_US/categories.lang +++ b/htdocs/langs/en_US/categories.lang @@ -1,6 +1,7 @@ # Dolibarr language file - Source file is en_US - categories Rubrique=Tag/Category Rubriques=Tags/Categories +RubriquesTransactions=Tags/Categories of transactions categories=tags/categories NoCategoryYet=No tag/category of this type created In=In From a99a4be9e01594d075216d767edf2e6f7177215d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 22:31:45 +0200 Subject: [PATCH 320/410] Work on 6.0 look and feel --- htdocs/compta/bank/class/account.class.php | 5 +-- htdocs/compta/bank/ligne.php | 2 +- htdocs/compta/bank/releve.php | 37 ++++++++++++---------- htdocs/core/lib/functions.lib.php | 18 +++++------ htdocs/theme/eldy/style.css.php | 1 + htdocs/theme/md/style.css.php | 1 + 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 8925a67d593..d360dc5207e 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1243,9 +1243,10 @@ class Account extends CommonObject * * @param int $withpicto Include picto into link * @param string $mode ''=Link to card, 'transactions'=Link to transactions card + * @param string $option ''=Show ref, 'reflabel'=Show ref+label * @return string Chaine avec URL */ - function getNomUrl($withpicto=0, $mode='') + function getNomUrl($withpicto=0, $mode='', $option='') { global $conf, $langs; @@ -1279,7 +1280,7 @@ class Account extends CommonObject } if ($withpicto) $result.=($link.img_object($label, 'account', 'class="classfortooltip"').$linkend.' '); - $result.=$link.$this->ref.$linkend; + $result.=$link.$this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '').$linkend; return $result; } diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index f77ac86af7f..360a0d15a00 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -293,7 +293,7 @@ if ($result) // Bank account print '
    '.$langs->trans("Account").''; - print $acct->getNomUrl(1,'transactions'); + print $acct->getNomUrl(1,'transactions','reflabel'); print '
    '.$objp->numr.'
    '.$objp->numr.''; print dol_print_date($db->jdate($objp->dv),"day") .' '; - print ''; + print ''; print img_edit_remove() . " "; - print ''; + print ''; print img_edit_add() .""; print "
    '; + dol_fiche_head($head, 'card', $langs->trans("SalaryPayment"), -1, 'payment'); $linkback = ''.$langs->trans("BackToList").''; - print ""; - print ''; + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', ''); + + print '
    '; + print '
    '; + + print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'ref', ''); - print '
    '; // Employee - print '
    '.$langs->trans("Employee").''; + print '
    '.$langs->trans("Employee").''; $usersal=new User($db); $usersal->fetch($object->fk_user); print $usersal->getNomUrl(1); @@ -394,7 +390,9 @@ if ($id) $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook print '
    '; - + + print '
    '; + dol_fiche_end(); diff --git a/htdocs/compta/salaries/class/paymentsalary.class.php b/htdocs/compta/salaries/class/paymentsalary.class.php index a4bee09d7de..6c151272035 100644 --- a/htdocs/compta/salaries/class/paymentsalary.class.php +++ b/htdocs/compta/salaries/class/paymentsalary.class.php @@ -33,20 +33,21 @@ class PaymentSalary extends CommonObject { //public $element='payment_salary'; //!< Id that identify managed objects //public $table_element='payment_salary'; //!< Name of table without prefix where object is stored - - var $tms; - var $fk_user; - var $datep; - var $datev; - var $amount; - var $type_payment; - var $num_payment; - var $label; - var $datesp; - var $dateep; - var $fk_bank; - var $fk_user_author; - var $fk_user_modif; + public $picto='payment'; + + public $tms; + public $fk_user; + public $datep; + public $datev; + public $amount; + public $type_payment; + public $num_payment; + public $label; + public $datesp; + public $dateep; + public $fk_bank; + public $fk_user_author; + public $fk_user_modif; /** @@ -547,4 +548,66 @@ class PaymentSalary extends CommonObject } } + + /** + * Retourne le libelle du statut d'une facture (brouillon, validee, abandonnee, payee) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Libelle + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut,$mode); + } + + /** + * Renvoi le libelle d'un statut donne + * + * @param int $status Statut + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Libelle du statut + */ + function LibStatut($status,$mode=0) + { + global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage + + $langs->load('compta'); + /*if ($mode == 0) + { + if ($status == 0) return $langs->trans('ToValidate'); + if ($status == 1) return $langs->trans('Validated'); + } + if ($mode == 1) + { + if ($status == 0) return $langs->trans('ToValidate'); + if ($status == 1) return $langs->trans('Validated'); + } + if ($mode == 2) + { + if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate'); + if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated'); + } + if ($mode == 3) + { + if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return img_picto($langs->trans('Validated'),'statut4'); + } + if ($mode == 4) + { + if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate'); + if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated'); + } + if ($mode == 5) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + } + if ($mode == 6) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + }*/ + return ''; + } + } diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index 5d8279b1c54..be87fbc7512 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -36,7 +36,8 @@ class PaiementFourn extends Paiement { public $element='payment_supplier'; public $table_element='paiementfourn'; - + public $picto = 'payment'; + var $statut; //Status of payment. 0 = unvalidated; 1 = validated // fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...) // fk_paiement dans llx_paiement_facture est le rowid du paiement @@ -486,7 +487,7 @@ class PaiementFourn extends Paiement global $langs; $langs->load('compta'); - if ($mode == 0) + /*if ($mode == 0) { if ($status == 0) return $langs->trans('ToValidate'); if ($status == 1) return $langs->trans('Validated'); @@ -516,7 +517,12 @@ class PaiementFourn extends Paiement if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); } - return $langs->trans('Unknown'); + if ($mode == 6) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + }*/ + return ''; } diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 9cb44a92bb8..c8e882e5003 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -179,7 +179,7 @@ $formfile = new FormFile($db); $head = payment_supplier_prepare_head($object); -dol_fiche_head($head, 'payment', $langs->trans('SupplierPayment'), 0, 'payment'); +dol_fiche_head($head, 'payment', $langs->trans('SupplierPayment'), -1, 'payment'); if ($result > 0) { @@ -201,15 +201,23 @@ if ($result > 0) } + $linkback = '' . $langs->trans("BackToList") . ''; + + + dol_banner_tab($object,'id',$linkback,1,'rowid','ref'); + + print '
    '; + print '
    '; + print ''; - print ''; + /*print ''; print ''; + print '';*/ // Date payment - print ''; @@ -270,6 +278,8 @@ if ($result > 0) print '
    '.$langs->trans('Ref').''; print $form->showrefnav($object,'id','',1,'rowid','ref'); - print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).''; + print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).''; print $form->editfieldval("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'datepicker','',null,$langs->trans('PaymentDateUpdateSucceeded')); print '
    '; + print '
    '; + print '
    '; /** From 76687028063578ceae53b626d93348bbeee32161 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 7 Apr 2017 08:56:10 +0200 Subject: [PATCH 322/410] fix: missing attribute update --- htdocs/fourn/class/fournisseur.commande.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 98939ee01f2..70c3f1a831a 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1503,6 +1503,7 @@ class CommandeFournisseur extends CommonOrder $this->line->product_type=$product_type; $this->line->remise_percent=$remise_percent; $this->line->subprice=$pu_ht; + $this->line->rang=$this->rang; $this->line->info_bits=$info_bits; $this->line->vat_src_code=$vat_src_code; From ea44e14b605725457bf6cf5f6293c9acf47184e3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 11:01:12 +0200 Subject: [PATCH 323/410] Start debug the variant module --- htdocs/compta/index.php | 12 +- htdocs/core/class/html.formfile.class.php | 2 + htdocs/langs/en_US/products.lang | 3 + htdocs/product/card.php | 1 + htdocs/product/class/product.class.php | 5 + htdocs/product/index.php | 16 +-- htdocs/variants/combinations.php | 162 ++++++++++++++-------- htdocs/variants/generator.php | 46 +++--- 8 files changed, 143 insertions(+), 104 deletions(-) diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index ea8d47b264e..736d5696c3e 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -233,7 +233,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- if ( $resql ) { - $var = false; $num = $db->num_rows($resql); print ''; @@ -248,7 +247,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- while ($i < $num) { $obj = $db->fetch_object($resql); - print ''; $tot_ttc+=$obj->total_ttc; $i++; - $var=!$var; } print ''; @@ -278,7 +276,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- } else { - print ''; + print ''; } print "
    '; + print '
    '; $facturesupplierstatic->ref=$obj->ref; $facturesupplierstatic->id=$obj->rowid; $facturesupplierstatic->total_ht=$obj->total_ht; @@ -269,7 +268,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- print '
    '.$langs->trans("Total").'
    '.$langs->trans("NoInvoice").'
    '.$langs->trans("NoInvoice").'

    "; $db->free($resql); @@ -768,6 +766,7 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) $num = $db->num_rows($resql); $i = 0; + print '
    '; print ''; print ''; print ''; @@ -848,7 +847,7 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) $colspan++; print ''; } - print '
    '.$langs->trans("BillsCustomersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").'
    '.$langs->trans("NoInvoice").'

    '; + print '

    '; $db->free($resql); } else @@ -890,6 +889,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- $var=false; $num = $db->num_rows($resql); + print '
    '; print ''; print ''; print ''; @@ -948,7 +948,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) $colspan++; print ''; } - print '
    '.$langs->trans("BillsSuppliersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").'
    '.$langs->trans("NoInvoice").'

    '; + print '

    '; } else { diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 1e2dc1c4938..647d0cf6a76 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -593,6 +593,7 @@ class FormFile $out.= ''; $out.= load_fiche_titre($titletoshow, '', ''); + $out.= '
    '; $out.= ''; $out.= ''; @@ -802,6 +803,7 @@ class FormFile { // Affiche pied du tableau $out.= "
    \n"; + $out.= "
    \n"; if ($genallowed) { if (empty($noform)) $out.= ''."\n"; diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 046521e398e..ef4c13c89cc 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -287,6 +287,9 @@ HideProductCombinations=Hide products variant in the products selector ProductCombination=Variant NewProductCombination=New variant EditProductCombination=Editing variant +NewProductCombinations=New variants +EditProductCombinations=Editing variants +SelectCombination=Select combination ProductCombinationGenerator=Variants generator Features=Features PriceImpact=Price impact diff --git a/htdocs/product/card.php b/htdocs/product/card.php index ac260fc99fb..0c6109ba64a 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -2015,6 +2015,7 @@ if (! empty($conf->global->PRODUCT_ADD_FORM_ADD_TO) && $object->id && ($action = /* * Documents generes */ + if ($action != 'edit' && $action != 'delete') { print '
    '; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 23be6de5111..5f5b6f6eae9 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3559,6 +3559,11 @@ class Product extends CommonObject if ($status == 0) return ($type==0 ? $langs->trans('ProductStatusNotOnSellShort'):$langs->trans('ProductStatusNotOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusNotOnSell'):$langs->trans('ProductStatusNotOnBuy')), 'statut5', 'class="pictostatus"'); if ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"'); } + if ($mode == 6) + { + if ($status == 0) return ($type==0 ? $langs->trans('ProductStatusNotOnSellShort'):$langs->trans('ProductStatusNotOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusNotOnSell'):$langs->trans('ProductStatusNotOnBuy')), 'statut5', 'class="pictostatus"'); + if ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"'); + } return $langs->trans('Unknown'); } diff --git a/htdocs/product/index.php b/htdocs/product/index.php index 355e0d2757f..73447e456e6 100644 --- a/htdocs/product/index.php +++ b/htdocs/product/index.php @@ -130,26 +130,26 @@ print ''; print ''; if (! empty($conf->product->enabled)) { - $statProducts = ""; + $statProducts = ''; $statProducts.= ''; $statProducts.= ""; - $statProducts.= ""; + $statProducts.= ''; $statProducts.= ''; $statProducts.= ""; - $statProducts.= ""; + $statProducts.= ''; $statProducts.= ''; $statProducts.= ""; } if (! empty($conf->service->enabled)) { - $statServices = ""; + $statServices = ''; $statServices.= ''; $statServices.= ""; - $statServices.= ""; + $statServices.= ''; $statServices.= ''; $statServices.= ""; - $statServices.= ""; + $statServices.= ''; $statServices.= ''; $statServices.= ""; @@ -325,10 +325,10 @@ if ($result) print ''; } print '"; print '"; print "\n"; $i++; diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index dabace75ac0..cfbec4a8016 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -36,6 +36,7 @@ $price_impact = (float) GETPOST('price_impact'); $price_impact_percent = (bool) GETPOST('price_impact_percent'); $form = new Form($db); $action = GETPOST('action'); +$cancel = GETPOST('cancel'); // Security check $fieldvalue = (! empty($id) ? $id : $ref); @@ -57,6 +58,10 @@ if ($id > 0 || $ref) * Actions */ +if ($cancel) { + $action=''; +} + if (! $object->isProduct()) { header('Location: '.dol_buildpath('/product/card.php?id='.$object->id, 2)); exit(); @@ -107,7 +112,7 @@ if ($_POST) { $db->begin(); if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) { - if (ProductCombination::createProductCombination($product, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact)) { + if (ProductCombination::createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact)) { $db->commit(); setEventMessage($langs->trans('RecordSaved')); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2)); @@ -175,7 +180,7 @@ if ($_POST) { setEventMessage($langs->trans('RecordSaved')); } - } else { + } elseif ($valueid > 0) { if ($prodcomb->fetch($valueid) < 0) { dol_print_error($db, $langs->trans('ErrorRecordNotFound')); @@ -256,6 +261,9 @@ if ($action === 'confirm_deletecombination') { * View */ +$form = new Form($db); + + if (! empty($id) || ! empty($ref)) { llxHeader("", "", $langs->trans("CardProduct".$object->type)); @@ -342,6 +350,7 @@ if (! empty($id) || ! empty($ref)) { var select = jQuery("select#features"); select.empty(); + jQuery("form#combinationform input[type=hidden]").detach(); jQuery.each(variants_selected.index, function (key, val) { @@ -359,11 +368,12 @@ if (! empty($id) || ! empty($ref)) { jQuery(document).ready(function() { jQuery("select#attribute").change(function () { - console.log("Change of field attribute"); + console.log("Change of field variant attribute"); var select = jQuery("select#value"); if (!jQuery(this).val().length || jQuery(this).val() == '-1') { select.empty(); + select.append(''); return; } @@ -373,22 +383,27 @@ if (! empty($id) || ! empty($ref)) { id: jQuery(this).val() }, function(data) { if (data.error) { - jQuery("select#value").empty(); + select.empty(); + select.append(''); return alert(data.error); } select.empty(); - /* console.log(data.length); */ + select.append(''); jQuery(data).each(function (key, val) { keyforoption = val.id valforoption = val.value - jQuery("select#value").append(''); + select.append(''); }); }); }); + /* Click on button Add combination + @FIXME Not compatible with all browsers. + */ jQuery("#addfeature").click(function () { + console.log("Click on add"); var selectedattr = jQuery("select[name=attribute] option:selected"); var selectedvalu = jQuery("select[name=value] option:selected"); @@ -438,54 +453,69 @@ if (! empty($id) || ! empty($ref)) { '; + print ''; + print ''; + print dol_fiche_head(); ?>
    '.$langs->trans("Statistics").'
    '.$langs->trans("ProductsNotOnSell").''.round($prodser[0][0]).'
    '.$langs->trans("ProductsOnSell").''.round($prodser[0][1]).'
    '.$langs->trans("ProductsOnSellAndOnBuy").''.round($prodser[0][2]).'
    '.$langs->trans("ServicesNotOnSell").''.round($prodser[1][0]).'
    '.$langs->trans("ServicesOnSell").''.round($prodser[1][1]).'
    '.$langs->trans("ServicesOnSellAndOnBuy").''.round($prodser[1][2]).'
    '; - print $product_static->LibStatut($objp->tosell,5,0); + print $product_static->LibStatut($objp->tosell,3,0); print "'; - print $product_static->LibStatut($objp->tobuy,5,1); + print $product_static->LibStatut($objp->tobuy,3,1); print "
    + - + - - - - + +
    +
    + trans("SelectCombination"); ?> +
    +
    + + + + + + +
    + +
    + - - +
    +
    +
    - -

    - -
    + >
    @@ -494,8 +524,10 @@ if (! empty($id) || ! empty($ref)) { ?>
    - -
    + +   + +
    @@ -509,7 +541,6 @@ if (! empty($id) || ! empty($ref)) { if ($action === 'delete') { if ($prodcomb->fetch($valueid) > 0) { - $form = new Form($db); $prodstatic->fetch($prodcomb->fk_product_child); print $form->formconfirm( @@ -524,8 +555,6 @@ if (! empty($id) || ! empty($ref)) { } } elseif ($action === 'copy') { - $form = new Form($db); - print $form->formconfirm( 'combinations.php?id='.$id, $langs->trans('CloneCombinationsProduct'), @@ -570,50 +599,64 @@ if (! empty($id) || ! empty($ref)) { }); - - - - - " class="button"> -
    -
    '; + print '
    '; if ($productCombinations) { print ''.$langs->trans('Copy').''; } + print ''.$langs->trans('NewProductCombination').''; - print ''.$langs->trans('ProductCombinationGenerator').''; + + if (empty($conf->dol_optimize_smallscreen) && $conf->use_javascript_ajax) // Bugged page. Too much useless javascript. + { + print ''.$langs->trans('ProductCombinationGenerator').''; + } + print '
    '; + print '
    '; + print ''; + $aaa=''; + if (count($productCombinations)) + { + $aaa = ''; + $aaa .= ''; + $aaa .= ''; + $aaa .= ''; + } + $title = $langs->trans("ProductCombinations"); + + print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $aaa, 0); + + print '
    '; ?> - - + + + + + + + - - - - - - - fetch($currcomb->fk_product_child); ?> - > - + - - + + - +
    + trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?> trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?>
    getNomUrl(1) ?> variation_price >= 0 ? '+' : '').price($currcomb->variation_price).($currcomb->variation_price_percentage ? ' %' : '') ?>variation_weight >= 0 ? '+' : '').price($currcomb->variation_weight).' '.measuring_units_string($prodstatic->weight_units, 'weight') ?>variation_price >= 0 ? '+' : '').price($currcomb->variation_price).($currcomb->variation_price_percentage ? ' %' : '') ?>variation_weight >= 0 ? '+' : '').price($currcomb->variation_weight).' '.measuring_units_string($prodstatic->weight_units, 'weight') ?> getLibStatut(2, 0) ?> getLibStatut(2, 1) ?> - - + + +
    - - - - '; + print ''; } } llxFooter(); + +$db->close(); diff --git a/htdocs/variants/generator.php b/htdocs/variants/generator.php index b709f240551..7b0358fd176 100644 --- a/htdocs/variants/generator.php +++ b/htdocs/variants/generator.php @@ -130,6 +130,8 @@ if ($_POST) { } } + + /* * View */ @@ -140,37 +142,21 @@ if (! empty($id) || ! empty($ref)) { llxHeader("", "", $langs->trans("CardProduct".$object->type)); - if ($result) { - $head = product_prepare_head($object); - $titre = $langs->trans("CardProduct".$object->type); - $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product'); - + if ($result > 0) + { + $showbarcode=empty($conf->barcode->enabled)?0:1; + if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) $showbarcode=0; + + $head=product_prepare_head($object); + $titre=$langs->trans("CardProduct".$object->type); + $picto=($object->type== Product::TYPE_SERVICE?'service':'product'); dol_fiche_head($head, 'combinations', $titre, 0, $picto); - - print ''; - - // Reference - print ''; - print ''; - print ''; - - // Label - print ''; - - // Status (to sell) - print ''; - - // Status (to buy) - print ''; - - print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object, 'id', '', 0); - print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Status").' ('.$langs->trans("Sell").')'; - print $object->getLibStatut(2, 0); - print '
    '.$langs->trans("Status").' ('.$langs->trans("Buy").')'; - print $object->getLibStatut(2, 1); - print '
    '; - + + $linkback = ''.$langs->trans("BackToList").''; + $object->next_prev_filter=" fk_product_type = ".$object->type; + + dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', '', '', '', 0, '', '', 1); + dol_fiche_end(); } From a6ec22d7fee41c954b37249909271c6370047eff Mon Sep 17 00:00:00 2001 From: altatof Date: Fri, 7 Apr 2017 12:06:15 +0200 Subject: [PATCH 324/410] FIX: dont lose supplier ref if no supplier price in database --- htdocs/fourn/class/fournisseur.commande.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index b2f2d3dc3c3..44364a884eb 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1373,7 +1373,7 @@ class CommandeFournisseur extends CommonOrder if ($result > 0) { $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice - $ref = $prod->ref_fourn; // Ref supplier price set by get_buyprice + $fourn_ref = $prod->ref_fourn; // Ref supplier price set by get_buyprice } if ($result == 0) // If result == 0, we failed to found the supplier reference price { @@ -1457,7 +1457,7 @@ class CommandeFournisseur extends CommonOrder $sql.= ", '".$localtax1_type."',"; $sql.= " '".$localtax2_type."'"; - $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$ref."',"; + $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$fourn_ref."',"; $sql.= "'".price2num($total_ht)."',"; $sql.= "'".price2num($total_tva)."',"; $sql.= "'".price2num($total_localtax1)."',"; From 919633b2beb65208d4b9c309b3dbf28a4ffd8d36 Mon Sep 17 00:00:00 2001 From: altatof Date: Fri, 7 Apr 2017 12:10:01 +0200 Subject: [PATCH 325/410] escape supplier ref --- 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 44364a884eb..99babcda7fe 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1457,7 +1457,7 @@ class CommandeFournisseur extends CommonOrder $sql.= ", '".$localtax1_type."',"; $sql.= " '".$localtax2_type."'"; - $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$fourn_ref."',"; + $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$this->db->escape($fourn_ref)."',"; $sql.= "'".price2num($total_ht)."',"; $sql.= "'".price2num($total_tva)."',"; $sql.= "'".price2num($total_localtax1)."',"; From aa47575b13f64e2b062a796168be7feb2fd8252c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 12:22:59 +0200 Subject: [PATCH 326/410] Serious debug of variant module. No more fu.. js errors on smarpthone. --- htdocs/langs/en_US/products.lang | 3 +- htdocs/variants/combinations.php | 282 +++++++++++++++---------------- 2 files changed, 140 insertions(+), 145 deletions(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index ef4c13c89cc..72ec89c55d3 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -283,6 +283,7 @@ ProductAttributeValueDeleteDialog=Are you sure you want to delete the value "%s" ProductCombinationDeleteDialog=Are you sure want to delete the variant of the product "%s"? ProductCombinationAlreadyUsed=There was an error while deleting the variant. Please check it is not being used in any object ProductCombinations=Variants +PropagateVariant=Propagate variants HideProductCombinations=Hide products variant in the products selector ProductCombination=Variant NewProductCombination=New variant @@ -307,7 +308,7 @@ NbOfDifferentValues=Nb of different values NbProducts=Nb. of products ParentProduct=Parent product HideChildProducts=Hide variant products -ConfirmCloneProductCombinations=Would you like to copy all the product variant to the product with the given reference? +ConfirmCloneProductCombinations=Would you like to copy all the product variants to the other parent product with the given reference? CloneDestinationReference=Destination product reference ErrorCopyProductCombinations=There was an error while copying the product variants ErrorDestinationProductNotFound=Destination product not found diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index cfbec4a8016..4342b352478 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -1,6 +1,6 @@ +/* Copyright (C) 2016 Marcos García + * Copyright (C) 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 @@ -35,7 +35,12 @@ $weight_impact = (float) GETPOST('weight_impact'); $price_impact = (float) GETPOST('price_impact'); $price_impact_percent = (bool) GETPOST('price_impact_percent'); $form = new Form($db); -$action = GETPOST('action'); + +$action=GETPOST('action','alpha'); +$massaction=GETPOST('massaction','alpha'); +$show_files=GETPOST('show_files','int'); +$confirm=GETPOST('confirm','alpha'); +$toselect = GETPOST('toselect', 'array'); $cancel = GETPOST('cancel'); // Security check @@ -53,6 +58,8 @@ if ($id > 0 || $ref) $object->fetch($id, $ref); } +$selectedvariant = $_SESSION['addvariant_'.$object->id]; + /* * Actions @@ -60,13 +67,25 @@ if ($id > 0 || $ref) if ($cancel) { $action=''; + $massactions=''; + unset($_SESSION['addvariant_'.$object->id]); } - + if (! $object->isProduct()) { header('Location: '.dol_buildpath('/product/card.php?id='.$object->id, 2)); exit(); } +if (GETPOST('selectvariant')) +{ + $action = 'add'; + if (GETPOST('attribute') != '-1' && GETPOST('value') != '-1') + { + $selectedvariant[GETPOST('attribute').':'.GETPOST('value')]=GETPOST('attribute').':'.GETPOST('value'); + $_SESSION['addvariant_'.$object->id]=$selectedvariant; + } +} + $prodcomb = new ProductCombination($db); $prodcomb2val = new ProductCombination2ValuePair($db); @@ -75,13 +94,16 @@ $productCombination2ValuePairs1 = array(); if ($_POST) { - if ($action == 'add') { + if (($action == 'add' || $action == 'create') && empty($massaction) && ! GETPOST('selectvariant')) { - $features = GETPOST('features', 'array'); + //$features = GETPOST('features', 'array'); + $features = $_SESSION['addvariant_'.$object->id]; if (!$features) { setEventMessage($langs->trans('ErrorFieldsRequired'), 'errors'); - } else { + } + else + { $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); $sanit_features = array(); @@ -115,6 +137,7 @@ if ($_POST) { if (ProductCombination::createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact)) { $db->commit(); setEventMessage($langs->trans('RecordSaved')); + unset($_SESSION['addvariant_'.$object->id]); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2)); exit(); } else { @@ -126,17 +149,17 @@ if ($_POST) { $db->rollback(); } - } elseif ($action == 'bulk_actions') { - - $prodarray = array_keys(GETPOST('select', 'array')); - $bulkaction = GETPOST('bulk_action'); + } + elseif (! empty($massaction)) + { + $bulkaction = $massaction; $error = 0; $prodstatic = new Product($db); $db->begin(); - foreach ($prodarray as $prodid) { + foreach ($toselect as $prodid) { if ($prodstatic->fetch($prodid) < 0) { continue; @@ -180,7 +203,8 @@ if ($_POST) { setEventMessage($langs->trans('RecordSaved')); } - } elseif ($valueid > 0) { + } + elseif ($valueid > 0) { if ($prodcomb->fetch($valueid) < 0) { dol_print_error($db, $langs->trans('ErrorRecordNotFound')); @@ -201,6 +225,7 @@ if ($_POST) { } } +// Reload variants $productCombinations = $prodcomb->fetchAllByFkProductParent($object->id); if ($action === 'confirm_deletecombination') { @@ -263,29 +288,26 @@ if ($action === 'confirm_deletecombination') { $form = new Form($db); - -if (! empty($id) || ! empty($ref)) { - +if (! empty($id) || ! empty($ref)) +{ llxHeader("", "", $langs->trans("CardProduct".$object->type)); - if ($result) - { - $showbarcode=empty($conf->barcode->enabled)?0:1; - if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) $showbarcode=0; - - $head=product_prepare_head($object); - $titre=$langs->trans("CardProduct".$object->type); - $picto=($object->type== Product::TYPE_SERVICE?'service':'product'); - dol_fiche_head($head, 'combinations', $titre, 0, $picto); - - $linkback = ''.$langs->trans("BackToList").''; - $object->next_prev_filter=" fk_product_type = ".$object->type; - - dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', '', '', '', 0, '', '', 1); - - dol_fiche_end(); - } + $showbarcode=empty($conf->barcode->enabled)?0:1; + if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) $showbarcode=0; + + $head=product_prepare_head($object); + $titre=$langs->trans("CardProduct".$object->type); + $picto=($object->type== Product::TYPE_SERVICE?'service':'product'); + dol_fiche_head($head, 'combinations', $titre, 0, $picto); + + $linkback = ''.$langs->trans("BackToList").''; + $object->next_prev_filter=" fk_product_type = ".$object->type; + + dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', '', '', '', 0, '', '', 1); + + dol_fiche_end(); + // Create or edit a varian if ($action == 'add' || ($action == 'edit')) { @@ -295,6 +317,7 @@ if (! empty($id) || ! empty($ref)) { $title = $langs->trans('EditProductCombination'); } + print '
    '; print_fiche_titre($title); if ($action == 'add') { @@ -312,7 +335,7 @@ if (! empty($id) || ! empty($ref)) { ?> - + '; - print ''; + print '
    '."\n"; + print ''."\n"; + print ''."\n"; print dol_fiche_head(); @@ -483,7 +439,8 @@ if (! empty($id) || ! empty($ref)) { - trans("SelectCombination"); ?> + "> + @@ -493,17 +450,27 @@ if (! empty($id) || ! empty($ref)) { - @@ -524,15 +491,12 @@ if (! empty($id) || ! empty($ref)) { ?>
    - + value="trans('Create') : $langs->trans('Save') ?>" class="button">  
    - - - -'; } @@ -606,36 +570,56 @@ if (! empty($id) || ! empty($ref)) { print '
    '; if ($productCombinations) { - print ''.$langs->trans('Copy').''; + print ''.$langs->trans('PropagateVariant').''; } - print ''.$langs->trans('NewProductCombination').''; + print ''.$langs->trans('NewProductCombination').''; // NewVariant - if (empty($conf->dol_optimize_smallscreen) && $conf->use_javascript_ajax) // Bugged page. Too much useless javascript. - { - print ''.$langs->trans('ProductCombinationGenerator').''; - } + // Too much bugged page. + /* + print ''.$langs->trans('ProductCombinationGenerator').''; + */ print '
    '; print ''; - print ''; + + + $arrayofselected=is_array($toselect)?$toselect:array(); + + + // List of variants + print ''; + + + // List of mass actions available + /* + $arrayofmassactions = array( + 'presend'=>$langs->trans("SendByMail"), + 'builddoc'=>$langs->trans("PDFMerge"), + ); + if ($user->rights->product->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + if ($massaction == 'presend' || $massaction == 'createbills') $arrayofmassactions=array(); + $massactionbutton=$form->selectMassAction('', $arrayofmassactions); + */ $aaa=''; if (count($productCombinations)) { - $aaa = ''; - $aaa .= ''; + $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ''; - $aaa .= ''; + $aaa .= ''; $aaa .= ''; } + $massactionbutton = $aaa; $title = $langs->trans("ProductCombinations"); @@ -645,18 +629,19 @@ if (! empty($id) || ! empty($ref)) { ?>
    +
    -
    -
    - + $val) { + $tmp = explode(':',$val); + $result1 = $prodattr->fetch($tmp[0]); + $result2 = $prodattr_val->fetch($tmp[1]); + if ($result1 > 0 && $result2 > 0) + { + print $prodattr->label . ' - '.$prodattr_val->value.'
    '; + // TODO Add delete link + } + } + } + ?>
    +
    - - - - - - - - + + + + + + + + '; + $searchpitco=$form->showCheckAddButtons('checkforselect', 1); + print $searchpitco; + print ''; + ?> id, 2) ?>"> - + '; + if ($productCombinations || $massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected=0; + if (in_array($prodstatic->id, $arrayofselected)) $selected=1; + print ''; + } + print ''; + ?> Date: Fri, 7 Apr 2017 13:56:41 +0200 Subject: [PATCH 327/410] Update code using new css class --- dev/skeletons/skeleton_list.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dev/skeletons/skeleton_list.php b/dev/skeletons/skeleton_list.php index ca66990a9f7..e5e0f925a9c 100644 --- a/dev/skeletons/skeleton_list.php +++ b/dev/skeletons/skeleton_list.php @@ -435,10 +435,8 @@ while ($i < min($num, $limit)) $obj = $db->fetch_object($resql); if ($obj) { - $var = !$var; - // Show here line of result - print ''; + print ''; // LIST_OF_TD_FIELDS_LIST /* if (! empty($arrayfields['t.field1']['checked'])) From 60a54041c20f8ac0cb5c7822a1cc0e4f0a105985 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 14:09:19 +0200 Subject: [PATCH 328/410] NEW Enable bulk actions delete on supplier invoices --- htdocs/comm/propal/list.php | 7 +- htdocs/commande/list.php | 8 +- htdocs/compta/facture/list.php | 33 +-- htdocs/core/class/html.formfile.class.php | 8 +- htdocs/core/lib/functions.lib.php | 2 +- .../class/api_supplier_invoices.class.php | 2 +- .../class/fournisseur.commande.class.php | 27 +- .../fourn/class/fournisseur.facture.class.php | 62 ++-- htdocs/fourn/class/paiementfourn.class.php | 2 +- htdocs/fourn/facture/list.php | 274 ++++++++++++++---- htdocs/main.inc.php | 2 +- htdocs/theme/eldy/style.css.php | 6 + htdocs/theme/md/style.css.php | 6 + 13 files changed, 305 insertions(+), 134 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index d1ccf6547ce..c06ea117d01 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -556,7 +556,8 @@ if ($resql) $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); + print '
    '; print '
    trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?> - - - - trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?>
    '."\n"; @@ -695,7 +696,7 @@ if ($resql) } // Action column print ''; @@ -807,7 +808,7 @@ if ($resql) // Thirdparty if (! empty($arrayfields['s.nom']['checked'])) { - print ''; if (! $i) $totalarray['nbfield']++; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index fa94541cdbf..27033254dba 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -789,7 +789,6 @@ if ($resql) print ''; print ''; print '
    '; - } if ($sall) @@ -841,7 +840,8 @@ if ($resql) $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); + print '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print ''; + print ''; print $companystatic->getNomUrl(1,'customer'); print '
    '."\n"; @@ -992,7 +992,7 @@ if ($resql) } // Action column print ''; @@ -1222,7 +1222,7 @@ if ($resql) // Third party if (! empty($arrayfields['s.nom']['checked'])) { - print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print ''; + print ''; print $companystatic->getNomUrl(1,'customer'); // If module invoices enabled and user with invoice creation permissions diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 03612cbb932..92fcf4fc511 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -738,7 +738,8 @@ if ($resql) $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); + print '
    '; print ''."\n"; @@ -748,14 +749,14 @@ if ($resql) if (! empty($arrayfields['f.facnumber']['checked'])) { print ''; } // Ref customer if (! empty($arrayfields['f.ref_client']['checked'])) { print ''; } // Type @@ -776,8 +777,8 @@ if ($resql) if (! empty($arrayfields['f.date']['checked'])) { print ''; } @@ -785,8 +786,8 @@ if ($resql) if (! empty($arrayfields['f.date_lim_reglement']['checked'])) { print ''; @@ -797,9 +798,9 @@ if ($resql) print ''; } // Town - if (! empty($arrayfields['s.town']['checked'])) print ''; + if (! empty($arrayfields['s.town']['checked'])) print ''; // Zip - if (! empty($arrayfields['s.zip']['checked'])) print ''; + if (! empty($arrayfields['s.zip']['checked'])) print ''; // State if (! empty($arrayfields['state.nom']['checked'])) { @@ -832,21 +833,21 @@ if ($resql) { // Amount print ''; } if (! empty($arrayfields['f.total_vat']['checked'])) { // Amount print ''; } if (! empty($arrayfields['f.total_ttc']['checked'])) { // Amount print ''; } if (! empty($arrayfields['dynamount_payed']['checked'])) @@ -908,7 +909,7 @@ if ($resql) } // Action column print ''; print "\n"; @@ -956,12 +957,10 @@ if ($resql) if ($num > 0) { $i=0; - $var=true; $totalarray=array(); while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); - $var=!$var; $datelimit=$db->jdate($obj->datelimite); $facturestatic->id=$obj->facid; @@ -978,7 +977,7 @@ if ($resql) $totalpay = $paiement + $totalcreditnotes + $totaldeposits; $remaintopay = $obj->total_ttc - $totalpay; - print ''; + print ''; if (! empty($arrayfields['f.facnumber']['checked'])) { print '\n"; $accountstatic = new AccountingAccount($db); diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 4589cdc754f..bf3d61cd6f2 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -594,7 +594,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['d.statut']['checked'])) print_liste_field_titre($arrayfields['d.statut']['label'],$_SERVER["PHP_SELF"],"d.statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $i = 0; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index c06ea117d01..ba01033eee5 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -738,7 +738,7 @@ if ($resql) if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print ''."\n"; $now = dol_now(); @@ -780,7 +780,7 @@ if ($resql) print ''; } // Other picto tool - print ''."\n"; $total=0; diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index ca786c1e3e0..44ff8934831 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -835,7 +835,7 @@ if ($resql) $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index e67441036c4..0f4e8b825b2 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -415,7 +415,7 @@ if (! empty($arrayfields['b.datec']['checked'])) print_liste_field_titr if (! empty($arrayfields['b.tms']['checked'])) print_liste_field_titre($arrayfields['b.tms']['label'],$_SERVER["PHP_SELF"],"b.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['b.clos']['checked'])) print_liste_field_titre($arrayfields['b.clos']['label'],$_SERVER["PHP_SELF"],'b.clos','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 92fcf4fc511..a8cd12c1884 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -951,7 +951,7 @@ if ($resql) if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type,dynamount_payed","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; if ($num > 0) diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 8a58b842ab6..3c651ec7eb3 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -38,10 +38,12 @@ $langs->load('bills'); $langs->load('banks'); $langs->load('companies'); -// Security check $id=GETPOST('id','int'); +$ref=GETPOST('ref', 'alpha'); $action=GETPOST('action','alpha'); $confirm=GETPOST('confirm','alpha'); + +// Security check if ($user->societe_id) $socid=$user->societe_id; // TODO ajouter regle pour restreindre acces paiement //$result = restrictedArea($user, 'facture', $id,''); @@ -163,11 +165,11 @@ if ($action == 'setdatep' && ! empty($_POST['datepday'])) * View */ -llxHeader(); +llxHeader('', $langs->trans("Payment")); $thirdpartystatic=new Societe($db); -$result=$object->fetch($id); +$result=$object->fetch($id, $ref); if ($result <= 0) { dol_print_error($db,'Payement '.$id.' not found in database'); @@ -178,7 +180,7 @@ $form = new Form($db); $head = payment_prepare_head($object); -dol_fiche_head($head, 'payment', $langs->trans("PaymentCustomerInvoice"), 0, 'payment'); +dol_fiche_head($head, 'payment', $langs->trans("PaymentCustomerInvoice"), -1, 'payment'); /* * Confirmation de la suppression du paiement @@ -199,19 +201,18 @@ if ($action == 'valide') } - $linkback = '' . $langs->trans("BackToList") . ''; +dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', ''); + + +print '
    '; +print '
    '; print '
    '; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; - print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; $formother->select_year($year?$year:-1,'year',1, 20, 5); print ''; - if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; - print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; $formother->select_year($year_lim?$year_lim:-1,'year_lim',1, 20, 5); print '
    '.$langs->trans("Late"); print '
    '; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; @@ -1045,7 +1044,7 @@ if ($resql) // Third party if (! empty($arrayfields['s.nom']['checked'])) { - print ''; + print ''; $thirdparty=new Societe($db); $thirdparty->id=$obj->socid; $thirdparty->name=$obj->name; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 647d0cf6a76..73e854248fe 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -871,8 +871,12 @@ class FormFile else $this->infofiles['extensions'][$ext]++; // Preview - $urladvanced = getAdvancedPreviewUrl($modulepart, $relativepath); - if ($urladvanced) $tmpout.= '
  • '.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'
  • '; + if (! empty($conf->use_javascript_ajax) && ! empty($conf->browser->layout != 'phone')) + { + $tmparray = getAdvancedPreviewUrl($modulepart, $relativepath, 1); + if ($tmparray && $tmparray['url']) $tmpout.= '
  • '.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'
  • '; + } + // Download $tmpout.= '
  • login); } - if( $this->invoice->delete($id) < 0) + if( $this->invoice->delete(DolibarrApiAccess::$user) < 0) { throw new RestException(500); } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 1da9854791b..7b732dd05a6 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1724,28 +1724,31 @@ class CommandeFournisseur extends CommonOrder * Delete an order * * @param User $user Object user + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, >0 if OK */ - public function delete($user='') + public function delete(User $user, $notrigger=0) { global $langs,$conf; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $error = 0; - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user); - if ($result < 0) - { - $this->errors[]='ErrorWhenRunningTrigger'; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - return -1; - } - // End call triggers - - $this->db->begin(); + if (empty($notrigger)) + { + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user); + if ($result < 0) + { + $this->errors[]='ErrorWhenRunningTrigger'; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + return -1; + } + // End call triggers + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =". $this->id ; dol_syslog(get_class($this)."::delete", LOG_DEBUG); if (! $this->db->query($sql) ) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 5f435da9daf..42daafe9c2d 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -849,14 +849,15 @@ class FactureFournisseur extends CommonInvoice /** * Delete invoice from database * - * @param int $rowid Id of invoice to delete + * @param User $user User object + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, >0 if OK */ - public function delete($rowid) + public function delete(User $user, $notrigger=0) { - global $user,$langs,$conf; + global $langs,$conf; - if (! $rowid) $rowid=$this->id; + $rowid=$this->id; dol_syslog("FactureFournisseur::delete rowid=".$rowid, LOG_DEBUG); @@ -865,22 +866,37 @@ class FactureFournisseur extends CommonInvoice $error=0; $this->db->begin(); - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';'; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) + if (! $error && ! $notrigger) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid; + // Call trigger + $result=$this->call_trigger('BILL_SUPPLIER_DELETE',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // Fin appel triggers + } + + if (! $error) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';'; dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql2 = $this->db->query($sql); - if (! $resql2) { + $resql = $this->db->query($sql); + if ($resql) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql2 = $this->db->query($sql); + if (! $resql2) { + $error++; + } + } + else { $error++; } } - else { - $error++; - } - + if (! $error) { // Delete linked object @@ -888,18 +904,6 @@ class FactureFournisseur extends CommonInvoice if ($res < 0) $error++; } - if (! $error) - { - // Call trigger - $result=$this->call_trigger('BILL_SUPPLIER_DELETE',$user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - // Fin appel triggers - } - if (! $error) { // Delete linked object @@ -2452,13 +2456,11 @@ class SupplierInvoiceLine extends CommonObjectLine /** * Deletes a line * - * @param bool|int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param bool|int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int 0 if KO, 1 if OK */ public function delete($notrigger = 0) { - global $user; - dol_syslog(get_class($this)."::deleteline rowid=".$this->id, LOG_DEBUG); $error = 0; diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index be87fbc7512..12fccab91d8 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -349,7 +349,7 @@ class PaiementFourn extends Paiement $result=$accline->fetch($bank_line_id); if ($result > 0) // If result = 0, record not found, we don't try to delete { - $result=$accline->delete(); + $result=$accline->delete($user); } if ($result < 0) { diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 52320ec9580..1eb2dfaeb4a 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -48,6 +48,12 @@ $langs->load("companies"); $langs->load('products'); $langs->load('projects'); +$action=GETPOST('action','alpha'); +$massaction=GETPOST('massaction','alpha'); +$show_files=GETPOST('show_files','int'); +$confirm=GETPOST('confirm','alpha'); +$toselect = GETPOST('toselect', 'array'); + $socid = GETPOST('socid','int'); // Security check @@ -110,7 +116,7 @@ if (! $sortfield) $sortfield="f.datef,f.rowid"; // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $contextpage='supplierinvoicelist'; -$diroutputmassaction=$conf->facture->dir_output . '/temp/massgeneration/'.$user->id; +$diroutputmassaction=$conf->fournisseur->facture->dir_output . '/temp/massgeneration/'.$user->id; $object=new FactureFournisseur($db); @@ -171,67 +177,62 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab */ if (GETPOST('cancel')) { $action='list'; $massaction=''; } -if (! GETPOST('confirmmassaction')) { $massaction=''; } +if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_createbills') { $massaction=''; } $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - -if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter") || GETPOST("button_removefilter.x")) // All test must be present to be compatible with all browsers -{ - $search_all=""; - $search_user=''; - $search_sale=''; - $search_product_category=''; - $search_ref=""; - $search_refsupplier=""; - $search_label=""; - $search_project=''; - $search_societe=""; - $search_company=""; - $search_amount_no_tax=""; - $search_amount_all_tax=""; - $search_montant_ht=''; - $search_montant_vat=''; - $search_montant_ttc=''; - $search_status=''; - $search_paymentmode=''; - $search_town=''; - $search_zip=""; - $search_state=""; - $search_type=''; - $search_country=''; - $search_type_thirdparty=''; - $year=""; - $month=""; - $day=""; - $year_lim=""; - $month_lim=""; - $day_lim=""; - $search_array_options=array(); - $filter=''; - $option=''; -} - if (empty($reshook)) { - // Mass actions. Controls on number of lines checked - $maxformassaction=1000; - if (! empty($massaction) && count($toselect) < 1) + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter") || GETPOST("button_removefilter.x")) // All test must be present to be compatible with all browsers { - $error++; - setEventMessages($langs->trans("NoLineChecked"), null, "warnings"); + $search_all=""; + $search_user=''; + $search_sale=''; + $search_product_category=''; + $search_ref=""; + $search_refsupplier=""; + $search_label=""; + $search_project=''; + $search_societe=""; + $search_company=""; + $search_amount_no_tax=""; + $search_amount_all_tax=""; + $search_montant_ht=''; + $search_montant_vat=''; + $search_montant_ttc=''; + $search_status=''; + $search_paymentmode=''; + $search_town=''; + $search_zip=""; + $search_state=""; + $search_type=''; + $search_country=''; + $search_type_thirdparty=''; + $year=""; + $month=""; + $day=""; + $year_lim=""; + $month_lim=""; + $day_lim=""; + $toselect=''; + $search_array_options=array(); + $filter=''; + $option=''; } - if (! $error && count($toselect) > $maxformassaction) - { - setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors'); - $error++; - } - - + + // Mass actions + $objectclass='FactureFournisseur'; + $objectlabel='SupplierInvoices'; + $permtoread = $user->rights->fournisseur->facture->lire; + $permtodelete = $user->rights->fournisseur->facture->supprimer; + $uploaddir = $conf->fournisseur->facture->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } + /* * View @@ -424,7 +425,15 @@ if ($resql) if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); } - $massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); + // List of mass actions available + $arrayofmassactions = array( + //'presend'=>$langs->trans("SendByMail"), + //'builddoc'=>$langs->trans("PDFMerge"), + ); + //if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); + if ($user->rights->fournisseur->facture->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + //if ($massaction == 'presend' || $massaction == 'createbills') $arrayofmassactions=array(); + $massactionbutton=$form->selectMassAction('', $arrayofmassactions); $i = 0; print ''."\n"; @@ -437,7 +446,144 @@ if ($resql) print ''; print ''; - print_barre_liste($langs->trans("BillsSuppliers").($socid?" - $soc->name":""), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); + print_barre_liste($langs->trans("BillsSuppliers").($socid?" - $soc->name":""), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); + + if ($massaction == 'presend') + { + $langs->load("mails"); + + if (! GETPOST('cancel')) + { + $objecttmp=new Commande($db); + $listofselectedid=array(); + $listofselectedthirdparties=array(); + $listofselectedref=array(); + foreach($arrayofselected as $toselectid) + { + $result=$objecttmp->fetch($toselectid); + if ($result > 0) + { + $listofselectedid[$toselectid]=$toselectid; + $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid; + $listofselectedthirdparties[$thirdpartyid]=$thirdpartyid; + $listofselectedref[$thirdpartyid][$toselectid]=$objecttmp->ref; + } + } + } + + print ''; + + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + dol_fiche_head(null, '', ''); + + $topicmail="SendOrderRef"; + $modelmail="order_send"; + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->withform=-1; + $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); + + if($formmail->fromtype === 'user'){ + $formmail->fromid = $user->id; + + } + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1)) // If bit 1 is set + { + $formmail->trackid='ord'.$object->id; + } + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set + { + include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id); + } + $formmail->withfrom=1; + $liste=$langs->trans("AllRecipientSelected"); + if (count($listofselectedthirdparties) == 1) + { + $liste=array(); + $thirdpartyid=array_shift($listofselectedthirdparties); + $soc=new Societe($db); + $soc->fetch($thirdpartyid); + foreach ($soc->thirdparty_and_contact_email_array(1) as $key=>$value) + { + $liste[$key]=$value; + } + $formmail->withtoreadonly=0; + } + else + { + $formmail->withtoreadonly=1; + } + $formmail->withto=$liste; + $formmail->withtofree=0; + $formmail->withtocc=1; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$langs->transnoentities($topicmail, '__REF__', '__REFCLIENT__'); + $formmail->withfile=$langs->trans("OnlyPDFattachmentSupported"); + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__REF__']='__REF__'; // We want to keep the tag + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__REFCLIENT__']='__REFCLIENT__'; // We want to keep the tag + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['models_id']=GETPOST('modelmailselected','int'); + $formmail->param['id']=join(',',$arrayofselected); + //$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + print $formmail->get_form(); + + dol_fiche_end(); + } + elseif ($massaction == 'createbills') + { + //var_dump($_REQUEST); + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '; + print $langs->trans('DateInvoice'); + print ''; + print $form->select_date('', '', '', '', '', '', 1, 1); + print '
    '; + print $langs->trans('CreateOneBillByThird'); + print ''; + print $form->selectyesno('createbills_onebythird', '', 1); + print '
    '; + print $langs->trans('ValidateInvoices'); + print ''; + print $form->selectyesno('valdate_invoices', 1, 1); + print '
    '; + + print '
    '; + print '
    '; + print ' '; + print ''; + print '
    '; + print '
    '; + } if ($search_all) { @@ -487,11 +633,11 @@ if ($resql) $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); + print '
    '; print ''."\n"; - // Line for filters print ''; // Ref @@ -646,7 +792,7 @@ if ($resql) } // Action column print ''; @@ -688,7 +834,7 @@ if ($resql) if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $facturestatic=new FactureFournisseur($db); @@ -944,11 +1090,15 @@ if ($resql) } // Action column + // Action column print '' ; + if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected=0; + if (in_array($obj->facid, $arrayofselected)) $selected=1; + print ''; + } + print ''; if (! $i) $totalarray['nbfield']++; print "\n"; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index f44f2f70acf..8fe2125251c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1922,7 +1922,7 @@ if (! function_exists("llxFooter")) } // Wrapper to manage document_preview - if (! empty($conf->use_javascript_ajax)) + if (! empty($conf->use_javascript_ajax) && ! empty($conf->browser->layout != 'phone')) { print "\n\n"; print ''; - - -// Part to create -if ($action == 'create') -{ - print load_fiche_titre($langs->trans("NewMyModule")); - - print ''; - print ''; - print ''; - - dol_fiche_head(); - - print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons(0, 'checkforselect', 0); + $searchpitco=$form->showFilterButtons('checkforselect', 0); print $searchpitco; print '
    '; - $selected=0; - if (in_array($obj->facid, $arrayofselected)) $selected=1; - //print ''; - print '
    '."\n"; - // print ''; - // LIST_OF_TD_LABEL_FIELDS_CREATE - print '
    '.$langs->trans("Label").'
    '."\n"; - - dol_fiche_end(); - - print '
     
    '; - - print ''; -} - - - -// Part to edit record -if (($id || $ref) && $action == 'edit') -{ - print load_fiche_titre($langs->trans("MyModule")); - - print '
    '; - print ''; - print ''; - print ''; - - dol_fiche_head(); - - print ''."\n"; - // print ''; - // LIST_OF_TD_LABEL_FIELDS_EDIT - print '
    '.$langs->trans("Label").'
    '; - - dol_fiche_end(); - - print '
    '; - print '   '; - print '
    '; - - print '
    '; -} - - - -// Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) -{ - $res = $object->fetch_optionals($object->id, $extralabels); - - $head = commande_prepare_head($object); - dol_fiche_head($head, 'order', $langs->trans("CustomerOrder"), 0, 'order'); - - print load_fiche_titre($langs->trans("MyModule")); - - dol_fiche_head(); - - if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteMyOjbect'), $langs->trans('ConfirmDeleteMyObject'), 'confirm_delete', '', 0, 1); - print $formconfirm; - } - - print ''."\n"; - // print ''; - // LIST_OF_TD_LABEL_FIELDS_VIEW - print '
    '.$langs->trans("Label").''.$object->label.'
    '; - - dol_fiche_end(); - - - // Buttons - print '
    '."\n"; - - - // Example 2 : Adding links to objects - // Show links to link elements - //$linktoelem = $form->showLinkToObjectBlock($object, null, array('skeleton')); - //$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - -} - - -// End of page -llxFooter(); -$db->close(); diff --git a/dev/skeletons/skeleton_class.class.php b/dev/skeletons/skeleton_class.class.php deleted file mode 100644 index 01b48c35f75..00000000000 --- a/dev/skeletons/skeleton_class.class.php +++ /dev/null @@ -1,593 +0,0 @@ - - * Copyright (C) 2014-2016 Juanjo Menent - * Copyright (C) 2015 Florian Henry - * Copyright (C) 2015 Raphaël Doursenaud - * Copyright (C) ---Put here your own copyright and developer email--- - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file dev/skeletons/skeleton_class.class.php - * \ingroup mymodule othermodule1 othermodule2 - * \brief This file is an example for a CRUD class file (Create/Read/Update/Delete) - * Put some comments here - */ - -// Put here all includes required by your class file -require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php'; -//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; -//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; - -/** - * Class Skeleton_Class - * - * Put here description of your class - * - * @see CommonObject - */ -class Skeleton_Class extends CommonObject -{ - /** - * @var string Id to identify managed objects - */ - public $element = 'skeleton'; - /** - * @var string Name of table without prefix where object is stored - */ - public $table_element = 'skeleton'; - - /** - * @var Skeleton_ClassLine[] Lines - */ - public $lines = array(); - - /** - * @var mixed Sample property 1 - */ - public $prop1; - /** - * @var mixed Sample property 2 - */ - public $prop2; - //... - - /** - * Constructor - * - * @param DoliDb $db Database handler - */ - public function __construct(DoliDB $db) - { - $this->db = $db; - } - - /** - * Create object into database - * - * @param User $user User that creates - * @param bool $notrigger false=launch triggers after, true=disable triggers - * - * @return int <0 if KO, Id of created object if OK - */ - public function create(User $user, $notrigger = false) - { - dol_syslog(__METHOD__, LOG_DEBUG); - - $error = 0; - - // Clean parameters - if (isset($this->prop1)) { - $this->prop1 = trim($this->prop1); - } - if (isset($this->prop2)) { - $this->prop2 = trim($this->prop2); - } - //... - - // Check parameters - // Put here code to add control on parameters values - - // Insert request - $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; - $sql .= ' field1,'; - $sql .= ' field2'; - //... - $sql .= ') VALUES ('; - $sql .= ' \'' . $this->prop1 . '\','; - $sql .= ' \'' . $this->prop2 . '\''; - //... - $sql .= ')'; - - $this->db->begin(); - - $resql = $this->db->query($sql); - if (!$resql) { - $error ++; - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - } - - if (!$error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); - - if (!$notrigger) { - // Uncomment this and change MYOBJECT to your own tag if you - // want this action to call a trigger. - - //// Call triggers - //$result=$this->call_trigger('MYOBJECT_CREATE',$user); - //if ($result < 0) $error++; - //// End call triggers - } - } - - // Commit or rollback - if ($error) { - $this->db->rollback(); - - return - 1 * $error; - } else { - $this->db->commit(); - - return $this->id; - } - } - - /** - * Load object in memory from the database - * - * @param int $id Id object - * @param string $ref Ref - * - * @return int <0 if KO, 0 if not found, >0 if OK - */ - public function fetch($id, $ref = null) - { - dol_syslog(__METHOD__, LOG_DEBUG); - - $sql = 'SELECT'; - $sql .= ' t.rowid,'; - $sql .= ' t.field1,'; - $sql .= ' t.field2'; - //... - $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t'; - $sql.= ' WHERE 1 = 1'; - if (! empty($conf->multicompany->enabled)) { - $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; - } - if (null !== $ref) { - $sql .= ' AND t.ref = ' . '\'' . $ref . '\''; - } else { - $sql .= ' AND t.rowid = ' . $id; - } - - $resql = $this->db->query($sql); - if ($resql) { - $numrows = $this->db->num_rows($resql); - if ($numrows) { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; - $this->prop1 = $obj->field1; - $this->prop2 = $obj->field2; - //... - } - - // Retrieve all extrafields for invoice - // fetch optionals attributes and labels - /* - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields=new ExtraFields($this->db); - $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); - $this->fetch_optionals($this->id,$extralabels); - */ - - // $this->fetch_lines(); - - $this->db->free($resql); - - if ($numrows) { - return 1; - } else { - return 0; - } - } else { - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - - return - 1; - } - } - - /** - * Load object in memory from the database - * - * @param string $sortorder Sort Order - * @param string $sortfield Sort field - * @param int $limit offset limit - * @param int $offset offset limit - * @param array $filter filter array - * @param string $filtermode filter mode (AND or OR) - * - * @return int <0 if KO, >0 if OK - */ - public function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND') - { - dol_syslog(__METHOD__, LOG_DEBUG); - - $sql = 'SELECT'; - $sql .= ' t.rowid,'; - $sql .= ' t.field1,'; - $sql .= ' t.field2'; - //... - $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t'; - - // Manage filter - $sqlwhere = array(); - if (count($filter) > 0) { - foreach ($filter as $key => $value) { - $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\''; - } - } - $sql.= ' WHERE 1 = 1'; - if (! empty($conf->multicompany->enabled)) { - $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; - } - if (count($sqlwhere) > 0) { - $sql .= ' AND ' . implode(' '.$filtermode.' ', $sqlwhere); - } - if (!empty($sortfield)) { - $sql .= $this->db->order($sortfield,$sortorder); - } - if (!empty($limit)) { - $sql .= ' ' . $this->db->plimit($limit, $offset); - } - - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - - while ($obj = $this->db->fetch_object($resql)) { - $line = new self($this->db); - - $line->id = $obj->rowid; - $line->prop1 = $obj->field1; - $line->prop2 = $obj->field2; - //... - } - $this->db->free($resql); - - return $num; - } else { - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - - return - 1; - } - } - - /** - * Update object into database - * - * @param User $user User that modifies - * @param bool $notrigger false=launch triggers after, true=disable triggers - * - * @return int <0 if KO, >0 if OK - */ - public function update(User $user, $notrigger = false) - { - $error = 0; - - dol_syslog(__METHOD__, LOG_DEBUG); - - // Clean parameters - if (isset($this->prop1)) { - $this->prop1 = trim($this->prop1); - } - if (isset($this->prop2)) { - $this->prop2 = trim($this->prop2); - } - //... - - // Check parameters - // Put here code to add a control on parameters values - - // Update request - $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; - $sql .= " field1=".(isset($this->field1)?"'".$this->db->escape($this->field1)."'":"null").","; - $sql .= " field2=".(isset($this->field2)?"'".$this->db->escape($this->field2)."'":"null").""; - //... - $sql .= ' WHERE rowid=' . $this->id; - - $this->db->begin(); - - $resql = $this->db->query($sql); - if (!$resql) { - $error ++; - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - } - - if (!$error && !$notrigger) { - // Uncomment this and change MYOBJECT to your own tag if you - // want this action calls a trigger. - - //// Call triggers - //$result=$this->call_trigger('MYOBJECT_MODIFY',$user); - //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} - //// End call triggers - } - - // Commit or rollback - if ($error) { - $this->db->rollback(); - - return - 1 * $error; - } else { - $this->db->commit(); - - return 1; - } - } - - /** - * Delete object in database - * - * @param User $user User that deletes - * @param bool $notrigger false=launch triggers after, true=disable triggers - * - * @return int <0 if KO, >0 if OK - */ - public function delete(User $user, $notrigger = false) - { - dol_syslog(__METHOD__, LOG_DEBUG); - - $error = 0; - - $this->db->begin(); - - if (!$error) { - if (!$notrigger) { - // Uncomment this and change MYOBJECT to your own tag if you - // want this action calls a trigger. - - //// Call triggers - //$result=$this->call_trigger('MYOBJECT_DELETE',$user); - //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} - //// End call triggers - } - } - - // If you need to delete child tables to, you can insert them here - - if (!$error) { - $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element; - $sql .= ' WHERE rowid=' . $this->id; - - $resql = $this->db->query($sql); - if (!$resql) { - $error ++; - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - } - } - - // Commit or rollback - if ($error) { - $this->db->rollback(); - - return - 1 * $error; - } else { - $this->db->commit(); - - return 1; - } - } - - /** - * Load an object from its id and create a new one in database - * - * @param int $fromid Id of object to clone - * - * @return int New id of clone - */ - public function createFromClone($fromid) - { - dol_syslog(__METHOD__, LOG_DEBUG); - - global $user; - $error = 0; - $object = new Skeleton_Class($this->db); - - $this->db->begin(); - - // Load source object - $object->fetch($fromid); - // Reset object - $object->id = 0; - - // Clear fields - // ... - - // Create clone - $result = $object->create($user); - - // Other options - if ($result < 0) { - $error ++; - $this->errors = $object->errors; - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - } - - // End - if (!$error) { - $this->db->commit(); - - return $object->id; - } else { - $this->db->rollback(); - - return - 1; - } - } - - /** - * Return a link to the object card (with optionaly the picto) - * - * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) - * @param string $option On what the link point to - * @param int $notooltip 1=Disable tooltip - * @param int $maxlen Max length of visible user name - * @param string $morecss Add more css on link - * @return string String with URL - */ - function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') - { - global $db, $conf, $langs; - global $dolibarr_main_authentication, $dolibarr_main_demo; - global $menumanager; - - if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips - - $result = ''; - $companylink = ''; - - $label = '' . $langs->trans("MyModule") . ''; - $label.= '
    '; - $label.= '' . $langs->trans('Ref') . ': ' . $this->ref; - - $url = DOL_URL_ROOT.'/mymodule/'.$this->table_name.'_card.php?id='.$this->id; - - $linkclose=''; - if (empty($notooltip)) - { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label=$langs->trans("ShowProject"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; - } - else $linkclose = ($morecss?' class="'.$morecss.'"':''); - - $linkstart = ''; - $linkend=''; - - if ($withpicto) - { - $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); - if ($withpicto != 2) $result.=' '; - } - $result.= $linkstart . $this->ref . $linkend; - return $result; - } - - /** - * Retourne le libelle du status d'un user (actif, inactif) - * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status - */ - function getLibStatut($mode=0) - { - return $this->LibStatut($this->status,$mode); - } - - /** - * Return the status - * - * @param int $status Id status - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 5=Long label + Picto - * @return string Label of status - */ - static function LibStatut($status,$mode=0) - { - global $langs; - - if ($mode == 0) - { - $prefix=''; - if ($status == 1) return $langs->trans('Enabled'); - if ($status == 0) return $langs->trans('Disabled'); - } - if ($mode == 1) - { - if ($status == 1) return $langs->trans('Enabled'); - if ($status == 0) return $langs->trans('Disabled'); - } - if ($mode == 2) - { - if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); - if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); - } - if ($mode == 3) - { - if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4'); - if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5'); - } - if ($mode == 4) - { - if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); - if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); - } - if ($mode == 5) - { - if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4'); - if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5'); - } - if ($mode == 6) - { - if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4'); - if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5'); - } - } - - - /** - * Initialise object with example values - * Id must be 0 if object instance is a specimen - * - * @return void - */ - public function initAsSpecimen() - { - $this->id = 0; - $this->prop1 = 'prop1'; - $this->prop2 = 'prop2'; - } - -} - -/** - * Class Skeleton_ClassLine - */ -class Skeleton_ClassLine -{ - /** - * @var int ID - */ - public $id; - /** - * @var mixed Sample line property 1 - */ - public $prop1; - /** - * @var mixed Sample line property 2 - */ - public $prop2; -} diff --git a/dev/skeletons/skeleton_list.php b/dev/skeletons/skeleton_list.php deleted file mode 100644 index ca66990a9f7..00000000000 --- a/dev/skeletons/skeleton_list.php +++ /dev/null @@ -1,569 +0,0 @@ - - * Copyright (C) 2014-2016 Juanjo Menent - * Copyright (C) 2016 Jean-François Ferry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file dev/skeletons/skeleton_list.php - * \ingroup mymodule othermodule1 othermodule2 - * \brief This file is an example of a php page - * Put here some comments - */ - -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - -// Change this following line to use the correct relative path (../, ../../, etc) -$res=0; -if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory -if (! $res && file_exists("../../main.inc.php")) $res=@include '../../main.inc.php'; // to work if your module directory is into a subdir of root htdocs directory -if (! $res && file_exists("../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only -if (! $res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only -if (! $res) die("Include of main fails"); -// Change this following line to use the correct relative path from htdocs -require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); -require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -dol_include_once('/mymodule/class/skeleton_class.class.php'); - -// Load traductions files requiredby by page -$langs->load("mymodule"); -$langs->load("other"); - -$action=GETPOST('action','alpha'); -$massaction=GETPOST('massaction','alpha'); -$show_files=GETPOST('show_files','int'); -$confirm=GETPOST('confirm','alpha'); -$toselect = GETPOST('toselect', 'array'); - -$id = GETPOST('id','int'); -$backtopage = GETPOST('backtopage'); -$myparam = GETPOST('myparam','alpha'); - -$search_all=trim(GETPOST("sall")); -$search_field1=GETPOST("search_field1"); -$search_field2=GETPOST("search_field2"); -$search_myfield=GETPOST('search_myfield'); -$optioncss = GETPOST('optioncss','alpha'); - -// Load variable for pagination -$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 = 0; } -$offset = $limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; -if (! $sortfield) $sortfield="t.rowid"; // Set here default search field -if (! $sortorder) $sortorder="ASC"; - -// Protection if external user -$socid=0; -if ($user->societe_id > 0) -{ - $socid = $user->societe_id; - //accessforbidden(); -} - -// Initialize technical object to manage context to save list fields -$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'mymodulelist'; - -// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array -$hookmanager->initHooks(array('mymodulelist')); -$extrafields = new ExtraFields($db); - -// fetch optionals attributes and labels -$extralabels = $extrafields->fetch_name_optionals_label('mymodule'); -$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); - -// List of fields to search into when doing a "search in all" -$fieldstosearchall = array( - 't.ref'=>'Ref', - 't.note_public'=>'NotePublic', -); -if (empty($user->socid)) $fieldstosearchall["t.note_private"]="NotePrivate"; - -// Definition of fields for list -$arrayfields=array( - 't.field1'=>array('label'=>$langs->trans("Field1"), 'checked'=>1), - 't.field2'=>array('label'=>$langs->trans("Field2"), 'checked'=>1), - //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), - 't.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), - 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), -); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); - } -} - - -// Load object if id or ref is provided as parameter -$object=new Skeleton_Class($db); -if (($id > 0 || ! empty($ref)) && $action != 'add') -{ - $result=$object->fetch($id,$ref); - if ($result < 0) dol_print_error($db); -} - - - - -/******************************************************************* -* ACTIONS -* -* Put here all code to do according to value of "action" parameter -********************************************************************/ - -if (GETPOST('cancel')) { $action='list'; $massaction=''; } -if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; } - -$parameters=array(); -$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - -if (empty($reshook)) -{ - // Selection of new fields - include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - - // Purge search criteria - if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") ||GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers - { - $search_field1=''; - $search_field2=''; - $search_date_creation=''; - $search_date_update=''; - $toselect=''; - $search_array_options=array(); - } - - // Mass actions - $objectclass='Skeleton'; - $objectlabel='Skeleton'; - $permtoread = $user->rights->skeleton->read; - $permtodelete = $user->rights->skeleton->delete; - $uploaddir = $conf->skeleton->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; -} - - - -/*************************************************** -* VIEW -* -* Put here all code to build page -****************************************************/ - -$now=dol_now(); - -$form=new Form($db); - -//$help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; -$help_url=''; -$title = $langs->trans('MyModuleListTitle'); - -// Put here content of your page - -// Example : Adding jquery code -print ''; - - -$sql = "SELECT"; -$sql.= " t.rowid,"; -$sql.= " t.field1,"; -$sql.= " t.field2"; -// Add fields from extrafields -foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); -// Add fields from hooks -$parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook -$sql.=$hookmanager->resPrint; -$sql.= " FROM ".MAIN_DB_PREFIX."mytable as t"; -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."mytable_extrafields as ef on (t.rowid = ef.fk_object)"; -$sql.= " WHERE 1 = 1"; -//$sql.= " WHERE u.entity IN (".getEntity('mytable',1).")"; -if ($search_field1) $sql.= natural_search("field1",$search_field1); -if ($search_field2) $sql.= natural_search("field2",$search_field2); -if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); -// Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode=0; - if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric - if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); - } -} -// Add where from hooks -$parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook -$sql.=$hookmanager->resPrint; -$sql.=$db->order($sortfield,$sortorder); -//$sql.= $db->plimit($conf->liste_limit+1, $offset); - -// Count total nb of records -$nbtotalofrecords = ''; -if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) -{ - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); -} - -$sql.= $db->plimit($limit+1, $offset); - -dol_syslog($script_file, LOG_DEBUG); -$resql=$db->query($sql); -if (! $resql) -{ - dol_print_error($db); - exit; -} - -$num = $db->num_rows($resql); - -// Direct jump if only one record found -if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) -{ - $obj = $db->fetch_object($resql); - $id = $obj->rowid; - header("Location: ".DOL_URL_ROOT.'/skeleton/card.php?id='.$id); - exit; -} - -llxHeader('', $title, $help_url); - -$arrayofselected=is_array($toselect)?$toselect:array(); - -$param=''; -if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; -if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; -if ($search_field1 != '') $param.= '&search_field1='.urlencode($search_field1); -if ($search_field2 != '') $param.= '&search_field2='.urlencode($search_field2); -if ($optioncss != '') $param.='&optioncss='.$optioncss; -// Add $param from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); -} - -$arrayofmassactions = array( - 'presend'=>$langs->trans("SendByMail"), - 'builddoc'=>$langs->trans("PDFMerge"), -); -if ($user->rights->mymodule->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); -if ($massaction == 'presend') $arrayofmassactions=array(); -$massactionbutton=$form->selectMassAction('', $arrayofmassactions); - -print '
    '; -if ($optioncss != '') print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; - -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); - -if ($sall) -{ - foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); - print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall); -} - -$moreforfilter = ''; -$moreforfilter.='
    '; -$moreforfilter.= $langs->trans('MyFilter') . ': '; -$moreforfilter.= '
    '; - -$parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook -if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; -else $moreforfilter = $hookmanager->resPrint; - -if (! empty($moreforfilter)) -{ - print '
    '; - print $moreforfilter; - print '
    '; -} - -$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; -$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - -print '
    '; -print ''."\n"; - -// Fields title -print ''; -// LIST_OF_TD_TITLE_FIELDS -//if (! empty($arrayfields['t.field1']['checked'])) print_liste_field_titre($arrayfields['t.field1']['label'],$_SERVER['PHP_SELF'],'t.field1','',$param,'',$sortfield,$sortorder); -//if (! empty($arrayfields['t.field2']['checked'])) print_liste_field_titre($arrayfields['t.field2']['label'],$_SERVER['PHP_SELF'],'t.field2','',$param,'',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -//if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print ''."\n"; - -// Fields title search -print ''; -// LIST_OF_TD_TITLE_SEARCH -//if (! empty($arrayfields['t.field1']['checked'])) print ''; -//if (! empty($arrayfields['t.field2']['checked'])) print ''; -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } -} -// Fields from hook -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['t.datec']['checked'])) -{ - // Date creation - print ''; -} -if (! empty($arrayfields['t.tms']['checked'])) -{ - // Date modification - print ''; -} -/*if (! empty($arrayfields['u.statut']['checked'])) -{ - // Status - print ''; -}*/ -// Action column -print ''; -print ''."\n"; - - -$i=0; -$var=true; -$totalarray=array(); -while ($i < min($num, $limit)) -{ - $obj = $db->fetch_object($resql); - if ($obj) - { - $var = !$var; - - // Show here line of result - print ''; - // LIST_OF_TD_FIELDS_LIST - /* - if (! empty($arrayfields['t.field1']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - } - if (! empty($arrayfields['t.field2']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - }*/ - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } - // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); - $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Date creation - if (! empty($arrayfields['t.datec']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - } - // Date modification - if (! empty($arrayfields['t.tms']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - } - // Status - /* - if (! empty($arrayfields['u.statut']['checked'])) - { - $userstatic->statut=$obj->statut; - print ''; - }*/ - - // Action column - print ''; - if (! $i) $totalarray['nbfield']++; - - print ''; - } - $i++; -} - -// Show total line -if (isset($totalarray['totalhtfield'])) -{ - print ''; - $i=0; - while ($i < $totalarray['nbfield']) - { - $i++; - if ($i == 1) - { - if ($num < $limit) print ''; - else print ''; - } - elseif ($totalarray['totalhtfield'] == $i) print ''; - elseif ($totalarray['totalvatfield'] == $i) print ''; - elseif ($totalarray['totalttcfield'] == $i) print ''; - else print ''; - } - print ''; -} - -$db->free($resql); - -$parameters=array('arrayfields'=>$arrayfields, 'sql'=>$sql); -$reshook=$hookmanager->executeHooks('printFieldListFooter',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; - -print '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print ''; - print ''; - print ''; - print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); - print ''; -$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); -print $searchpitco; -print '
    '.$obj->field1.''.$obj->field2.''; - print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); - print ''; - print dol_print_date($db->jdate($obj->date_update), 'dayhour'); - print ''.$userstatic->getLibStatut(3).''; - if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - { - $selected=0; - if (in_array($obj->rowid, $arrayofselected)) $selected=1; - print ''; - } - print '
    '.$langs->trans("Total").''.$langs->trans("Totalforthispage").''.price($totalarray['totalht']).''.price($totalarray['totalvat']).''.price($totalarray['totalttc']).'
    '."\n"; -print '
    '."\n"; - -print '
    '."\n"; - - -if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) -{ - // Show list of available documents - $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; - $urlsource.=str_replace('&','&',$param); - - $filedir=$diroutputmassaction; - $genallowed=$user->rights->facture->lire; - $delallowed=$user->rights->facture->lire; - - print $formfile->showdocuments('massfilesarea_mymodule','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,''); -} -else -{ - print '
    '.$langs->trans("ShowTempMassFilesArea").''; -} - - -// End of page -llxFooter(); -$db->close(); diff --git a/dev/skeletons/skeleton_script.php b/dev/skeletons/skeleton_script.php deleted file mode 100644 index 5eb1565d4a3..00000000000 --- a/dev/skeletons/skeleton_script.php +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env php - - * Copyright (C) ---Put here your own copyright and developer email--- - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file dev/skeletons/skeleton_script.php - * \ingroup mymodule - * \brief This file is an example for a command line script - * Put here some comments - */ - -$sapi_type = php_sapi_name(); -$script_file = basename(__FILE__); -$path=dirname(__FILE__).'/'; - -// Test if batch mode -if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; - exit(-1); -} - -// Global variables -$version='1.0'; -$error=0; - - -// -------------------- START OF YOUR CODE HERE -------------------- -@set_time_limit(0); // No timeout for this script -define('EVEN_IF_ONLY_LOGIN_ALLOWED',1); // Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only". - -// Include and load Dolibarr environment variables -require_once($path."../../htdocs/master.inc.php"); -// After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file). -// $user is created but empty. - -//$langs->setDefaultLang('en_US'); // To change default language of $langs -$langs->load("main"); // To load language file for default language - -// Load user and its permissions -$result=$user->fetch('','admin'); // Load user for login 'admin'. Comment line to run as anonymous user. -if (! $result > 0) { dol_print_error('',$user->error); exit; } -$user->getrights(); - - -print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; -if (! isset($argv[1])) { // Check parameters - print "Usage: ".$script_file." param1 param2 ...\n"; - exit(-1); -} -print '--- start'."\n"; -print 'Argument 1='.$argv[1]."\n"; -print 'Argument 2='.$argv[2]."\n"; - - -// Start of transaction -$db->begin(); - - -// Examples for manipulating class skeleton_class -require_once(DOL_DOCUMENT_ROOT."/../dev/skeletons/skeleton_class.class.php"); -$myobject=new Skeleton_Class($db); - -// Example for inserting creating object in database -/* -dol_syslog($script_file." CREATE", LOG_DEBUG); -$myobject->prop1='value_prop1'; -$myobject->prop2='value_prop2'; -$id=$myobject->create($user); -if ($id < 0) { $error++; dol_print_error($db,$myobject->error); } -else print "Object created with id=".$id."\n"; -*/ - -// Example for reading object from database -/* -dol_syslog($script_file." FETCH", LOG_DEBUG); -$result=$myobject->fetch($id); -if ($result < 0) { $error; dol_print_error($db,$myobject->error); } -else print "Object with id=".$id." loaded\n"; -*/ - -// Example for updating object in database ($myobject must have been loaded by a fetch before) -/* -dol_syslog($script_file." UPDATE", LOG_DEBUG); -$myobject->prop1='newvalue_prop1'; -$myobject->prop2='newvalue_prop2'; -$result=$myobject->update($user); -if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } -else print "Object with id ".$myobject->id." updated\n"; -*/ - -// Example for deleting object in database ($myobject must have been loaded by a fetch before) -/* -dol_syslog($script_file." DELETE", LOG_DEBUG); -$result=$myobject->delete($user); -if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } -else print "Object with id ".$myobject->id." deleted\n"; -*/ - - -// An example of a direct SQL read without using the fetch method -/* -$sql = "SELECT field1, field2"; -$sql.= " FROM ".MAIN_DB_PREFIX."skeleton"; -$sql.= " WHERE field3 = 'xxx'"; -$sql.= " ORDER BY field1 ASC"; - -dol_syslog($script_file, LOG_DEBUG); -$resql=$db->query($sql); -if ($resql) -{ - $num = $db->num_rows($resql); - $i = 0; - if ($num) - { - while ($i < $num) - { - $obj = $db->fetch_object($resql); - if ($obj) - { - // You can use here results - print $obj->field1; - print $obj->field2; - } - $i++; - } - } -} -else -{ - $error++; - dol_print_error($db); -} -*/ - - -// -------------------- END OF YOUR CODE -------------------- - -if (! $error) -{ - $db->commit(); - print '--- end ok'."\n"; -} -else -{ - print '--- end error code='.$error."\n"; - $db->rollback(); -} - -$db->close(); // Close $db database opened handler - -exit($error); diff --git a/dev/skeletons/skeleton_webservice_server.php b/dev/skeletons/skeleton_webservice_server.php deleted file mode 100644 index 54a050ff9da..00000000000 --- a/dev/skeletons/skeleton_webservice_server.php +++ /dev/null @@ -1,272 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/webservices/server_skeleton.php - * \brief File that is entry point to call Dolibarr WebServices - * \version $Id: server_skeleton.php,v 1.7 2010/12/19 11:49:37 eldy Exp $ - */ - -// This is to make Dolibarr working with Plesk -set_include_path($_SERVER['DOCUMENT_ROOT'].'/htdocs'); - -require_once("../master.inc.php"); -require_once(NUSOAP_PATH.'/nusoap.php'); // Include SOAP -require_once(DOL_DOCUMENT_ROOT."/core/lib/ws.lib.php"); -require_once(DOL_DOCUMENT_ROOT."/skeleton/class/skeleton.class.php"); - - -dol_syslog("Call Skeleton webservices interfaces"); - -// Enable and test if module web services is enabled -if (empty($conf->global->MAIN_MODULE_WEBSERVICES)) -{ - $langs->load("admin"); - dol_syslog("Call Dolibarr webservices interfaces with module webservices disabled"); - print $langs->trans("WarningModuleNotActive",'WebServices').'.

    '; - print $langs->trans("ToActivateModule"); - exit; -} - -// Create the soap Object -$server = new nusoap_server(); -$server->soap_defencoding='UTF-8'; -$server->decode_utf8=false; -$ns='http://www.dolibarr.org/ns/'; -$server->configureWSDL('WebServicesDolibarrSkeleton',$ns); -$server->wsdl->schemaTargetNamespace=$ns; - - -// Define WSDL Authentication object -$server->wsdl->addComplexType( - 'authentication', - 'complexType', - 'struct', - 'all', - '', - array( - 'dolibarrkey' => array('name'=>'dolibarrkey','type'=>'xsd:string'), - 'sourceapplication' => array('name'=>'sourceapplication','type'=>'xsd:string'), - 'login' => array('name'=>'login','type'=>'xsd:string'), - 'password' => array('name'=>'password','type'=>'xsd:string'), - 'entity' => array('name'=>'entity','type'=>'xsd:string'), - ) -); - -// Define WSDL Return object -$server->wsdl->addComplexType( - 'result', - 'complexType', - 'struct', - 'all', - '', - array( - 'result_code' => array('name'=>'result_code','type'=>'xsd:string'), - 'result_label' => array('name'=>'result_label','type'=>'xsd:string'), - ) -); - -// Define other specific objects -$server->wsdl->addComplexType( - 'skeleton', - 'complexType', - 'struct', - 'all', - '', - array( - 'prop1'=>'xxx', - 'prop2'=>'xxx', - //... - ) -); - - - -// 5 styles: RPC/encoded, RPC/literal, Document/encoded (not WS-I compliant), Document/literal, Document/literal wrapped -// Style merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model. -// http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/ -$styledoc='rpc'; // rpc/document (document is an extend into SOAP 1.0 to support unstructured messages) -$styleuse='encoded'; // encoded/literal/literal wrapped -// Better choice is document/literal wrapped but literal wrapped not supported by nusoap. - - -// Register WSDL -$server->register( - 'getSkeleton', - // Entry values - array('authentication'=>'tns:authentication','id'=>'xsd:string','ref'=>'xsd:string','ref_ext'=>'xsd:string'), - // Exit values - array('result'=>'tns:result','skeleton'=>'tns:skeleton'), - $ns, - $ns.'#getSkeleton', - $styledoc, - $styleuse, - 'WS to get skeleton' -); - -// Register WSDL -$server->register( - 'createSkeleton', - // Entry values - array('authentication'=>'tns:authentication','skeleton'=>'tns:skeleton'), - // Exit values - array('result'=>'tns:result','id'=>'xsd:string'), - $ns, - $ns.'#createSkeleton', - $styledoc, - $styleuse, - 'WS to create a skeleton' -); - - - - -/** - * Get Skeleton - * - * @param array $authentication Array of authentication information - * @param int $id Id of object - * @param string $ref Ref of object - * @param string $ref_ext Ref external of object - * @return mixed - */ -function getSkeleton($authentication,$id,$ref='',$ref_ext='') -{ - global $db,$conf,$langs; - - dol_syslog("Function: getSkeleton login=".$authentication['login']." id=".$id." ref=".$ref." ref_ext=".$ref_ext); - - if ($authentication['entity']) $conf->entity=$authentication['entity']; - - // Init and check authentication - $objectresp=array(); - $errorcode='';$errorlabel=''; - $error=0; - $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); - // Check parameters - if (! $error && (($id && $ref) || ($id && $ref_ext) || ($ref && $ref_ext))) - { - $error++; - $errorcode='BAD_PARAMETERS'; $errorlabel="Parameter id, ref and ref_ext can't be both provided. You must choose one or other but not both."; - } - - if (! $error) - { - $fuser->getrights(); - - if ($fuser->rights->skeleton->read) - { - $skeleton=new Skeleton($db); - $result=$skeleton->fetch($id,$ref,$ref_ext); - if ($result > 0) - { - // Create - $objectresp = array( - 'result'=>array('result_code'=>'OK', 'result_label'=>''), - 'skeleton'=>array( - 'prop1'=>$skeleton->prop1, - 'prop2'=>$skeleton->prop2, - //... - ) - ); - } - else - { - $error++; - $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext; - } - } - else - { - $error++; - $errorcode='PERMISSION_DENIED'; $errorlabel='User does not have permission for this request'; - } - } - - if ($error) - { - $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); - } - - return $objectresp; -} - - -/** - * Create Skeleton - * - * @param array $authentication Array of authentication information - * @param Skeleton $skeleton $skeleton - * @return array Array result - */ -function createSkeleton($authentication,$skeleton) -{ - global $db,$conf,$langs; - - $now=dol_now(); - - dol_syslog("Function: createSkeleton login=".$authentication['login']); - - if ($authentication['entity']) $conf->entity=$authentication['entity']; - - // Init and check authentication - $objectresp=array(); - $errorcode='';$errorlabel=''; - $error=0; - $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); - // Check parameters - - - if (! $error) - { - $newobject=new Skeleton($db); - $newobject->prop1=$skeleton->prop1; - $newobject->prop2=$skeleton->prop2; - //... - - $db->begin(); - - $result=$newobject->create($fuser); - if ($result <= 0) - { - $error++; - } - - if (! $error) - { - $db->commit(); - $objectresp=array('result'=>array('result_code'=>'OK', 'result_label'=>''),'id'=>$newobject->id,'ref'=>$newobject->ref); - } - else - { - $db->rollback(); - $error++; - $errorcode='KO'; - $errorlabel=$newobject->error; - } - } - - if ($error) - { - $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); - } - - return $objectresp; -} - -// Return the results. -$server->service(file_get_contents("php://input")); diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index b10463361f8..7f909cd2f13 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -263,7 +263,7 @@ if ($resql) if (! empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'],$_SERVER["PHP_SELF"],'aa.pcg_type','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'],$_SERVER["PHP_SELF"],'aa.pcg_subtype','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'],$_SERVER["PHP_SELF"],'aa.active','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "
  • '; + print ''; $filename=dol_sanitizeFileName($obj->ref); $filedir=$conf->propal->dir_output . '/' . dol_sanitizeFileName($obj->ref); $urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 27033254dba..fcd68992b38 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1033,7 +1033,7 @@ if ($resql) if (! empty($arrayfields['c.tms']['checked'])) print_liste_field_titre($arrayfields['c.tms']['label'],$_SERVER["PHP_SELF"],"c.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['c.fk_statut']['checked'])) print_liste_field_titre($arrayfields['c.fk_statut']['label'],$_SERVER["PHP_SELF"],"c.fk_statut","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['c.facture']['checked'])) print_liste_field_titre($arrayfields['c.facture']['label'],$_SERVER["PHP_SELF"],'c.facture','',$param,'align="center"',$sortfield,$sortorder,''); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print '
    '."\n"; -// Ref -print ''; - // Date payment -print ''; @@ -280,6 +281,8 @@ if (! empty($conf->banque->enabled)) print '
    '.$langs->trans('Ref').''; -print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); -print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$user->rights->facture->paiement).''; +print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$user->rights->facture->paiement).''; print $form->editfieldval("Date",'datep',$object->date,$object,$user->rights->facture->paiement,'datepicker','',null,$langs->trans('PaymentDateUpdateSucceeded')); print '
    '; +print '
    '; + dol_fiche_end(); diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 61d2b5a3b8a..b229f756b25 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -96,7 +96,7 @@ class Paiement extends CommonObject if ($id > 0) $sql.= ' AND p.rowid = '.$id; else if ($ref) - $sql.= ' AND p.rowid = '.$ref; + $sql.= " AND p.ref = '".$ref."'"; else if ($fk_bank) $sql.= ' AND p.fk_bank = '.$fk_bank; diff --git a/htdocs/compta/paiement/info.php b/htdocs/compta/paiement/info.php index e1b12225aad..d0bda152b21 100644 --- a/htdocs/compta/paiement/info.php +++ b/htdocs/compta/paiement/info.php @@ -32,33 +32,39 @@ $langs->load("bills"); $langs->load("companies"); $id=GETPOST('id'); +$ref=GETPOST('ref', 'alpha'); +$action=GETPOST('action','alpha'); +$confirm=GETPOST('confirm','alpha'); + +/* + * Actions + */ + +// None /* * View */ -llxHeader(); +llxHeader('', $langs->trans("Payment")); $object = new Paiement($db); -$object->fetch($id); -$object->info($id); +$object->fetch($id, $ref); +$object->info($object->id); $head = payment_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("PaymentCustomerInvoice"), 0, 'payment'); +dol_fiche_head($head, 'info', $langs->trans("PaymentCustomerInvoice"), -1, 'payment'); -print ''; $linkback = '' . $langs->trans("BackToList") . ''; +dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', ''); -// Ref -print ''; -print '
    '.$langs->trans('Ref').''; -print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); -print '
    '; +print '
    '; +print '
    '; print '
    '; @@ -68,5 +74,7 @@ print '
    '; print '
    '; +dol_fiche_end(); + llxFooter(); $db->close(); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 917c59006f2..ef26c9c80e2 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -642,7 +642,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"p.statut","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index af68e789da2..be1b2e5fccf 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -551,7 +551,7 @@ if ($resql) print_liste_field_titre($staticcontratligne->LibStatut(4,3,1), '', '', '', '', 'width="16"'); print_liste_field_titre($staticcontratligne->LibStatut(5,3), '', '', '', '', 'width="16"'); } - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; while ($i < min($num,$limit)) diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index 62b9fddf743..1e2820f10e0 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -382,7 +382,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['cd.datec']['checked'])) print_liste_field_titre($arrayfields['cd.datec']['label'],$_SERVER["PHP_SELF"],"cd.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['cd.tms']['checked'])) print_liste_field_titre($arrayfields['cd.tms']['label'],$_SERVER["PHP_SELF"],"cd.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['status']['checked'])) print_liste_field_titre($arrayfields['status']['label'],$_SERVER["PHP_SELF"],"cd.statut,c.statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; print ''; diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php index fe460f7d512..be9a868109d 100644 --- a/htdocs/core/boxes/box_commandes.php +++ b/htdocs/core/boxes/box_commandes.php @@ -121,7 +121,7 @@ class box_commandes extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => '', + 'td' => 'class="tdoverflowmax100"', 'text' => $societestatic->getNomUrl(1), 'asis' => 1, ); diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index d3945ddb940..3f7b37f186a 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -116,8 +116,8 @@ class box_propales extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => '', - 'text' => $societestatic->getNomUrl(1,'',40), + 'td' => 'class="tdoverflowmax100"', + 'text' => $societestatic->getNomUrl(1), 'asis' => 1, ); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 73e854248fe..7dc69a82b23 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -834,8 +834,8 @@ class FormFile $out=''; $this->infofiles=array('nboffiles'=>0,'extensions'=>array(),'files'=>array()); - if (! empty($conf->dol_use_jmobile)) return ''; - + //if (! empty($conf->dol_use_jmobile)) return ''; + $file_list=dol_dir_list($filedir, 'files', 0, preg_quote(basename($modulesubdir),'/').'[^\-]+', '\.meta$|\.png$'); // Get list of files starting with name of ref (but not followed by "-" to discard uploaded files) // For ajax treatment diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index ed6bb2c9979..178a3629d23 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -57,7 +57,10 @@ $nolinesbefore=(count($this->lines) == 0 || $forcetoshowtitlelines); if ($nolinesbefore) { ?> - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>> + global->MAIN_VIEW_LINE_NUMBER)) { ?> + + +
    trans('AddNewLine'); ?>trans("FreeZone"); ?> element == 'supplier_proposal') { ?> @@ -114,12 +117,17 @@ if ($nolinesbefore) { global->MAIN_VIEW_LINE_NUMBER)) { - $coldisplay=2; } + $coldisplay=2; + ?> + + - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>> + global->MAIN_VIEW_LINE_NUMBER)) { ?> -
    +
    info_bits & 2) == 2) { ?> diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 29f6978b24e..853c047b23c 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -458,7 +458,7 @@ if ($resql) if (! empty($arrayfields['e.tms']['checked'])) print_liste_field_titre($arrayfields['e.tms']['label'],$_SERVER["PHP_SELF"],"e.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['e.fk_statut']['checked'])) print_liste_field_titre($arrayfields['e.fk_statut']['label'],$_SERVER["PHP_SELF"],"e.fk_statut","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['l.fk_statut']['checked'])) print_liste_field_titre($arrayfields['l.fk_statut']['label'], $_SERVER["PHP_SELF"],"l.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $i=0; diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 9339b33ee7f..c04a2fc3b61 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -342,43 +342,13 @@ if ($resql) $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); + print '
    '; print ''."\n"; - print ""; - if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],"d.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['user']['checked'])) print_liste_field_titre($arrayfields['user']['label'],$_SERVER["PHP_SELF"],"u.lastname","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_debut']['checked'])) print_liste_field_titre($arrayfields['d.date_debut']['label'],$_SERVER["PHP_SELF"],"d.date_debut","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_fin']['checked'])) print_liste_field_titre($arrayfields['d.date_fin']['label'],$_SERVER["PHP_SELF"],"d.date_fin","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_valid']['checked'])) print_liste_field_titre($arrayfields['d.date_valid']['label'],$_SERVER["PHP_SELF"],"d.date_valid","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_approve']['checked'])) print_liste_field_titre($arrayfields['d.date_approve']['label'],$_SERVER["PHP_SELF"],"d.date_approve","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.total_ht']['checked'])) print_liste_field_titre($arrayfields['d.total_ht']['label'],$_SERVER["PHP_SELF"],"d.total_ht","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['d.total_vat']['checked'])) print_liste_field_titre($arrayfields['d.total_vat']['label'],$_SERVER["PHP_SELF"],"d.total_tva","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['d.total_ttc']['checked'])) print_liste_field_titre($arrayfields['d.total_ttc']['label'],$_SERVER["PHP_SELF"],"d.total_ttc","",$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['d.fk_statut']['checked'])) print_liste_field_titre($arrayfields['d.fk_statut']['label'],$_SERVER["PHP_SELF"],"d.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - + // Filters - print ''; + print ''; if (! empty($arrayfields['d.ref']['checked'])) { print ''; print "\n"; - $var=true; + print ''; + if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],"d.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['user']['checked'])) print_liste_field_titre($arrayfields['user']['label'],$_SERVER["PHP_SELF"],"u.lastname","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_debut']['checked'])) print_liste_field_titre($arrayfields['d.date_debut']['label'],$_SERVER["PHP_SELF"],"d.date_debut","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_fin']['checked'])) print_liste_field_titre($arrayfields['d.date_fin']['label'],$_SERVER["PHP_SELF"],"d.date_fin","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_valid']['checked'])) print_liste_field_titre($arrayfields['d.date_valid']['label'],$_SERVER["PHP_SELF"],"d.date_valid","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_approve']['checked'])) print_liste_field_titre($arrayfields['d.date_approve']['label'],$_SERVER["PHP_SELF"],"d.date_approve","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.total_ht']['checked'])) print_liste_field_titre($arrayfields['d.total_ht']['label'],$_SERVER["PHP_SELF"],"d.total_ht","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['d.total_vat']['checked'])) print_liste_field_titre($arrayfields['d.total_vat']['label'],$_SERVER["PHP_SELF"],"d.total_tva","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['d.total_ttc']['checked'])) print_liste_field_titre($arrayfields['d.total_ttc']['label'],$_SERVER["PHP_SELF"],"d.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['d.fk_statut']['checked'])) print_liste_field_titre($arrayfields['d.fk_statut']['label'],$_SERVER["PHP_SELF"],"d.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; $total_total_ht = 0; $total_total_ttc = 0; @@ -528,7 +528,7 @@ if ($resql) $expensereportstatic->note_public=$obj->note_public; $var=!$var; - print ""; + print ''; // Ref if (! empty($arrayfields['d.ref']['checked'])) { print '\n"; $total = 0; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index be3cb384e96..5c4c8aae11c 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -684,7 +684,7 @@ if ($resql) if (! empty($arrayfields['cf.tms']['checked'])) print_liste_field_titre($arrayfields['cf.tms']['label'],$_SERVER["PHP_SELF"],"cf.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['cf.fk_statut']['checked'])) print_liste_field_titre($arrayfields['cf.fk_statut']['label'],$_SERVER["PHP_SELF"],"cf.fk_statut","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['cf.billed']['checked'])) print_liste_field_titre($arrayfields['cf.billed']['label'],$_SERVER["PHP_SELF"],'cf.billed','',$param,'align="center"',$sortfield,$sortorder,''); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 131dcc3651b..d9c5fdf43c0 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2016 Laurent Destailleur + * Copyright (C) 2013-2017 Laurent Destailleur * Copyright (C) 2012-2016 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -82,7 +82,7 @@ $fieldstosearchall = array( * Actions */ -if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers { $search_ref=""; $month_create=""; @@ -292,21 +292,8 @@ if ($sall) print '
    '; print '
    '; @@ -491,13 +461,43 @@ if ($resql) } // Action column print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 4a24f0d0c6d..88584a4f954 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -367,7 +367,7 @@ if ($result) if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "
    '."\n"; -print ''; -print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"cp.rowid","",'','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("DateCreateCP"),$_SERVER["PHP_SELF"],"cp.date_create","",'','align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"cp.fk_user","",'','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("ValidatorCP"),$_SERVER["PHP_SELF"],"cp.fk_validator","",'','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],'','','','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],'','','','align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("DateDebCP"),$_SERVER["PHP_SELF"],"cp.date_debut","",'','align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("DateFinCP"),$_SERVER["PHP_SELF"],"cp.date_fin","",'','align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cp.statut","",'','align="right"',$sortfield,$sortorder); -print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - // FILTRES -print ''; +print ''; print ''; @@ -391,6 +378,18 @@ print ''; print "\n"; +print ''; +print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"cp.rowid","",'','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("DateCreateCP"),$_SERVER["PHP_SELF"],"cp.date_create","",'','align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"cp.fk_user","",'','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("ValidatorCP"),$_SERVER["PHP_SELF"],"cp.fk_validator","",'','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],'','','','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],'','','','align="right"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("DateDebCP"),$_SERVER["PHP_SELF"],"cp.date_debut","",'','align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("DateFinCP"),$_SERVER["PHP_SELF"],"cp.date_fin","",'','align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cp.statut","",'','align="right"',$sortfield,$sortorder); +print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; // Lines if (! empty($holiday->holiday)) @@ -400,8 +399,6 @@ if (! empty($holiday->holiday)) foreach($holiday->holiday as $infos_CP) { - $var=!$var; - // Utilisateur $userstatic->id=$infos_CP['fk_user']; $userstatic->lastname=$infos_CP['user_lastname']; @@ -420,7 +417,7 @@ if (! empty($holiday->holiday)) $date = $infos_CP['date_create']; - print ''; + print ''; print ''."\n"; // Fields title search diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 2e651398766..7789849da99 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -622,7 +622,7 @@ else if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.tosell']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['p.tobuy']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index 45ace2031cb..bc4099f66ec 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -898,7 +898,7 @@ if ($resql) print $hookmanager->resPrint; if (! empty($arrayfields['m.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['m.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index ac6bc7b9948..b6a51233fa2 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -433,7 +433,7 @@ if ($resql) if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); //if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print ''."\n"; $productlot = new Productlot($db); diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 790dde6e1aa..fb6453e8159 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -614,7 +614,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $i=0; diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 13e15eb7eb6..ca7cff35a0a 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -585,7 +585,7 @@ $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // No print $hookmanager->resPrint; if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 2d93a0ab2df..e1047d22981 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -252,7 +252,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab } } } -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 5c5f6f8e1c8..88e7a7a631e 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -886,7 +886,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['s.datec']['checked'])) print_liste_field_titre($arrayfields['s.datec']['label'],$_SERVER["PHP_SELF"],"s.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['s.tms']['checked'])) print_liste_field_titre($arrayfields['s.tms']['label'],$_SERVER["PHP_SELF"],"s.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['s.status']['checked'])) print_liste_field_titre($arrayfields['s.status']['label'],$_SERVER["PHP_SELF"],"s.status","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index 09dd0eb240c..3624101d7cf 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -568,7 +568,7 @@ if ($result) print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'sp.total_ht','',$param, 'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans('Author'),$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'sp.fk_statut','',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $now = dol_now(); diff --git a/htdocs/theme/eldy/ckeditor/config.js b/htdocs/theme/eldy/ckeditor/config.js index a1bb5fdcf0b..eabd0c58bd3 100644 --- a/htdocs/theme/eldy/ckeditor/config.js +++ b/htdocs/theme/eldy/ckeditor/config.js @@ -31,7 +31,7 @@ CKEDITOR.editorConfig = function( config ) ['Templates','NewPage'], ['Save'], ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], + ['PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], ['CreateDiv','ShowBlocks'], ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], @@ -42,14 +42,14 @@ CKEDITOR.editorConfig = function( config ) ['Link','Unlink','Anchor'], ['Image','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], ['Styles','Format','Font','FontSize'], - ['TextColor','BGColor'], + ['TextColor','BGColor'] ]; // Used for mailing fields config.toolbar_dolibarr_mailings = [ ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], ['Undo','Redo','-','Find','Replace'], ['CreateDiv','ShowBlocks'], ['Format','Font','FontSize'], @@ -63,7 +63,7 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_notes = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace'], ['Format','Font','FontSize'], ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], @@ -76,9 +76,9 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_details = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Format','Font','FontSize'], - ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], + ['Bold','Italic','Underline','Strike','-','TextColor','RemoveFormat'], // ,'Subscript','Superscript' useless ['NumberedList','BulletedList','Outdent','Indent'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Link','Unlink','SpecialChar'] diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 38d50962086..793e17c8f72 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -411,7 +411,6 @@ hr { border: 0; border-top: 1px solid #ccc; } margin-top: 0; text-align: center; cursor: pointer; - color: #333333 !important; text-decoration: none !important; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); background-color: #f5f5f5; @@ -430,9 +429,6 @@ hr { border: 0; border-top: 1px solid #ccc; } -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .button:focus, .buttonDelete:focus { -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1); @@ -775,8 +771,8 @@ div.fiche>form>div.div-table-responsive { .minwidth100imp { min-width: 80px !important; } .minwidth200imp { min-width: 100px !important; } .minwidth300imp { min-width: 100px !important; } - .minwidth400imp { min-width: 100px !important; } - .minwidth500imp { min-width: 100px !important; } + .minwidth400imp { min-width: 150px !important; } + .minwidth500imp { min-width: 250px !important; } } /* Force values for small screen 570 */ @@ -826,9 +822,9 @@ div.fiche>form>div.div-table-responsive { .minwidth75imp { min-width: 60px !important; } .minwidth100imp { min-width: 60px !important; } .minwidth200imp { min-width: 60px !important; } - .minwidth300imp { min-width: 60px !important; } - .minwidth400imp { min-width: 60px !important; } - .minwidth500imp { min-width: 60px !important; } + .minwidth300imp { min-width: 100px !important; } + .minwidth400imp { min-width: 150px !important; } + .minwidth500imp { min-width: 250px !important; } .titlefield { width: auto; } .titlefieldcreate { width: auto; } @@ -2115,6 +2111,7 @@ span.butAction, span.butActionDelete { .butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete { background: #633; border: 1px solid #633; + color: #FFF; } .butActionDelete:hover { diff --git a/htdocs/theme/md/ckeditor/config.js b/htdocs/theme/md/ckeditor/config.js index eb88af48a04..6f1bbe7fb30 100644 --- a/htdocs/theme/md/ckeditor/config.js +++ b/htdocs/theme/md/ckeditor/config.js @@ -31,25 +31,25 @@ CKEDITOR.editorConfig = function( config ) ['Templates','NewPage'], ['Save'], ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], + ['PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], + ['CreateDiv','ShowBlocks'], ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], - ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], + ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['BidiLtr', 'BidiRtl'], ['Link','Unlink','Anchor'], ['Image','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], ['Styles','Format','Font','FontSize'], - ['TextColor','BGColor'], - ['Maximize', 'ShowBlocks'] + ['TextColor','BGColor'] ]; // Used for mailing fields config.toolbar_dolibarr_mailings = [ ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace'], ['Format','Font','FontSize'], ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], @@ -62,7 +62,7 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_notes = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace'], ['Format','Font','FontSize'], ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], @@ -75,9 +75,9 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_details = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Format','Font','FontSize'], - ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], + ['Bold','Italic','Underline','Strike','-','TextColor','RemoveFormat'], // ,'Subscript','Superscript' useless ['NumberedList','BulletedList','Outdent','Indent'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Link','Unlink','SpecialChar'] diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 312416afa29..c3a32ae02fc 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -458,7 +458,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['u.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"u.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['u.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"u.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['u.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"u.statut","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; From 1ab3086fcafa9cd342a3ea6d5ad6343db2ece6ed Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 16:44:43 +0200 Subject: [PATCH 335/410] Work on website module --- htdocs/websites/index.php | 225 ++++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 105 deletions(-) diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index e6bfec0d84a..b55f81f5b7f 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2016-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 @@ -143,6 +143,8 @@ $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain */ if (GETPOST('refreshsite')) $pageid=0; // If we change the site, we reset the pageid. +if (GETPOST('refreshpage')) $action='preview'; + // Add page if ($action == 'add') @@ -434,7 +436,7 @@ if ($action == 'updatemeta') } // Update page -if ($action == 'updatecontent') +if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage') || GETPOST('preview')) { $db->begin(); $object->fetch(0, $website); @@ -444,110 +446,123 @@ if ($action == 'updatecontent') $res = $objectpage->fetch($pageid, $object->fk_website); if ($res > 0) { - $objectpage->content = GETPOST('PAGE_CONTENT'); - - // Clean data. We remove all the head section. - $objectpage->content = preg_replace('//s', '', $objectpage->content); - /* $objectpage->content = preg_replace('//s', '', $objectpage->content); */ - - $res = $objectpage->update($user); - if ($res < 0) + if ($action == 'updatecontent') { - $error++; - setEventMessages($objectpage->error, $objectpage->errors, 'errors'); - } - - if (! $error) - { - $db->commit(); - - $filemaster=$pathofwebsite.'/master.inc.php'; - //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; - $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; - - dol_mkdir($pathofwebsite); - - - // Now generate the master.inc.php page - dol_syslog("We regenerate the master file"); - dol_delete_file($filemaster); - - $mastercontent = ''."\n"; - $result = file_put_contents($filemaster, $mastercontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); - - if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); - - - // Now generate the alias.php page - if (! empty($fileoldalias)) - { - dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); - dol_delete_file($fileoldalias); - } + $objectpage->content = GETPOST('PAGE_CONTENT'); + + // Clean data. We remove all the head section. + $objectpage->content = preg_replace('//s', '', $objectpage->content); + /* $objectpage->content = preg_replace('//s', '', $objectpage->content); */ - $aliascontent = 'id.".tpl.php';\n"; - $aliascontent.= '?>'."\n"; - $result = file_put_contents($filealias, $aliascontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filealias, octdec($conf->global->MAIN_UMASK)); - - if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); - - - // Now create the .tpl file with code to be able to make dynamic changes - dol_delete_file($filetpl); - - $tplcontent =''; - $tplcontent.= "\n"; - $tplcontent.= ''."\n"; - $tplcontent.= '
    '."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''.dol_escape_htmltag($objectpage->title).''."\n"; - $tplcontent.= '
    '."\n"; - - $tplcontent.= ''."\n"; - $tplcontent.= $objectpage->content."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= '"."\n"; - - //var_dump($filetpl);exit; - $result = file_put_contents($filetpl, $tplcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); - - if ($result) - { - setEventMessages($langs->trans("Saved"), null, 'mesgs'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - exit; - } - else setEventMessages('Failed to write file '.$filetpl, null, 'errors'); - } - else - { - $db->rollback(); - } + $res = $objectpage->update($user); + if ($res < 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } + + if (! $error) + { + $db->commit(); + + $filemaster=$pathofwebsite.'/master.inc.php'; + //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; + $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; + + dol_mkdir($pathofwebsite); + + + // Now generate the master.inc.php page + dol_syslog("We regenerate the master file"); + dol_delete_file($filemaster); + + $mastercontent = ''."\n"; + $result = file_put_contents($filemaster, $mastercontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); + + if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); + + + // Now generate the alias.php page + if (! empty($fileoldalias)) + { + dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); + dol_delete_file($fileoldalias); + } + + $aliascontent = 'id.".tpl.php';\n"; + $aliascontent.= '?>'."\n"; + $result = file_put_contents($filealias, $aliascontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filealias, octdec($conf->global->MAIN_UMASK)); + + if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + + + // Now create the .tpl file with code to be able to make dynamic changes + dol_delete_file($filetpl); + + $tplcontent =''; + $tplcontent.= "\n"; + $tplcontent.= ''."\n"; + $tplcontent.= '
    '."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''.dol_escape_htmltag($objectpage->title).''."\n"; + $tplcontent.= '
    '."\n"; + + $tplcontent.= ''."\n"; + $tplcontent.= $objectpage->content."\n"; + $tplcontent.= ''."\n"; + + $tplcontent.= '"."\n"; + + //var_dump($filetpl);exit; + $result = file_put_contents($filetpl, $tplcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + + if ($result) + { + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } + else + { + setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } + } + else + { + $db->rollback(); + } + } + else + { + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } } else { @@ -603,7 +618,7 @@ if ($action == 'edit') $style=''; if ($action != 'preview' && $action != 'editcontent') $style=' margin-bottom: 5px;'; - +//var_dump($objectpage);exit; print '
    '; if (count($object->records) > 0) From a0e75d0af053851c08c6efa2bd266e6a6ddbd9b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 16:44:43 +0200 Subject: [PATCH 336/410] Work on look and feel v6 --- htdocs/categories/class/categorie.class.php | 93 +++++--- htdocs/compta/bank/ligne.php | 169 +++++++-------- htdocs/compta/bank/releve.php | 7 +- htdocs/core/class/html.form.class.php | 34 ++- htdocs/websites/index.php | 225 +++++++++++--------- 5 files changed, 299 insertions(+), 229 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 0263395ec50..b2cd3d3dd31 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -49,9 +49,10 @@ class Categorie extends CommonObject const TYPE_MEMBER = 3; // TODO Replace this value with 'member' const TYPE_CONTACT = 4; // TODO Replace this value with 'contact' const TYPE_USER = 4; // categorie contact and user are same ! TODO Replace this value with 'user' - const TYPE_ACCOUNT = 5; // for bank account TODO Replace this value with 'account' - const TYPE_PROJECT = 6; - public $picto = 'category'; + const TYPE_ACCOUNT = 5; // TODO Replace this value with 'bank_account' + const TYPE_PROJECT = 6; + const TYPE_BANK_LINE = 'bank_line'; + public $picto = 'category'; /** @@ -1337,34 +1338,68 @@ class Categorie extends CommonObject $type = $map_type[$type]; } - $sql = "SELECT ct.fk_categorie, c.label, c.rowid"; - $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as ct, " . MAIN_DB_PREFIX . "categorie as c"; - $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . (int) $id . " AND c.type = " . $this->MAP_ID[$type]; - $sql .= " AND c.entity IN (" . getEntity( 'category', 1 ) . ")"; - - $res = $this->db->query($sql); - if ($res) + if ($type == Categorie::TYPE_BANK_LINE) // TODO Remove this with standard category code { - while ($obj = $this->db->fetch_object($res)) - { - if ($mode == 'id') { - $cats[] = $obj->rowid; - } else if ($mode == 'label') { - $cats[] = $obj->label; - } else { - $cat = new Categorie($this->db); - $cat->fetch($obj->fk_categorie); - $cats[] = $cat; - } - } - - return $cats; - } - else - { - dol_print_error($this->db); - return -1; + // Load bank groups + $sql = "SELECT c.label, c.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c"; + $sql.= " WHERE a.lineid=".$id." AND a.fk_categ = c.rowid"; + $sql.= " ORDER BY c.label"; + + $res = $this->db->query($sql); + if ($res) + { + while ($obj = $this->db->fetch_object($res)) + { + if ($mode == 'id') { + $cats[] = $obj->rowid; + } else if ($mode == 'label') { + $cats[] = $obj->label; + } else { + $cat = new Categorie($this->db); + $cat->id = $obj->rowid; + $cat->label = $obj->label; + $cats[] = $cat; + } + } + } + else + { + dol_print_error($this->db); + return -1; + } } + else + { + $sql = "SELECT ct.fk_categorie, c.label, c.rowid"; + $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as ct, " . MAIN_DB_PREFIX . "categorie as c"; + $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . (int) $id . " AND c.type = " . $this->MAP_ID[$type]; + $sql .= " AND c.entity IN (" . getEntity( 'category', 1 ) . ")"; + + $res = $this->db->query($sql); + if ($res) + { + while ($obj = $this->db->fetch_object($res)) + { + if ($mode == 'id') { + $cats[] = $obj->rowid; + } else if ($mode == 'label') { + $cats[] = $obj->label; + } else { + $cat = new Categorie($this->db); + $cat->fetch($obj->fk_categorie); + $cats[] = $cat; + } + } + } + else + { + dol_print_error($this->db); + return -1; + } + } + + return $cats; } diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 360a0d15a00..b50bf07d31a 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -1,7 +1,7 @@ * Copyright (C) 2003 Xavier DUTOIT - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2004 Christophe Combelles * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015-2017 Alexandre Spangaro @@ -30,6 +30,7 @@ require('../../main.inc.php'); require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $langs->load("banks"); $langs->load("categories"); @@ -47,6 +48,8 @@ $action=GETPOST('action','alpha'); $confirm=GETPOST('confirm','alpha'); $rowid=GETPOST("rowid",'int'); $orig_account=GETPOST("orig_account"); +$backtopage=GETPOST('backtopage'); +$cancel=GETPOSt('cancel'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref :'')); @@ -59,6 +62,14 @@ if (! $user->rights->banque->lire && ! $user->rights->banque->consolidate) acces /* * Actions */ +if ($cancel) +{ + if ($backtopage) + { + header("Location: ".$backtopage); + exit; + } +} if ($user->rights->banque->consolidate && $action == 'dvnext') { @@ -81,21 +92,6 @@ if ($action == 'confirm_delete_categ' && $confirm == "yes" && $user->rights->ban } } -if ($user->rights->banque->modifier && $action == 'class') -{ - $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid = ".$rowid." AND fk_categ = ".GETPOST('cat1', 'int'); - if (! $db->query($sql)) - { - dol_print_error($db); - } - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (lineid, fk_categ) VALUES (".$rowid.", ".GETPOST('cat1', 'int').")"; - if (! $db->query($sql)) - { - dol_print_error($db); - } -} - if ($user->rights->banque->modifier && $action == "update") { $error=0; @@ -145,7 +141,36 @@ if ($user->rights->banque->modifier && $action == "update") $sql.= " WHERE rowid = ".$rowid; $result = $db->query($sql); - if ($result) + if (! $result) + { + $error++; + } + + if (! $error) + { + $arrayofcategs=GETPOST('custcats', 'array'); + $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid = ".$rowid; + if (! $db->query($sql)) + { + $error++; + dol_print_error($db); + } + if (count($arrayofcategs)) + { + foreach($arrayofcategs as $val) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (lineid, fk_categ) VALUES (".$rowid.", ".$val.")"; + if (! $db->query($sql)) + { + $error++; + dol_print_error($db); + } + } + // $arrayselected will be loaded after in page output + } + } + + if (! $error) { setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); $db->commit(); @@ -204,19 +229,14 @@ if ($user->rights->banque->consolidate && ($action == 'num_releve' || $action == $form = new Form($db); -llxHeader(); +llxHeader('', $langs->trans("BankTransaction")); -// Load bank groups -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/bankcateg.class.php'; -$bankcateg = new BankCateg($db); -$options = array(); - -foreach ($bankcateg->fetchAll() as $bankcategory) { - $options[$bankcategory->id] = $bankcategory->label; +$c = new Categorie($db); +$cats = $c->containing($rowid, Categorie::TYPE_BANK_LINE); +foreach ($cats as $cat) { + $arrayselected[] = $cat->id; } -$var=false; - $tabs = array( array( DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$rowid, @@ -300,7 +320,7 @@ if ($result) // Show links of bank transactions if (count($links)) { - print "
    "; + print ''; print ''; } else @@ -444,7 +464,7 @@ if ($result) if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { print ''; } else @@ -498,7 +518,7 @@ if ($result) if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { print ''; } else @@ -532,7 +552,7 @@ if ($result) if ($user->rights->banque->modifier) { print ''; } else @@ -543,25 +563,41 @@ if ($result) } print ""; + // Categories + if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) + { + $langs->load('categories'); + + // Bank line + print '"; + } + print "
    '; print ''; print '
    '; $holidaystatic->id=$infos_CP['rowid']; $holidaystatic->ref=$infos_CP['rowid']; diff --git a/htdocs/modulebuilder/skeletons/skeleton_list.php b/htdocs/modulebuilder/skeletons/skeleton_list.php index 561dc98da35..fb2ec136bbe 100644 --- a/htdocs/modulebuilder/skeletons/skeleton_list.php +++ b/htdocs/modulebuilder/skeletons/skeleton_list.php @@ -365,7 +365,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); //if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print '
    ".$langs->trans("Links")."
    '.$langs->trans("Links").''; foreach($links as $key=>$val) { @@ -430,7 +450,7 @@ if ($result) if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print 'rappro?' disabled':'').' value="'; + print 'rappro?' disabled':'').' value="'; if (preg_match('/^\((.*)\)$/i',$objp->label,$reg)) { // Label generique car entre parentheses. On l'affiche en le traduisant @@ -508,7 +528,7 @@ if ($result) { print $objp->label; } - print '" size="50">'; + print '">'; print ''; - print 'rappro?' disabled':'').' value="'.price($objp->amount).'"> '.$langs->trans("Currency".$acct->currency_code); + print 'rappro?' disabled':'').' value="'.price($objp->amount).'"> '.$langs->trans("Currency".$acct->currency_code); print '
    ' . fieldLabel('RubriquesTransactions', 'custcats') . ''; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_BANK_LINE, null, 'parent', null, null, 1); + print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, null, null, null, null, "90%"); + print "
    "; dol_fiche_end(); + print '

    '; - + print ""; + + // Releve rappro if ($acct->canBeConciliated() > 0) // Si compte rapprochable { - print '

    '."\n"; - print load_fiche_titre($langs->trans("Reconciliation"), '', 'title_bank.png'); + print '
    '."\n"; + print '
    '; print ''; print ''; print ''; - + print ''; + print ''; print '"; @@ -600,7 +636,15 @@ if ($result) print ''; print '
    '.$langs->trans("Conciliation")."
    '; - print '

    '; + print '
    '; + + print ''; + if ($backtopage) + { + print '   '; + print ''; + } + print '
    '; print '
    '; } @@ -611,55 +655,6 @@ if ($result) } else dol_print_error($db); - - -// List of bank categories -print '
    '; - -print '
    '; -print ''; -print ''; -print ''; - -print ''; -print ''; -} -print ''; - -$sql = "SELECT c.label, c.rowid"; -$sql.= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c"; -$sql.= " WHERE a.lineid=".$rowid." AND a.fk_categ = c.rowid"; -$sql.= " ORDER BY c.label"; -$result = $db->query($sql); -if ($result) -{ - $var=True; - $num = $db->num_rows($result); - $i = 0; $total = 0; - while ($i < $num) - { - $objp = $db->fetch_object($result); - - print ''; - - print ""; - print ""; - if ($user->rights->banque->modifier) - { - print ''; - } - print ''; - - $i++; - } - $db->free($result); -} -print '
    '.$langs->trans("Rubriques").''; -if ($user->rights->banque->modifier) -{ - print Form::selectarray('cat1', $options, '', 1).' '; - print '
    ".$objp->label."rowid."\">".$langs->trans("ListBankTransactions")."'.img_delete($langs->trans("Remove")).'
    '; - llxFooter(); $db->close(); diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 9d9826d0729..5abbcb2512e 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2017 Patrick Delcroix @@ -403,8 +403,7 @@ else $objp = $db->fetch_object($result); $total = $total + $objp->amount; - $var=!$var; - print ""; + print ''; // Date operation print ''.dol_print_date($db->jdate($objp->do),"day").''; @@ -595,7 +594,7 @@ else if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { - print "rowid&account=".$object->id."\">"; + print ''; print img_edit(); print ""; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index eba2fda5049..6bd2d3036b9 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3395,7 +3395,7 @@ class Form */ function select_all_categories($type, $selected='', $htmlname="parent", $maxlength=64, $excludeafterid=0, $outputmode=0) { - global $langs; + global $conf, $langs; $langs->load("categories"); include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; @@ -3406,9 +3406,35 @@ class Form dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING); } - $cat = new Categorie($this->db); - $cate_arbo = $cat->get_full_arbo($type,$excludeafterid); - + if ($type == Categorie::TYPE_BANK_LINE) + { + // TODO Move this into common category feature + $categids=array(); + $sql = "SELECT c.label, c.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank_categ as c"; + $sql.= " WHERE entity = ".$conf->entity; + $sql.= " ORDER BY c.label"; + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + if ($objp) $cate_arbo[$objp->rowid]=array('id'=>$objp->rowid, 'fulllabel'=>$objp->label); + $i++; + } + $this->db->free($result); + } + else dol_print_error($this->db); + } + else + { + $cat = new Categorie($this->db); + $cate_arbo = $cat->get_full_arbo($type,$excludeafterid); + } + $output = ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +$head=defaultvalues_prepare_head(); + +dol_fiche_head($head, 'overwrite', '', -1, ''); + + +print ''; +print ''; +print ''; + +print ''; +print ''; +print_liste_field_titre($langs->trans("Language").' (en_US, es_MX, ...)',$_SERVER["PHP_SELF"],'lang,transkey','',$param,'',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Key"),$_SERVER["PHP_SELF"],'transkey','',$param,'',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("NewTranslationStringToShow"),$_SERVER["PHP_SELF"],'transvalue','',$param,'',$sortfield,$sortorder); +//if (! empty($conf->multicompany->enabled) && !$user->entity) print_liste_field_titre($langs->trans("Entity"),$_SERVER["PHP_SELF"],'entity,transkey','',$param,'',$sortfield,$sortorder); +print ''; +print "\n"; + + +// Line to add new record +print "\n"; + +print ''."\n"; +print ''; +// Limit to superadmin +/*if (! empty($conf->multicompany->enabled) && !$user->entity) +{ + print ''; + print '\n"; +print ''; + + +// Show constants +$sql = "SELECT"; +$sql.= " rowid"; +$sql.= ", lang"; +$sql.= ", transkey"; +$sql.= ", transvalue"; +$sql.= " FROM ".MAIN_DB_PREFIX."overwrite_trans"; +$sql.= " WHERE 1 = 1"; +//$sql.= " AND entity IN (".$user->entity.",".$conf->entity.")"; +//if ((empty($user->entity) || $user->admin) && $debug) {} // to force for superadmin to debug +//else if (! GETPOST('visible') || GETPOST('visible') != 'all') $sql.= " AND visible = 1"; // We must always have this. Otherwise, array is too large and submitting data fails due to apache POST or GET limits +//if (GETPOST('name')) $sql.=natural_search("name", GETPOST('name')); +//$sql.= " ORDER BY entity, name ASC"; +$sql.= $db->order($sortfield, $sortorder); + +dol_syslog("translation::select from table", LOG_DEBUG); +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + $i = 0; + $var=false; + + while ($i < $num) + { + $obj = $db->fetch_object($result); + $var=!$var; + + print "\n"; + + print ''; + + print ''."\n"; + print ''."\n"; + + // Value + print ''; + + print ''; + + print "\n"; + print "\n"; + $i++; + } +} + + +print '
    '; +print $formadmin->select_language(GETPOST('langcode'), 'langcode', 0, null, 1, 0, 0, 'maxwidthonsmartphone', 1); +print ''; +print ''; +print ''; +print ''; +print ''; + print ''; + print ''; +} +else +{*/ + print ''; + print ''; +//} +print ''; +print "
    '.$obj->lang.''.$obj->transkey.''; + /*print ''; + print ''; + print ''; + print ''; + */ + print $obj->transvalue; + print ''; + print ''.img_delete().''; + print '
    '; + +dol_fiche_end(); + +print "\n"; + + +llxFooter(); + +$db->close(); diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index 4dbfc53c821..bb485c41999 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -57,10 +57,6 @@ if (! $sortfield) $sortfield='lang,transkey'; if (! $sortorder) $sortorder='ASC'; -/* - * Actions - */ - /* * Actions */ diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index edfeef064f2..5c4df1bcd91 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -598,6 +598,35 @@ function translation_prepare_head() } +/** + * Prepare array with list of tabs + * + * @return array Array of tabs to show + */ +function defaultvalues_prepare_head() +{ + global $langs, $conf, $user; + $h = 0; + $head = array(); + + $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=overwrite"; + $head[$h][1] = $langs->trans("DefaultValuesOverwriteKey"); + $head[$h][2] = 'overwrite'; + $h++; + + /*$head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=searchkey"; + $head[$h][1] = $langs->trans("TranslationKeySearch"); + $head[$h][2] = 'searchkey'; + $h++;*/ + + complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin'); + + complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin','remove'); + + + return $head; +} + /** * Return list of session diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index c0da3e8af0e..f85885def1d 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -545,6 +545,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/admin/ihm.php?mainmenu=home", $langs->trans("GUISetup"),1); $newmenu->add("/admin/translation.php?mainmenu=home", $langs->trans("Translation"),1); + $newmenu->add("/admin/defaultvalues.php?mainmenu=home", $langs->trans("DefaultValues"),1, $conf->global->MAIN_FEATURES_LEVEL); $newmenu->add("/admin/boxes.php?mainmenu=home", $langs->trans("Boxes"),1); $newmenu->add("/admin/delais.php?mainmenu=home",$langs->trans("MenuWarnings"),1); $newmenu->add("/admin/security_other.php?mainmenu=home", $langs->trans("Security"),1); From ff75077b340888a079b1a61c541b1c90bb83d03b Mon Sep 17 00:00:00 2001 From: vvnt Date: Sat, 8 Apr 2017 20:15:14 +0200 Subject: [PATCH 341/410] Fix: bug #6653 situation invoice miscalculation Bug (#6653) In price.lib.php (htdocs\core\lib\price.lib.php), the function calcul_price_total() is defined (line 76). The 7th parameter is **$remise_percent_global**. However, this function is called on facture.class.php (htdocs\compta\facture\class\facture.class.php) and the 7th parameter used is **$line->product_type**. Consequently, invoice situation is correct when user sells a product (product_type = 0) and is wrong when user sells a service (product_type = 1). Effectively, in the latter case, the total situation invoice will be wrong by 1%. In order to correct this, we can add 0 as the 7th parameter and move **$line->product_type** to the 10th parameter. --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 963534da934..5838bb9bcf3 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2872,7 +2872,7 @@ class Facture extends CommonInvoice // Cap percentages to 100 if ($percent > 100) $percent = 100; $line->situation_percent = $percent; - $tabprice = calcul_price_total($line->qty, $line->subprice, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->product_type, 'HT', 0, 0, $mysoc, '', $percent); + $tabprice = calcul_price_total($line->qty, $line->subprice, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 0, 'HT', 0, $line->product_type, $mysoc, '', $percent); $line->total_ht = $tabprice[0]; $line->total_tva = $tabprice[1]; $line->total_ttc = $tabprice[2]; From feebd4252a0d364f18cfcbb520d8e4c3248d74f8 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 9 Apr 2017 11:29:54 +0200 Subject: [PATCH 342/410] add invoice_rec_prepare_head for reccuring invoice --- htdocs/core/lib/invoice.lib.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 6e5640d1e0a..453b27aefee 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -3,6 +3,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Juanjo Menent + * Copyright (C) 2017 Charlie Benke * * 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 @@ -157,4 +158,27 @@ function invoice_admin_prepare_head() } +function invoice_rec_prepare_head($object) +{ + global $db, $langs, $conf; + + $h = 0; + $head = array(); + + $head[$h][0] = DOL_URL_ROOT.'/compta/facture/fiche-rec.php?facid='.$object->id; + $head[$h][1] = $langs->trans('Card'); + $head[$h][2] = 'compta'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab + // $this->tabs = array('entity:-tabname); to remove a tab + complete_head_from_modules($conf,$langs,$object,$head,$h,'invoice-rec'); + + complete_head_from_modules($conf,$langs,$object,$head,$h,'invoice-rec','remove'); + + return $head; +} + From 54780ff205b5ab18b8a25b11318c08b8cb50c788 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 9 Apr 2017 11:33:09 +0200 Subject: [PATCH 343/410] Update fiche-rec.php --- htdocs/compta/facture/fiche-rec.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 88cb39bd7a9..90938242f5f 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -38,6 +38,7 @@ if (! empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; } require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php'; $langs->load('bills'); $langs->load('compta'); @@ -1109,11 +1110,7 @@ else $author = new User($db); $author->fetch($object->user_author); - $head=array(); - $h=0; - $head[$h][0] = $_SERVER["PHP_SELF"].'?id='.$object->id; - $head[$h][1] = $langs->trans("CardBill"); - $head[$h][2] = 'card'; + $head=invoice_rec_prepare_head($object); dol_fiche_head($head, 'card', $langs->trans("RepeatableInvoice"),0,'bill'); // Add a div From a0a9c8fa0c35e5c122fa5ee5a3c4c077cdcee77a Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 9 Apr 2017 11:33:56 +0200 Subject: [PATCH 344/410] Update invoice.lib.php --- htdocs/core/lib/invoice.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 453b27aefee..564e909a2da 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -165,9 +165,9 @@ function invoice_rec_prepare_head($object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/compta/facture/fiche-rec.php?facid='.$object->id; - $head[$h][1] = $langs->trans('Card'); - $head[$h][2] = 'compta'; + $head[$h][0] = DOL_URL_ROOT.'/compta/facture/fiche-rec.php?id='.$object->id; + $head[$h][1] = $langs->trans("CardBill"); + $head[$h][2] = 'card'; $h++; // Show more tabs from modules From e4ed626912dcd6d070eeb286e15a124d94d110c8 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Sun, 9 Apr 2017 12:50:09 +0200 Subject: [PATCH 345/410] Fix: Travis error --- test/phpunit/FactureFournisseurTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/phpunit/FactureFournisseurTest.php b/test/phpunit/FactureFournisseurTest.php index 199d397f50d..7985e8f0931 100644 --- a/test/phpunit/FactureFournisseurTest.php +++ b/test/phpunit/FactureFournisseurTest.php @@ -1,5 +1,6 @@ + * Copyright (C) 2017 Juanjo Menent * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -259,7 +260,7 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase $localobject=new FactureFournisseur($this->savdb); $result=$localobject->fetch($id); - $result=$localobject->delete($id); + $result=$localobject->delete($user); print __METHOD__." id=".$id." result=".$result."\n"; $this->assertLessThan($result, 0); From 52c86cb3f5af57c26e691241adf9bfde3e1bd2ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 9 Apr 2017 13:12:25 +0200 Subject: [PATCH 346/410] NEW Bulk actions available on supplier orders --- htdocs/comm/card.php | 2 +- htdocs/comm/remise.php | 38 +- htdocs/comm/remx.php | 262 ++++++----- htdocs/commande/list.php | 449 ++++++++++--------- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/class/html.formfile.class.php | 10 +- htdocs/core/lib/files.lib.php | 24 + htdocs/core/lib/functions.lib.php | 16 + htdocs/fourn/commande/list.php | 517 +++++++++++++++++++--- htdocs/societe/class/societe.class.php | 2 +- htdocs/theme/eldy/style.css.php | 23 +- htdocs/theme/md/style.css.php | 14 +- 12 files changed, 913 insertions(+), 446 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index aa6c2729745..52fdaa6eceb 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -460,7 +460,7 @@ if ($id > 0) } else { - print $langs->trans("ThirdpartyNotLinkedToMember"); + print ''.$langs->trans("ThirdpartyNotLinkedToMember").''; } print ''; print "\n"; diff --git a/htdocs/comm/remise.php b/htdocs/comm/remise.php index cf93c87dabb..2be1981c5ae 100644 --- a/htdocs/comm/remise.php +++ b/htdocs/comm/remise.php @@ -107,7 +107,7 @@ if ($socid > 0) print ''; print ''; - dol_fiche_head($head, 'relativediscount', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'relativediscount', $langs->trans("ThirdParty"), 0, 'company'); dol_banner_tab($object, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom'); @@ -119,7 +119,6 @@ if ($socid > 0) // Discount print ''; print $langs->trans("CustomerRelativeDiscount").''.price2num($object->remise_percent)."%"; - print ''; print '
    '; @@ -130,11 +129,11 @@ if ($socid > 0) print ''; // New value - print ''; // Motif/Note - print ''; print "
    '; + print '
    '; print $langs->trans("NewValue").'%
    '; + print '
    '; print $langs->trans("NoteReason").'
    "; @@ -179,21 +178,26 @@ if ($socid > 0) print ''.$langs->trans("NoteReason").''; print ''.$langs->trans("User").''; print ''; - $i = 0 ; $num = $db->num_rows($resql); - - while ($i < $num ) - { - $obj = $db->fetch_object($resql); - $tag = !$tag; - print ''; - print ''.dol_print_date($db->jdate($obj->dc),"dayhour").''; - print ''.price2num($obj->remise_percent).'%'; - print ''.$obj->note.''; - print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; - print ''; - $i++; + if ($num > 0) + { + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + print ''; + print ''.dol_print_date($db->jdate($obj->dc),"dayhour").''; + print ''.price2num($obj->remise_percent).'%'; + print ''.$obj->note.''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ''; + $i++; + } } + else + { + print ''.$langs->trans("None").''; + } $db->free($resql); print ""; } diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 6481c891d45..375b4d0ecb8 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -235,7 +235,7 @@ if ($socid > 0) print ''; print ''; - dol_fiche_head($head, 'absolutediscount', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'absolutediscount', $langs->trans("ThirdParty"), 0, 'company'); dol_banner_tab($object, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom'); @@ -274,6 +274,8 @@ if ($socid > 0) } print ''; + print '
    '; + if ($user->rights->societe->creer) { print '
    '; @@ -294,7 +296,6 @@ if ($socid > 0) print ""; } - print '
  • '; dol_fiche_end(); @@ -342,8 +343,8 @@ if ($socid > 0) print load_fiche_titre($langs->trans("DiscountStillRemaining")); print ''; print ''; - print ''; // Need 120+ for format with AM/PM - print ''; + print ''; // Need 120+ for format with AM/PM + print ''; print ''; print ''; print ''; @@ -354,73 +355,79 @@ if ($socid > 0) $showconfirminfo=array(); - $var = true; $i = 0; $num = $db->num_rows($resql); - while ($i < $num) + if ($num > 0) { - $obj = $db->fetch_object($resql); - $var = !$var; - print ""; - print ''; - if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) - { - print ''; - } - else - { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - if ($user->rights->societe->creer || $user->rights->facture->creer) - { - print ''; - } - else print ''; - print ''; - - if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) - { - $showconfirminfo['rowid']=$obj->rowid; - $showconfirminfo['amount_ttc']=$obj->amount_ttc; - } - $i++; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + if ($user->rights->societe->creer || $user->rights->facture->creer) + { + print ''; + } + else print ''; + print ''; + + if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) + { + $showconfirminfo['rowid']=$obj->rowid; + $showconfirminfo['amount_ttc']=$obj->amount_ttc; + } + $i++; + } } + else + { + print ''; + } $db->free($resql); print "
    '.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").'
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - print $obj->description; - print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; - print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; - print ''; - print 'rowid.'">'.img_picto($langs->trans("SplitDiscount"),'split').''; - print '   '; - print 'rowid.'">'.img_delete($langs->trans("RemoveDiscount")).''; - print ' 
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + print $obj->description; + print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ''; + print 'rowid.'">'.img_split($langs->trans("SplitDiscount")).''; + print '   '; + print 'rowid.'">'.img_delete($langs->trans("RemoveDiscount")).''; + print ' 
    '.$langs->trans("None").'
    "; @@ -491,8 +498,8 @@ if ($socid > 0) print load_fiche_titre($langs->trans("DiscountAlreadyCounted")); print ''; print ''; - print ''; // Need 120+ for format with AM/PM - print ''; + print ''; // Need 120+ for format with AM/PM + print ''; print ''; print ''; print ''; @@ -501,15 +508,17 @@ if ($socid > 0) print ''; print ''; - $var = true; $tab_sqlobj=array(); $tab_sqlobjOrder=array(); $num = $db->num_rows($resql); - for ($i = 0;$i < $num;$i++) + if ($num > 0) { - $sqlobj = $db->fetch_object($resql); - $tab_sqlobj[] = $sqlobj; - $tab_sqlobjOrder[]=$db->jdate($sqlobj->dc); + for ($i = 0;$i < $num; $i++) + { + $sqlobj = $db->fetch_object($resql); + $tab_sqlobj[] = $sqlobj; + $tab_sqlobjOrder[]=$db->jdate($sqlobj->dc); + } } $db->free($resql); @@ -524,57 +533,64 @@ if ($socid > 0) array_multisort($tab_sqlobjOrder,SORT_DESC,$tab_sqlobj); $num = count($tab_sqlobj); - $i = 0 ; - while ($i < $num ) + if ($num > 0) { - $obj = array_shift($tab_sqlobj); - $var = !$var; - print ""; - print ''; - if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) - { - print ''; - } - else - { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $i++; + $i = 0 ; + while ($i < $num ) + { + $obj = array_shift($tab_sqlobj); + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $i++; + } } + else + { + print ''; + } + print "
    '.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").' 
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - print $obj->description; - print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; - print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; - print ' 
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + print $obj->description; + print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ' 
    '.$langs->trans("None").'
    "; } else diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index fcd68992b38..6d8f42edffb 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -199,227 +199,226 @@ if (empty($reshook)) $permtodelete = $user->rights->commande->supprimer; $uploaddir = $conf->commande->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; -} - -if ($massaction == 'confirm_createbills') { - - $orders = GETPOST('toselect'); - $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); - $validate_invoices = GETPOST('valdate_invoices', 'int'); - - $TFact = array(); - $TFactThird = array(); - - $nb_bills_created = 0; - - $db->begin(); - - foreach($orders as $id_order) { - - $cmd = new Commande($db); - if($cmd->fetch($id_order) <= 0) continue; - - $object = new Facture($db); - if(!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) $object = $TFactThird[$cmd->socid]; // If option "one bill per third" is set, we use already created order. - else { - - $object->socid = $cmd->socid; - $object->type = Facture::TYPE_STANDARD; - $object->cond_reglement_id = $cmd->cond_reglement_id; - $object->mode_reglement_id = $cmd->mode_reglement_id; - $object->fk_project = $cmd->fk_project; - - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $datefacture = dol_mktime(date("h"), date("M"), 0, date("m"), date("d"), date("Y")); - } - - $object->date = $datefacture; - $object->origin = 'commande'; - $object->origin_id = $id_order; - - $res = $object->create($user); - - if($res > 0) $nb_bills_created++; - - } - - if($object->id > 0) { - - $db->begin(); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; - $sql.= "fk_source"; - $sql.= ", sourcetype"; - $sql.= ", fk_target"; - $sql.= ", targettype"; - $sql.= ") VALUES ("; - $sql.= $id_order; - $sql.= ", '".$object->origin."'"; - $sql.= ", ".$object->id; - $sql.= ", '".$object->element."'"; - $sql.= ")"; - - if ($db->query($sql)) - { - $db->commit(); - } - else - { - $db->rollback(); - } - - $lines = $cmd->lines; - if (empty($lines) && method_exists($cmd, 'fetch_lines')) - { - $cmd->fetch_lines(); - $lines = $cmd->lines; - } - - $fk_parent_line=0; - $num=count($lines); - - for ($i=0;$i<$num;$i++) - { - $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle); - if ($lines[$i]->subprice < 0) - { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc=$object->socid; - $discount->amount_ht=abs($lines[$i]->total_ht); - $discount->amount_tva=abs($lines[$i]->total_tva); - $discount->amount_ttc=abs($lines[$i]->total_ttc); - $discount->tva_tx=$lines[$i]->tva_tx; - $discount->fk_user=$user->id; - $discount->description=$desc; - $discountid=$discount->create($user); - if ($discountid > 0) - { - $result=$object->insert_discount($discountid); - //$result=$discount->link_to_invoice($lineid,$id); - } - else - { - setEventMessages($discount->error, $discount->errors, 'errors'); - $error++; - break; - } - } - else - { - // Positive line - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - // Date start - $date_start=false; - if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; - //Date end - $date_end=false; - if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) - { - $fk_parent_line = 0; - } - $result = $object->addline( - $desc, - $lines[$i]->subprice, - $lines[$i]->qty, - $lines[$i]->tva_tx, - $lines[$i]->localtax1_tx, - $lines[$i]->localtax2_tx, - $lines[$i]->fk_product, - $lines[$i]->remise_percent, - $date_start, - $date_end, - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_remise_except, - 'HT', - 0, - $product_type, - $ii, - $lines[$i]->special_code, - $object->origin, - $lines[$i]->rowid, - $fk_parent_line, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - $lines[$i]->label - ); - if ($result > 0) - { - $lineid=$result; - } - else - { - $lineid=0; - $error++; - break; - } - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) - { - $fk_parent_line = $result; - } - } - } - - } - - $cmd->classifyBilled($user); - - if(!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) $TFactThird[$cmd->socid] = $object; - else $TFact[$object->id] = $object; - } - - // Build doc with all invoices - $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; - $toselect = array(); - - if(!empty($validate_invoices)) { - - $massaction = $action = 'builddoc'; - - foreach($TAllFact as &$object) { - $object->validate($user); - $toselect[] = $object->id; // For builddoc action - - // Fac builddoc - $upload_dir = $conf->facture->dir_output; - $permissioncreate=$user->rights->facture->creer; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - } - - $objectclass='Facture'; - $objectlabel='Invoice'; - $permtoread = $user->rights->facture->lire; - $permtodelete = $user->rights->facture->supprimer; - $uploaddir = $conf->facture->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; - - } - - if (! $error) - { - $db->commit(); - setEventMessage($langs->trans('BillCreated', $nb_bills_created)); - } - else - { - $db->rollback(); - $action='create'; - $_GET["origin"]=$_POST["origin"]; - $_GET["originid"]=$_POST["originid"]; - setEventMessages($object->error, $object->errors, 'errors'); - $error++; - } - + // TODO Move this into mass action include + if ($massaction == 'confirm_createbills') { + + $orders = GETPOST('toselect'); + $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); + $validate_invoices = GETPOST('valdate_invoices', 'int'); + + $TFact = array(); + $TFactThird = array(); + + $nb_bills_created = 0; + + $db->begin(); + + foreach($orders as $id_order) { + + $cmd = new Commande($db); + if($cmd->fetch($id_order) <= 0) continue; + + $object = new Facture($db); + if(!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) $object = $TFactThird[$cmd->socid]; // If option "one bill per third" is set, we use already created order. + else { + + $object->socid = $cmd->socid; + $object->type = Facture::TYPE_STANDARD; + $object->cond_reglement_id = $cmd->cond_reglement_id; + $object->mode_reglement_id = $cmd->mode_reglement_id; + $object->fk_project = $cmd->fk_project; + + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $datefacture = dol_mktime(date("h"), date("M"), 0, date("m"), date("d"), date("Y")); + } + + $object->date = $datefacture; + $object->origin = 'commande'; + $object->origin_id = $id_order; + + $res = $object->create($user); + + if($res > 0) $nb_bills_created++; + + } + + if($object->id > 0) { + + $db->begin(); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; + $sql.= "fk_source"; + $sql.= ", sourcetype"; + $sql.= ", fk_target"; + $sql.= ", targettype"; + $sql.= ") VALUES ("; + $sql.= $id_order; + $sql.= ", '".$object->origin."'"; + $sql.= ", ".$object->id; + $sql.= ", '".$object->element."'"; + $sql.= ")"; + + if ($db->query($sql)) + { + $db->commit(); + } + else + { + $db->rollback(); + } + + $lines = $cmd->lines; + if (empty($lines) && method_exists($cmd, 'fetch_lines')) + { + $cmd->fetch_lines(); + $lines = $cmd->lines; + } + + $fk_parent_line=0; + $num=count($lines); + + for ($i=0;$i<$num;$i++) + { + $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle); + if ($lines[$i]->subprice < 0) + { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc=$object->socid; + $discount->amount_ht=abs($lines[$i]->total_ht); + $discount->amount_tva=abs($lines[$i]->total_tva); + $discount->amount_ttc=abs($lines[$i]->total_ttc); + $discount->tva_tx=$lines[$i]->tva_tx; + $discount->fk_user=$user->id; + $discount->description=$desc; + $discountid=$discount->create($user); + if ($discountid > 0) + { + $result=$object->insert_discount($discountid); + //$result=$discount->link_to_invoice($lineid,$id); + } + else + { + setEventMessages($discount->error, $discount->errors, 'errors'); + $error++; + break; + } + } + else + { + // Positive line + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + // Date start + $date_start=false; + if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; + //Date end + $date_end=false; + if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) + { + $fk_parent_line = 0; + } + $result = $object->addline( + $desc, + $lines[$i]->subprice, + $lines[$i]->qty, + $lines[$i]->tva_tx, + $lines[$i]->localtax1_tx, + $lines[$i]->localtax2_tx, + $lines[$i]->fk_product, + $lines[$i]->remise_percent, + $date_start, + $date_end, + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_remise_except, + 'HT', + 0, + $product_type, + $ii, + $lines[$i]->special_code, + $object->origin, + $lines[$i]->rowid, + $fk_parent_line, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + $lines[$i]->label + ); + if ($result > 0) + { + $lineid=$result; + } + else + { + $lineid=0; + $error++; + break; + } + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) + { + $fk_parent_line = $result; + } + } + } + + } + + $cmd->classifyBilled($user); + + if(!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) $TFactThird[$cmd->socid] = $object; + else $TFact[$object->id] = $object; + } + + // Build doc with all invoices + $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; + $toselect = array(); + + if(!empty($validate_invoices)) { + + $massaction = $action = 'builddoc'; + + foreach($TAllFact as &$object) { + $object->validate($user); + $toselect[] = $object->id; // For builddoc action + + // Fac builddoc + $upload_dir = $conf->facture->dir_output; + $permissioncreate=$user->rights->facture->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + } + + $objectclass='Facture'; + $objectlabel='Invoice'; + $permtoread = $user->rights->facture->lire; + $permtodelete = $user->rights->facture->supprimer; + $uploaddir = $conf->facture->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + + } + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans('BillCreated', $nb_bills_created)); + } + else + { + $db->rollback(); + $action='create'; + $_GET["origin"]=$_POST["origin"]; + $_GET["originid"]=$_POST["originid"]; + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } } @@ -435,8 +434,9 @@ $formfile = new FormFile($db); $companystatic = new Societe($db); $formcompany=new FormCompany($db); +$title=$langs->trans("Orders"); $help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; -llxHeader('',$langs->trans("Orders"),$help_url); +llxHeader('',$title,$help_url); $sql = 'SELECT'; if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT'; @@ -622,7 +622,6 @@ if ($resql) if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; if ($billed != '') $param.='&billed='.$billed; - // Add $param from extra fields foreach ($search_array_options as $key => $val) { @@ -654,6 +653,7 @@ if ($resql) print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, '', '', $limit); + // TODO Move this into an invluce if ($massaction == 'presend') { $langs->load("mails"); @@ -679,9 +679,6 @@ if ($resql) print ''; - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - dol_fiche_head(null, '', ''); $topicmail="SendOrderRef"; @@ -1428,8 +1425,6 @@ if ($resql) print ''."\n"; - //print '
    '.img_help(1,'').' '.$langs->trans("ToBillSeveralOrderSelectCustomer", $langs->transnoentitiesnoconv("CreateInvoiceForThisCustomer")).'
    '; - if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) { /* diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6bd2d3036b9..9ee36f783d2 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6218,7 +6218,7 @@ class Form global $conf, $langs; $out=''; - if (! empty($conf->use_javascript_ajax)) $out.=''; + if (! empty($conf->use_javascript_ajax)) $out.='
    '; $out.='