diff --git a/ChangeLog b/ChangeLog index 51107b308c2..359ae891b50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,7 +22,7 @@ WARNING: Following changes may create regression for some external modules, but were necessary to make Dolibarr better: - Function delete of class Facture (invoice) need the object $user as first parameter. Also you must -check you make a fetch on object before calling the delete. + check you make a fetch on object before calling the delete. - The old driver of "mysql" has been removed. Dolibarr use the new one (mysqli) by default. - Remove not used function calculate_byte(). Use dol_print_size() instead. - Function pdf_getTotalQty is now deprecated. Not used by Dolibarr core. @@ -36,7 +36,8 @@ check you make a fetch on object before calling the delete. So there is no reason to maintain its compatibility with other dolibarr components. If an external module need this library, this external module must embed hte library in his own sources/packages. - Trigger name SUPPLIER_PROPOSAL_CREATE has been renamed into PROPOSAL_SUPPLIER_CREATE - +- A new paramater sqlfilters was introduced to allow filter on any fields int the REST API. Few old parameters + no more required were also removed. Use this new one if you ware using one of them. ***** ChangeLog for 4.0.1 compared to 4.0.0 ***** diff --git a/build/debian/copyright b/build/debian/copyright index e3397d82992..8207df4b6d7 100644 --- a/build/debian/copyright +++ b/build/debian/copyright @@ -1,7 +1,7 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Dolibarr Upstream-Contact: Laurent Destailleur -Source: http://www.dolibarr.org/files/stable/standard/ +Source: https://www.dolibarr.org/files/stable/standard/ Files: * Copyright: 2002-2009, Rodolphe Quiedeville diff --git a/dev/skeletons/skeleton_api_class.class.php b/dev/skeletons/skeleton_api_class.class.php index 9cc8de2bc5e..a40b00af72c 100644 --- a/dev/skeletons/skeleton_api_class.class.php +++ b/dev/skeletons/skeleton_api_class.class.php @@ -93,12 +93,12 @@ class SkeletonApi extends DolibarrApi * @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 getList($mode, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) { + function index($mode, $sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -124,18 +124,19 @@ class SkeletonApi extends DolibarrApi 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; } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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); diff --git a/dev/skeletons/skeleton_class.class.php b/dev/skeletons/skeleton_class.class.php index eb915999e7e..bb4358806f1 100644 --- a/dev/skeletons/skeleton_class.class.php +++ b/dev/skeletons/skeleton_class.class.php @@ -454,33 +454,49 @@ class Skeleton_Class extends CommonObject * @param integer $notooltip 1=Disable tooltip * @param int $maxlen Max length of visible user name * @param string $morecss Add more css on link + * @param int $notooltip 1=Disable tooltip * @return string String with URL */ - function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') + function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='', $notooltip=0) { - global $langs, $conf, $db; + 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.= '
'; $label.= '' . $langs->trans('Ref') . ': ' . $this->ref; - $link = '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.=($link.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); + $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); if ($withpicto != 2) $result.=' '; } - $result.= $link . $this->ref . $linkend; + $result.= $linkstart . $this->ref . $linkend; return $result; } diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 90e96b23a83..ddbc7123d70 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -257,6 +257,7 @@ if (empty($reshook)) } $lastname=$_POST["lastname"]; $firstname=$_POST["firstname"]; + $societe=$_POST["societe"]; $morphy=$_POST["morphy"]; $login=$_POST["login"]; if ($morphy != 'mor' && empty($lastname)) { diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index d18bbdbc106..9b55ef995f7 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -84,13 +84,12 @@ class Members extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $typeid ID of the type of member - * @param string $login To filter the members by login - * @param string $name To filter the members by name (firstname, lastname or company name matching the filter) - * @return array Array of member objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of member objects * * @throws RestException */ - function index($sortfield = "a.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $typeid = '', $login = '', $name = '') { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $typeid = '', $login = '', $name = '', $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -99,27 +98,24 @@ class Members extends DolibarrApi throw new RestException(401); } - $sql = "SELECT a.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; - $sql.= ' WHERE a.entity IN ('.getEntity('adherent', 1).')'; + $sql = "SELECT t.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as t"; + $sql.= ' WHERE t.entity IN ('.getEntity('adherent', 1).')'; if (!empty($typeid)) { - $sql.= ' AND a.fk_adherent_type='.$typeid; + $sql.= ' AND t.fk_adherent_type='.$typeid; } - if (!empty($login)) { - $sql .= " AND a.login LIKE '%".$login."%'"; - } - if (!empty($name)) { - $sql .= " AND (a.firstname LIKE '%".$name."%' OR a.lastname LIKE '%".$name."%' OR a.societe LIKE '%".$name."%')"; - } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) @@ -271,7 +267,7 @@ class Members extends DolibarrApi /** * Validate fields before creating an object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * * @throws RestException diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php index 4f8435c3a1d..2dd2a609e63 100644 --- a/htdocs/adherents/class/api_subscriptions.class.php +++ b/htdocs/adherents/class/api_subscriptions.class.php @@ -80,11 +80,12 @@ class Subscriptions extends DolibarrApi * @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.import_key:<:'20160101')" * @return array Array of subscription objects * * @throws RestException */ - function index($sortfield = "dateadh", $sortorder = 'ASC', $limit = 0, $page = 0) { + function index($sortfield = "dateadh", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -94,15 +95,19 @@ class Subscriptions extends DolibarrApi } $sql = "SELECT rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."subscription"; - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + $sql.= " FROM ".MAIN_DB_PREFIX."subscription as t"; + $sql.= ' WHERE 1 = 1'; + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) @@ -225,7 +230,7 @@ class Subscriptions extends DolibarrApi /** * Validate fields before creating an object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * * @throws RestException diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index d3efef9dadc..8142b564c1e 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -1,6 +1,6 @@ - * Copyright (C) 2005-2010 Laurent Destailleur + * Copyright (C) 2005-2016 Laurent Destailleur * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin * Copyright (C) 2015 Jean-François Ferry @@ -43,8 +43,16 @@ if ($action == 'setproductionmode') if (dolibarr_set_const($db, 'API_PRODUCTION_MODE', $status, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; + $result = dol_mkdir($conf->api->dir_temp); + if ($result < 0) + { + setEventMessages($langs->trans("ErrorFaildToCreateDir", $conf->api->dir_temp), null, 'errors'); + } + else + { + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } } else { @@ -71,7 +79,7 @@ print ''; print ''; print ""; -print ""; +print '"; print ""; print ""; diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index a1660be133d..1eacdffa167 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -162,4 +162,60 @@ class DolibarrApi return checkUserAccessToObject(DolibarrApiAccess::$user, $featuresarray,$resource_id,$dbtablename,$feature2,$dbt_keyfield,$dbt_select); } + + /** + * Return if a $sqlfilters parameter is valid + * + * @param string $sqlfilters sqlfilter string + * @return boolean True if valid, False if not valid + */ + function _checkFilters($sqlfilters) + { + //$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + //$tmp=preg_replace_all('/'.$regexstring.'/', '', $sqlfilters); + $tmp=$sqlfilters; + $ok=0; + $i=0; $nb=count($tmp); + $counter=0; + while ($i < $nb) + { + if ($tmp[$i]=='(') $counter++; + if ($tmp[$i]==')') $counter--; + if ($counter < 0) + { + $error="Bad sqlfilters=".$sqlfilters; + dol_syslog($error, LOG_WARNING); + return false; + } + $i++; + } + return true; + } + + /** + * Function to forge a SQL criteria + * + * @param array $matches Array of found string by regex search + * @return string Forged criteria. Example: "t.field like 'abc%'" + */ + protected static function _forge_criteria_callback($matches) + { + global $db; + + //dol_syslog("Convert matches ".$matches[1]); + if (empty($matches[1])) return ''; + $tmp=explode(':',$matches[1]); + if (count($tmp) < 3) return ''; + + $tmpescaped=$tmp[2]; + if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) + { + $tmpescaped = "'".$db->escape($regbis[1])."'"; + } + else + { + $tmpescaped = $db->escape($tmpescaped); + } + return $db->escape($tmp[0]).' '.strtoupper($db->escape($tmp[1]))." ".$tmpescaped; + } } diff --git a/htdocs/api/class/api_dictionnarycountries.class.php b/htdocs/api/class/api_dictionnarycountries.class.php index 0243d27c81b..9b7b409ef19 100644 --- a/htdocs/api/class/api_dictionnarycountries.class.php +++ b/htdocs/api/class/api_dictionnarycountries.class.php @@ -54,27 +54,31 @@ class DictionnaryCountries extends DolibarrApi * @param int $page Page number (starting from zero) * @param string $filter To filter the countries by name * @param string $lang Code of the language the label of the countries must be translated to + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" * @return List of countries * * @throws RestException */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '') + function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '') { $list = array(); // Note: The filter is not applied in the SQL request because it must // be applied to the translated names, not to the names in database. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country"; - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t"; + $sql.=" WHERE 1 = 1"; + // Add sql filters + if ($sqlfilters) { - $result = $this->db->query($sql); - $nbtotalofrecords = $this->db->num_rows($result); + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql.= $this->db->order($sortfield, $sortorder); - if ($limit) { if ($page < 0) { diff --git a/htdocs/api/class/api_dictionnarytowns.class.php b/htdocs/api/class/api_dictionnarytowns.class.php index b028ff4af03..b5813d07792 100644 --- a/htdocs/api/class/api_dictionnarytowns.class.php +++ b/htdocs/api/class/api_dictionnarytowns.class.php @@ -47,27 +47,32 @@ class DictionnaryTowns extends DolibarrApi * @param int $page Page number (starting from zero) * @param string $zipcode To filter on zipcode * @param string $town To filter on city name + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" * @return List of towns * * @throws RestException */ - function index($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '') + function index($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $sqlfilters = '') { $list = array(); $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown"; - $sql.= " WHERE active = 1"; - if ($zipcode) $sql.=" AND zip LIKE '%" . $this->db->escape($zipcode) . "%'"; - if ($town) $sql.=" AND town LIKE '%" . $this->db->escape($town) . "%'"; - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; + $sql.= " WHERE t.active = 1"; + if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; + if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; + // Add sql filters + if ($sqlfilters) { - $result = $this->db->query($sql); - $nbtotalofrecords = $this->db->num_rows($result); + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } + $sql.= $this->db->order($sortfield, $sortorder); if ($limit) { diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index bea6061e0fe..616ffcc31cd 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -98,11 +98,12 @@ class Categories extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $type Type of category ('member', 'customer', 'supplier', 'product', 'contact') - * @return array Array of category objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of category objects * * @throws RestException */ - function index($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $type = '') { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $type = '', $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -111,21 +112,24 @@ class Categories extends DolibarrApi throw new RestException(401); } - $sql = "SELECT s.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."categorie as s"; - $sql.= ' WHERE s.entity IN ('.getEntity('categorie', 1).')'; + $sql = "SELECT t.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."categorie as t"; + $sql.= ' WHERE t.entity IN ('.getEntity('categorie', 1).')'; if (!empty($type)) { - $sql.= ' AND s.type='.array_search($type,Categories::$TYPES); + $sql.= ' AND t.type='.array_search($type,Categories::$TYPES); } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) @@ -258,6 +262,7 @@ class Categories extends DolibarrApi if(! DolibarrApiAccess::$user->rights->categorie->creer) { throw new RestException(401); } + // Check mandatory fields $result = $this->_validate($request_data); @@ -337,7 +342,7 @@ class Categories extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * * @throws RestException diff --git a/htdocs/categories/class/api_deprecated_category.class.php b/htdocs/categories/class/api_deprecated_category.class.php index e18ada34e0a..106927a1a33 100644 --- a/htdocs/categories/class/api_deprecated_category.class.php +++ b/htdocs/categories/class/api_deprecated_category.class.php @@ -471,7 +471,7 @@ class CategoryApi extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * * @throws RestException diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 3ab4e7dd898..721e5db7f83 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1102,13 +1102,17 @@ class ActionComm extends CommonObject * @param string $classname Force style class on a link * @param string $option ''=Link to action, 'birthday'=Link to contact * @param int $overwritepicto 1=Overwrite picto + * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ - function getNomUrl($withpicto=0,$maxlength=0,$classname='',$option='',$overwritepicto=0) + function getNomUrl($withpicto=0,$maxlength=0,$classname='',$option='',$overwritepicto=0, $notooltip=0) { - global $conf,$langs, $hookmanager; + global $conf, $langs, $user, $hookmanager; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + $result=''; + $tooltip = '' . $langs->trans('ShowAction'.$objp->code) . ''; if (! empty($this->ref)) $tooltip .= '
' . $langs->trans('Ref') . ': ' . $this->ref; @@ -1118,27 +1122,43 @@ class ActionComm extends CommonObject $tooltip .= '
' . $langs->trans('Title') . ': ' . $label; if (! empty($this->location)) $tooltip .= '
' . $langs->trans('Location') . ': ' . $this->location; - + + $linkclose=''; if (! empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color) - $linkclose = ' style="background-color:#'.$this->type_color.'" class="'.$classname.' classfortooltip" title="'.dol_escape_htmltag($tooltip, 1).'">'; - else - $linkclose = ' class="'.$classname.' classfortooltip" title="'.dol_escape_htmltag($tooltip, 1).'">'; + $linkclose = ' style="background-color:#'.$this->type_color.'"'; - if (! is_object($hookmanager)) + if (empty($notooltip) && $user->rights->propal->lire) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowSupplierProposal"); + $linkclose.=' alt="'.dol_escape_htmltag($tooltip, 1).'"'; + } + $linkclose.=' title="'.dol_escape_htmltag($tooltip, 1).'"'; + $linkclose.=' class="'.$classname.' classfortooltip"'; + + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('actiondao')); + $parameters=array('id'=>$this->id); + $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + $linkclose = ($hookmanager->resPrint ? $hookmanager->resPrint : $linkclose); } - $hookmanager->initHooks(array('actiondao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - $linkclose = ($hookmanager->resPrint ? $hookmanager->resPrint : $linkclose); - + else $linkclose.=' class="'.$classname.'"'; + + $url=''; if ($option=='birthday') - $link = 'id; else - $link = 'id; + + $linkstart = ''; $linkend=''; + //print 'rrr'.$this->libelle.'-'.$withpicto; if ($withpicto == 2) @@ -1161,10 +1181,10 @@ class ActionComm extends CommonObject { $libelle.=(($this->type_code && $libelle!=$langs->transnoentities("Action".$this->type_code) && $langs->transnoentities("Action".$this->type_code)!="Action".$this->type_code)?' ('.$langs->transnoentities("Action".$this->type_code).')':''); } - $result.=$link.img_object($langs->trans("ShowAction").': '.$libelle, ($overwritepicto?$overwritepicto:'action'), 'class="classfortooltip"').$linkend; + $result.=$linkstart.img_object(($notooltip?'':$langs->trans("ShowAction").': '.$libelle), ($overwritepicto?$overwritepicto:'action'), ($notooltip?'':'class="classfortooltip"')).$linkend; } if ($withpicto==1) $result.=' '; - $result.=$link.$libelleshort.$linkend; + $result.=$linkstart.$libelleshort.$linkend; return $result; } diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php index c245476bdcc..db828656966 100644 --- a/htdocs/comm/action/class/api_agendaevents.class.php +++ b/htdocs/comm/action/class/api_agendaevents.class.php @@ -94,10 +94,10 @@ class AgendaEvents extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $user_ids User ids filter field (owners of event). Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * - * @return array Array of Agenda Events objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of Agenda Events objects */ - function index($sortfield = "t.id", $sortorder = 'ASC', $limit = 0, $page = 0, $user_ids = 0) { + function index($sortfield = "t.id", $sortorder = 'ASC', $limit = 0, $page = 0, $user_ids = 0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -108,21 +108,23 @@ class AgendaEvents extends DolibarrApi $sql = "SELECT t.id as rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as t"; $sql.= ' WHERE t.entity IN ('.getEntity('actioncomm', 1).')'; - if ($user_ids) $sql.=" AND ar.fk_user_action IN (".$user_ids.")"; - + if ($user_ids) $sql.=" AND t.fk_user_action IN (".$user_ids.")"; // Insert sale filter if ($search_sale > 0) { $sql .= " AND sc.fk_user = ".$search_sale; } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 95698154870..84a7a1a1a1c 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -90,10 +90,10 @@ class Proposals extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $thirdparty_ids Thirdparty ids to filter commercial proposal of. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * - * @return array Array of order objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of order objects */ - function index($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '') { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '', $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -103,30 +103,32 @@ class Proposals extends DolibarrApi // If the internal user must only see his customers, force searching by him if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; - $sql = "SELECT s.rowid"; + $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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."propal as s"; + $sql.= " FROM ".MAIN_DB_PREFIX."propal as t"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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.= ' WHERE s.entity IN ('.getEntity('propal', 1).')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc"; - if ($socids) $sql.= " AND s.fk_soc IN (".$socids.")"; - if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + $sql.= ' WHERE t.entity IN ('.getEntity('propal', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql.= " AND t.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; } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 8df81f942ed..df2c1cef9fc 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3214,44 +3214,67 @@ class Propal extends CommonObject * @param int $withpicto Add picto into link * @param string $option Where point the link ('expedition', 'document', ...) * @param string $get_params Parametres added to url + * @param int $notooltip 1=Disable tooltip * @return string String with URL */ - function getNomUrl($withpicto=0,$option='', $get_params='') + function getNomUrl($withpicto=0,$option='', $get_params='', $notooltip=0) { - global $langs, $conf; + global $langs, $conf, $user; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + $result=''; - $label = '' . $langs->trans("ShowPropal") . ''; - if (! empty($this->ref)) - $label.= '
'.$langs->trans('Ref').': '.$this->ref; - if (! empty($this->ref_client)) - $label.= '
'.$langs->trans('RefCustomer').': '.$this->ref_client; - if (! empty($this->total_ht)) - $label.= '
' . $langs->trans('AmountHT') . ': ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_tva)) - $label.= '
' . $langs->trans('VAT') . ': ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_ttc)) - $label.= '
' . $langs->trans('AmountTTC') . ': ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; - if ($option == '') { - $link = ''; + if (! empty($this->ref)) + $label.= '
'.$langs->trans('Ref').': '.$this->ref; + if (! empty($this->ref_client)) + $label.= '
'.$langs->trans('RefCustomer').': '.$this->ref_client; + if (! empty($this->total_ht)) + $label.= '
' . $langs->trans('AmountHT') . ': ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_tva)) + $label.= '
' . $langs->trans('VAT') . ': ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_ttc)) + $label.= '
' . $langs->trans('AmountTTC') . ': ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + if ($option == '') { + $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$this->id. $get_params; + } + if ($option == 'compta') { // deprecated + $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$this->id. $get_params; + } + if ($option == 'expedition') { + $url = DOL_URL_ROOT.'/expedition/propal.php?id='.$this->id. $get_params; + } + if ($option == 'document') { + $url = DOL_URL_ROOT.'/comm/propal/document.php?id='.$this->id. $get_params; + } } - if ($option == 'compta') { // deprecated - $link = '
rights->propal->lire) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowPropal"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; } + + $linkstart = ''; $linkend=''; if ($withpicto) - $result.=($link.img_object($label, $this->picto, 'class="classfortooltip"').$linkend); + $result.=($linkstart.img_object(($notooltip?'':$label), $this->picto, ($notooltip?'':'class="classfortooltip"')).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - $result.=$link.$this->ref.$linkend; + $result.=$linkstart.$this->ref.$linkend; return $result; } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 6ba66a78013..f000e4ce201 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -80,20 +80,22 @@ class Orders extends DolibarrApi return $this->_cleanObjectDatas($this->commande); } + + /** * List orders * * Get a list of orders * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $thirdparty_ids Thirdparty ids to filter orders of. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * - * @return array Array of order objects + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter orders of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of order objects */ - function index($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '') { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -103,30 +105,32 @@ class Orders extends DolibarrApi // If the internal user must only see his customers, force searching by him if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; - $sql = "SELECT s.rowid"; + $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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."commande as s"; + $sql.= " FROM ".MAIN_DB_PREFIX."commande as t"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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.= ' WHERE s.entity IN ('.getEntity('commande', 1).')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc"; - if ($socids) $sql.= " AND s.fk_soc IN (".$socids.")"; - if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + $sql.= ' WHERE t.entity IN ('.getEntity('commande', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql.= " AND t.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; } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) @@ -138,6 +142,7 @@ class Orders extends DolibarrApi $sql.= $db->plimit($limit + 1, $offset); } + dol_syslog("API Rest request"); $result = $db->query($sql); if ($result) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 49092d6e58e..1d46b62d8d0 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3326,12 +3326,15 @@ class Commande extends CommonOrder * @param int $option Where point the link (0=> main card, 1,2 => shipment) * @param int $max Max length to show * @param int $short Use short labels + * @param int $notooltip 1=Disable tooltip * @return string String with URL */ - function getNomUrl($withpicto=0,$option=0,$max=0,$short=0) + function getNomUrl($withpicto=0,$option=0,$max=0,$short=0,$notooltip=0) { global $conf, $langs, $user; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + $result=''; if (! empty($conf->expedition->enabled) && ($option == 1 || $option == 2)) $url = DOL_URL_ROOT.'/expedition/shipment.php?id='.$this->id; @@ -3351,23 +3354,33 @@ class Commande extends CommonOrder $label .= '
'.$langs->trans('RefCustomer').': '.$this->ref_client; } if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, - $conf->currency); + $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); } if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, - $conf->currency); + $label .= '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); } if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, - $conf->currency); + $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); } } - $linkstart = ''; + $linkclose=''; + if (empty($notooltip) && $user->rights->commande->lire) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowOrder"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; + } + + $linkstart = ''; $linkend=''; - if ($withpicto) $result.=($linkstart.img_object($label, $picto, 'class="classfortooltip"').$linkend); + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"')).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; $result.=$linkstart.$this->ref.$linkend; return $result; diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 250faea5a5d..7de67119d2b 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -56,11 +56,12 @@ class BankAccounts extends DolibarrApi * @param string $sortorder Sort order * @param int $limit Limit for list * @param int $page Page number - * @return array List of account objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.import_key:<:'20160101')" + * @return array List of account objects * * @throws RestException */ - function index($sortfield = "rowid", $sortorder = 'ASC', $limit = 0, $page = 0) + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') { $list = array(); @@ -68,13 +69,17 @@ class BankAccounts extends DolibarrApi throw new RestException(401); } - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank_account"; - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank_account as t"; + $sql.= ' WHERE t.entity IN ('.getEntity('banque', 1).')'; + // Add sql filters + if ($sqlfilters) { - $result = $this->db->query($sql); - $nbtotalofrecords = $this->db->num_rows($result); + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql.= $this->db->order($sortfield, $sortorder); @@ -88,6 +93,7 @@ class BankAccounts extends DolibarrApi $sql.= $this->db->plimit($limit + 1, $offset); } + dol_syslog("API Rest request"); $result = $this->db->query($sql); if ($result) { @@ -100,7 +106,7 @@ class BankAccounts extends DolibarrApi } } } else { - throw new RestException(503, 'Error when retrieving list of accounts: ' . $account->error); + throw new RestException(503, 'Error when retrieving list of accounts: ' . $this->db->lasterror()); } return $list; @@ -220,7 +226,7 @@ class BankAccounts extends DolibarrApi /** * Validate fields before creating an object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * * @throws RestException diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index e3951b4dca7..0b2b7f58781 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -89,11 +89,12 @@ class Invoices extends DolibarrApi * @param int $page Page number * @param int $socid Filter list with thirdparty ID * @param string $status Filter by invoice status : draft | unpaid | paid | cancelled - * @return array Array of invoice objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of invoice objects * * @throws RestException */ - function index($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $socid=0, $status='') { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $socid=0, $status='', $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -103,38 +104,38 @@ class Invoices extends DolibarrApi // 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"; + $sql = "SELECT t.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."facture as s"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as t"; 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.= ' WHERE s.entity IN ('.getEntity('facture', 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 - + $sql.= ' WHERE t.entity IN ('.getEntity('facture', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($socid) $sql.= " AND t.fk_soc = ".$socid; + if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale // Filter by status - if ($status == 'draft') $sql.= " AND s.fk_statut IN (0)"; - if ($status == 'unpaid') $sql.= " AND s.fk_statut IN (1)"; - if ($status == 'paid') $sql.= " AND s.fk_statut IN (2)"; - if ($status == 'cancelled') $sql.= " AND s.fk_statut IN (3)"; - + if ($status == 'draft') $sql.= " AND t.fk_statut IN (0)"; + if ($status == 'unpaid') $sql.= " AND t.fk_statut IN (1)"; + if ($status == 'paid') $sql.= " AND t.fk_statut IN (2)"; + if ($status == 'cancelled') $sql.= " AND t.fk_statut IN (3)"; // Insert sale filter if ($search_sale > 0) { $sql .= " AND sc.fk_user = ".$search_sale; } - - // TODO remove this, useless for WS - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index bea5571730f..7171e06c7ee 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -998,12 +998,15 @@ class Facture extends CommonInvoice * @param int $max Maxlength of ref * @param int $short 1=Return just URL * @param string $moretitle Add more text to title tooltip + * @param int $notooltip 1=Disable tooltip * @return string String with URL */ - function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='') + function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='',$notooltip=0) { global $langs, $conf; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + $result=''; if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; @@ -1015,28 +1018,44 @@ class Facture extends CommonInvoice if ($this->type == self::TYPE_REPLACEMENT) $picto.='r'; // Replacement invoice if ($this->type == self::TYPE_CREDIT_NOTE) $picto.='a'; // Credit note if ($this->type == self::TYPE_DEPOSIT) $picto.='d'; // Deposit invoice - - $label = '' . $langs->trans("ShowInvoice") . ''; - if (! empty($this->ref)) - $label .= '
'.$langs->trans('Ref') . ': ' . $this->ref; - if (! empty($this->ref_client)) - $label .= '
' . $langs->trans('RefCustomer') . ': ' . $this->ref_client; - if (! empty($this->total_ht)) - $label.= '
' . $langs->trans('AmountHT') . ': ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_tva)) - $label.= '
' . $langs->trans('VAT') . ': ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_ttc)) - $label.= '
' . $langs->trans('AmountTTC') . ': ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - if ($this->type == self::TYPE_REPLACEMENT) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref; - if ($this->type == self::TYPE_CREDIT_NOTE) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; - if ($this->type == self::TYPE_DEPOSIT) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; - if ($this->type == self::TYPE_SITUATION) $label=$langs->transnoentitiesnoconv("ShowInvoiceSituation").': '.$this->ref; - if ($moretitle) $label.=' - '.$moretitle; - - $linkstart=''; + $label=''; + + if ($user->rights->facture->lire) { + $label = '' . $langs->trans("ShowInvoice") . ''; + if (! empty($this->ref)) + $label .= '
'.$langs->trans('Ref') . ': ' . $this->ref; + if (! empty($this->ref_client)) + $label .= '
' . $langs->trans('RefCustomer') . ': ' . $this->ref_client; + if (! empty($this->total_ht)) + $label.= '
' . $langs->trans('AmountHT') . ': ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_tva)) + $label.= '
' . $langs->trans('VAT') . ': ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_ttc)) + $label.= '
' . $langs->trans('AmountTTC') . ': ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + if ($this->type == self::TYPE_REPLACEMENT) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref; + if ($this->type == self::TYPE_CREDIT_NOTE) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; + if ($this->type == self::TYPE_DEPOSIT) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; + if ($this->type == self::TYPE_SITUATION) $label=$langs->transnoentitiesnoconv("ShowInvoiceSituation").': '.$this->ref; + if ($moretitle) $label.=' - '.$moretitle; + } + + $linkclose=''; + if (empty($notooltip) && $user->rights->facture->lire) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowInvoice"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; + } + + $linkstart='
'; $linkend=''; - if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label), $picto, 'class="classfortooltip"').$linkend); + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"')).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend; return $result; diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 5ad8b3aa646..ef750e70253 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -81,7 +81,7 @@ class DolEditor // Check if extended editor is ok. If not we force textarea if (empty($conf->fckeditor->enabled) || ! $okforextendededitor) $this->tool = 'textarea'; - //if ($conf->browser->phone) $this->tool = 'textarea'; + if ($conf->dol_use_jmobile) $this->tool = 'textarea'; // TODO ckeditor ko with jmobile // Define content and some properties if ($this->tool == 'ckeditor') diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index da63720a69c..bb022b7767c 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -512,15 +512,16 @@ class Form if (count($arrayofaction) == 0) return; $disabled=0; - $ret='
'; $ret.=''; foreach($arrayofaction as $code => $label) { $ret.=''; } $ret.=''; - // Warning: if you set submit button to disabled, post using Enter will no more work - $ret.=''; + // Warning: if you set submit button to disabled, post using 'Enter' will no more work. + $ret.=''; $ret.='
'; $ret.=' diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 2724d64f17f..6f01a4c1406 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -268,7 +268,8 @@ class Utils { $i++; // output line number $read = fgets($handlein); - if ($i == 1 && preg_match('/'.preg_quote('Warning: Using a password').'/i', $read)) continue; + // Exclude warning line we don't want + if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; fwrite($handle,$read); if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 921571a478c..9c7e5f0330b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7,7 +7,7 @@ * Copyright (C) 2004 Christophe Combelles * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2008 Raphael Bertrand (Resultic) - * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2010-2016 Juanjo Menent * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2013 Alexandre Spangaro * Copyright (C) 2014 Cédric GROSS @@ -2500,9 +2500,9 @@ function img_printer($titlealt = "default", $other='') /** * Show help logo with cursor "?" * - * @param string $usehelpcursor Use help cursor - * @param string $usealttitle Text to use as alt title - * @return string Retourne tag img + * @param int $usehelpcursor Use help cursor + * @param int|string $usealttitle Text to use as alt title + * @return string Return tag img */ function img_help($usehelpcursor = 1, $usealttitle = 1) { @@ -3600,7 +3600,7 @@ function get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller $vatratecleaned = $vatrate; if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) // If vat is "xx (yy)" { - $vatratecleaned = $reg[1]; + $vatratecleaned = trim($reg[1]); $vatratecode = $reg[2]; } @@ -3614,7 +3614,7 @@ function get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller { if ($local == 1) { - if (! $mysoc->localtax1_assuj) return 0; + if (! $mysoc->localtax1_assuj || (string) $vatratecleaned == "0") return 0; if ($thirdparty_seller->id == $mysoc->id) { if (! $thirdparty_buyer->localtax1_assuj) return 0; @@ -3627,7 +3627,7 @@ function get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller if ($local == 2) { - if (! $mysoc->localtax2_assuj) return 0; + if (! $mysoc->localtax2_assuj || (string) $vatratecleaned == "0") return 0; if ($thirdparty_seller->id == $mysoc->id) { if (! $thirdparty_buyer->localtax2_assuj) return 0; @@ -3899,7 +3899,7 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi * @param int $idprod Id of product or 0 if not a predefined product * @param Societe $thirdparty_seller Thirdparty with a ->country_code defined (FR, US, IT, ...) * @param int $idprodfournprice Id product_fournisseur_price (for "supplier" order/invoice) - * @return int <0 if KO, Vat rate if OK + * @return float Vat rate * @see get_product_localtax_for_country */ function get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice=0) @@ -4049,7 +4049,7 @@ function get_product_localtax_for_country($idprod, $local, $thirdparty_seller) * @param Societe $thirdparty_buyer Objet societe acheteuse * @param int $idprod Id product * @param int $idprodfournprice Id product_fournisseur_price (for supplier order/invoice) - * @return float Taux de tva a appliquer, -1 si ne peut etre determine + * @return float Vat rate to use, -1 if we can't guess it * @see get_default_npr, get_default_localtax */ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0) @@ -4598,7 +4598,7 @@ function dol_nboflines_bis($text,$maxlinesize=0,$charset='UTF-8') else $pattern = '/(]*>)/U'; // /U is to have UNGREEDY regex to limit to one html tag. $a = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); - $nblines = floor((count($a)+1)/2); + $nblines = (int) floor((count($a)+1)/2); // count possible auto line breaks if($maxlinesize) { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 7b5e5d98d9d..124aaa2adca 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -942,46 +942,46 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/accountancy/index.php?leftmenu=accountancy",$langs->trans("MenuAccountancy"), 0, $permtoshowmenu, '', $mainmenu, 'accountancy'); // Chart of account - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/index.php?leftmenu=accountancy_admin", $langs->trans("Setup"),1,$user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin', 1); - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/accountmodel.php?id=31&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Pcg_version"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chartmodel', 10); - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Chartofaccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 20); - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 40); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/index.php?leftmenu=accountancy_admin", $langs->trans("Setup"),1,$user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin', 1); + if (empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/accountmodel.php?id=31&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Pcg_version"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chartmodel', 10); + if (empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Chartofaccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 20); + if (empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 40); if (! empty($conf->facture->enabled) || ! empty($conf->fournisseur->enabled)) { - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=10&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuVatAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 30); + if (empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=10&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuVatAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 30); } if (! empty($conf->tax->enabled)) { - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=7&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuTaxAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 30); + if (empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=7&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuTaxAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 30); } if (! empty($conf->loan->enabled)) { - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/loan.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuLoanAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_loan', 45); + if (empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/loan.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuLoanAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_loan', 45); } /* not required yet, already supported by default account if (! empty($conf->don->enabled)) { if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/don/admin/donation.php?from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDonationAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_donation', 47); }*/ - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuProductsAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_product', 50); + if (empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuProductsAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_product', 50); // Binding - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/customer/index.php?leftmenu=accountancy_dispatch_customer&mainmenu=accountancy",$langs->trans("CustomersVentilation"),1,$user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_customer'); - if (preg_match('/accountancy_dispatch_customer/',$leftmenu)) $newmenu->add("/accountancy/customer/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer",$langs->trans("ToBind"),2,$user->rights->accounting->bind->write); - if (preg_match('/accountancy_dispatch_customer/',$leftmenu)) $newmenu->add("/accountancy/customer/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer",$langs->trans("Binded"),2,$user->rights->accounting->bind->write); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/customer/index.php?leftmenu=accountancy_dispatch_customer&mainmenu=accountancy",$langs->trans("CustomersVentilation"),1,$user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_customer'); + if (empty($leftmenu) || preg_match('/accountancy_dispatch_customer/',$leftmenu)) $newmenu->add("/accountancy/customer/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer",$langs->trans("ToBind"),2,$user->rights->accounting->bind->write); + if (empty($leftmenu) || preg_match('/accountancy_dispatch_customer/',$leftmenu)) $newmenu->add("/accountancy/customer/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer",$langs->trans("Binded"),2,$user->rights->accounting->bind->write); if (! empty($conf->supplier_invoice->enabled)) { - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/supplier/index.php?leftmenu=accountancy_dispatch_supplier&mainmenu=accountancy",$langs->trans("SuppliersVentilation"),1,$user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_supplier'); - if (preg_match('/accountancy_dispatch_supplier/',$leftmenu)) $newmenu->add("/accountancy/supplier/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier",$langs->trans("ToBind"),2,$user->rights->accounting->bind->write); - if (preg_match('/accountancy_dispatch_supplier/',$leftmenu)) $newmenu->add("/accountancy/supplier/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier",$langs->trans("Binded"),2,$user->rights->accounting->bind->write); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/supplier/index.php?leftmenu=accountancy_dispatch_supplier&mainmenu=accountancy",$langs->trans("SuppliersVentilation"),1,$user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_supplier'); + if (empty($leftmenu) || preg_match('/accountancy_dispatch_supplier/',$leftmenu)) $newmenu->add("/accountancy/supplier/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier",$langs->trans("ToBind"),2,$user->rights->accounting->bind->write); + if (empty($leftmenu) || preg_match('/accountancy_dispatch_supplier/',$leftmenu)) $newmenu->add("/accountancy/supplier/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier",$langs->trans("Binded"),2,$user->rights->accounting->bind->write); } // Journals if(! empty($conf->accounting->enabled) && ! empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add('',$langs->trans("Journalization"),1,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('',$langs->trans("Journalization"),1,$user->rights->accounting->comptarapport->lire); $sql = "SELECT rowid, label, accountancy_journal"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; @@ -999,7 +999,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu while ($i < $numr) { $objp = $db->fetch_object($resql); - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/bankjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_account='.$objp->rowid,$langs->trans("Journal").' - '.dol_trunc($objp->label,10),2,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/bankjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_account='.$objp->rowid,$langs->trans("Journal").' - '.dol_trunc($objp->label,10),2,$user->rights->accounting->comptarapport->lire); $i++; } } @@ -1007,33 +1007,33 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $db->free($resql); // Add other journal - if (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 (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 (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 (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); } // General Ledger - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/bookkeeping/list.php?mainmenu=accountancy",$langs->trans("Bookkeeping"),1,$user->rights->accounting->mouvements->lire); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/bookkeeping/list.php?mainmenu=accountancy&leftmenu=accountancy_generalledger",$langs->trans("Bookkeeping"),1,$user->rights->accounting->mouvements->lire); // Balance - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/bookkeeping/balance.php?mainmenu=accountancy",$langs->trans("AccountBalance"),1,$user->rights->accounting->mouvements->lire); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_balance",$langs->trans("AccountBalance"),1,$user->rights->accounting->mouvements->lire); // Reports $langs->load("compta"); - if (preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/report/result.php?leftmenu=accountancy_report&mainmenu=accountancy",$langs->trans("Reportings"),1,$user->rights->accounting->comptarapport->lire, '', $mainmenu, 'ca'); + if (empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/report/result.php?mainmenu=accountancy&leftmenu=accountancy_report",$langs->trans("Reportings"),1,$user->rights->accounting->comptarapport->lire, '', $mainmenu, 'ca'); - if (preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/accountancy/report/result.php?leftmenu=accountancy_report",$langs->trans("ReportInOut"),2,$user->rights->accounting->comptarapport->lire); - if (preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/resultat/index.php?leftmenu=accountancy_report",$langs->trans("ByExpenseIncome"),3,$user->rights->accounting->comptarapport->lire); - if (preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=accountancy_report",$langs->trans("ByCompanies"),3,$user->rights->accounting->comptarapport->lire); - if (preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report",$langs->trans("ReportTurnover"),2,$user->rights->accounting->comptarapport->lire); - if (preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report",$langs->trans("ByCompanies"),3,$user->rights->accounting->comptarapport->lire); - if (preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report",$langs->trans("ByUsers"),3,$user->rights->accounting->comptarapport->lire); - if (preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=accountancy_report", $langs->trans("ByProductsAndServices"),3,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/accountancy/report/result.php?leftmenu=accountancy_report",$langs->trans("ReportInOut"),2,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/resultat/index.php?leftmenu=accountancy_report",$langs->trans("ByExpenseIncome"),3,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=accountancy_report",$langs->trans("ByCompanies"),3,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report",$langs->trans("ReportTurnover"),2,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report",$langs->trans("ByCompanies"),3,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report",$langs->trans("ByUsers"),3,$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || preg_match('/accountancy_report/',$leftmenu)) $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=accountancy_report", $langs->trans("ByProductsAndServices"),3,$user->rights->accounting->comptarapport->lire); // Fiscal year if ($conf->global->MAIN_FEATURES_LEVEL > 0) // Not yet used. In a future will lock some periods. { - if (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 (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'); } } diff --git a/htdocs/core/menus/standard/eldy_menu.php b/htdocs/core/menus/standard/eldy_menu.php index db1a7b8392f..0b876899272 100644 --- a/htdocs/core/menus/standard/eldy_menu.php +++ b/htdocs/core/menus/standard/eldy_menu.php @@ -152,9 +152,10 @@ class MenuManager if ($mode == 'jmobile') { - print_eldy_menu($this->db,$this->atarget,$this->type_user,$this->tabMenu,$this->menu,1,$mode); // Fill this->menu that is empty with top menu - + + // $this->menu->liste is top menu + //var_dump($this->menu->liste);exit; print ''."\n"; foreach($this->menu->liste as $key => $val) // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu' { @@ -168,14 +169,15 @@ class MenuManager $relurl=preg_replace('/__USERID__/',$user->id,$relurl); print ''.$val['titre'].''."\n"; - // Search submenu fot this entry + // Search submenu fot this mainmenu entry $tmpmainmenu=$val['mainmenu']; $tmpleftmenu='all'; $submenu=new Menu(); print_left_eldy_menu($this->db,$this->menu_array,$this->menu_array_after,$this->tabMenu,$submenu,1,$tmpmainmenu,$tmpleftmenu); // Fill $submenu (example with tmpmainmenu='home' tmpleftmenu='all', return left menu tree of Home) - //if ($tmpmainmenu.'-'.$tmpleftmenu == 'home-all') { var_dump($submenu);exit; } + //if ($tmpmainmenu.'-'.$tmpleftmenu == 'home-all') { var_dump($submenu); exit; } + //if ($tmpmainmenu=='accountancy') { var_dump($submenu->liste); exit; } $nexturl=dol_buildpath($submenu->liste[0]['url'],1); - + $canonrelurl=preg_replace('/\?.*$/','',$relurl); $canonnexturl=preg_replace('/\?.*$/','',$nexturl); //var_dump($canonrelurl); diff --git a/htdocs/core/modules/export/export_excel.modules.php b/htdocs/core/modules/export/export_excel.modules.php index 91f78522973..00d06e8511a 100644 --- a/htdocs/core/modules/export/export_excel.modules.php +++ b/htdocs/core/modules/export/export_excel.modules.php @@ -64,24 +64,27 @@ class ExportExcel extends ModeleExports $this->picto='mime/xls'; // Picto $this->version='1.30'; // Driver version - // If driver use an external library, put its name here - if (! empty($conf->global->MAIN_USE_PHP_WRITEEXCEL)) - { - require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_workbookbig.inc.php'; - require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_worksheet.inc.php'; - require_once PHP_WRITEEXCEL_PATH.'functions.writeexcel_utility.inc.php'; - $this->label_lib='PhpWriteExcel'; - $this->version_lib='unknown'; - } - else - { - require_once PHPEXCEL_PATH.'PHPExcel.php'; - require_once PHPEXCEL_PATH.'PHPExcel/Style/Alignment.php'; - $this->label_lib='PhpExcel'; - $this->version_lib='1.8.0'; // No way to get info from library - } - $this->disabled = (in_array(constant('PHPEXCEL_PATH'),array('disabled','disabled/'))?1:0); // A condition to disable module (used for native debian packages) + + if (empty($this->disabled)) + { + // If driver use an external library, put its name here + if (! empty($conf->global->MAIN_USE_PHP_WRITEEXCEL)) + { + require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_workbookbig.inc.php'; + require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_worksheet.inc.php'; + require_once PHP_WRITEEXCEL_PATH.'functions.writeexcel_utility.inc.php'; + $this->label_lib='PhpWriteExcel'; + $this->version_lib='unknown'; + } + else + { + require_once PHPEXCEL_PATH.'PHPExcel.php'; + require_once PHPEXCEL_PATH.'PHPExcel/Style/Alignment.php'; + $this->label_lib='PhpExcel'; + $this->version_lib='1.8.0'; // No way to get info from library + } + } $this->row=0; } diff --git a/htdocs/core/modules/export/export_excel2007.modules.php b/htdocs/core/modules/export/export_excel2007.modules.php index dcb649e780d..df9fd9d5705 100644 --- a/htdocs/core/modules/export/export_excel2007.modules.php +++ b/htdocs/core/modules/export/export_excel2007.modules.php @@ -64,25 +64,28 @@ class ExportExcel2007 extends ExportExcel $this->picto='mime/xls'; // Picto $this->version='1.30'; // Driver version - // If driver use an external library, put its name here - if (! empty($conf->global->MAIN_USE_PHP_WRITEEXCEL)) + $this->disabled = (in_array(constant('PHPEXCEL_PATH'),array('disabled','disabled/'))?1:0); // A condition to disable module (used for native debian packages) + + if (empty($this->disabled)) { - require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_workbookbig.inc.php'; - require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_worksheet.inc.php'; - require_once PHP_WRITEEXCEL_PATH.'functions.writeexcel_utility.inc.php'; - $this->label_lib='PhpWriteExcel'; - $this->version_lib='unknown'; - } - else - { - require_once PHPEXCEL_PATH.'PHPExcel.php'; - require_once PHPEXCEL_PATH.'PHPExcel/Style/Alignment.php'; - $this->label_lib='PhpExcel'; - $this->version_lib='1.8.0'; // No way to get info from library + // If driver use an external library, put its name here + if (! empty($conf->global->MAIN_USE_PHP_WRITEEXCEL)) + { + require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_workbookbig.inc.php'; + require_once PHP_WRITEEXCEL_PATH.'class.writeexcel_worksheet.inc.php'; + require_once PHP_WRITEEXCEL_PATH.'functions.writeexcel_utility.inc.php'; + $this->label_lib='PhpWriteExcel'; + $this->version_lib='unknown'; + } + else + { + require_once PHPEXCEL_PATH.'PHPExcel.php'; + require_once PHPEXCEL_PATH.'PHPExcel/Style/Alignment.php'; + $this->label_lib='PhpExcel'; + $this->version_lib='1.8.0'; // No way to get info from library + } } - $this->disabled = (in_array(constant('PHPEXCEL_PATH'),array('disabled','disabled/'))?1:0); // A condition to disable module (used for native debian packages) - $this->row=0; } diff --git a/htdocs/core/modules/export/modules_export.php b/htdocs/core/modules/export/modules_export.php index ee1c3b8e96c..8cbb3850c2b 100644 --- a/htdocs/core/modules/export/modules_export.php +++ b/htdocs/core/modules/export/modules_export.php @@ -65,22 +65,24 @@ class ModeleExports extends CommonDocGenerator // This class can't be abstrac $moduleid=$reg[1]; // Loading Class - $file = $dir."/export_".$moduleid.".modules.php"; + $file = $dir."export_".$moduleid.".modules.php"; $classname = "Export".ucfirst($moduleid); require_once $file; - $module = new $classname($db); - - // Picto - $this->picto[$module->id]=$module->picto; - // Driver properties - $this->driverlabel[$module->id]=$module->getDriverLabel().(empty($module->disabled)?'':' __(Disabled)__'); // '__(Disabled)__' is a key - $this->driverdesc[$module->id]=$module->getDriverDesc(); - $this->driverversion[$module->id]=$module->getDriverVersion(); - // If use an external lib - $this->liblabel[$module->id]=$module->getLibLabel(); - $this->libversion[$module->id]=$module->getLibVersion(); - + if (class_exists($classname)) + { + $module = new $classname($db); + + // Picto + $this->picto[$module->id]=$module->picto; + // Driver properties + $this->driverlabel[$module->id]=$module->getDriverLabel().(empty($module->disabled)?'':' __(Disabled)__'); // '__(Disabled)__' is a key + $this->driverdesc[$module->id]=$module->getDriverDesc(); + $this->driverversion[$module->id]=$module->getDriverVersion(); + // If use an external lib + $this->liblabel[$module->id]=$module->getLibLabel(); + $this->libversion[$module->id]=$module->getLibVersion(); + } $i++; } } diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 61db64e8c97..bce6cd02eee 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -872,8 +872,6 @@ class InterfaceActionsAuto extends DolibarrTriggers dol_syslog("interface_modAgenda_ActionsAuto.class.php: ".$this->error, LOG_ERR); return -1; } - - return 0; } } diff --git a/htdocs/don/list.php b/htdocs/don/list.php index 8c7f5b987be..f5ce8b0350b 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -72,9 +72,7 @@ $fieldstosearchall = array( 'd.lastname'=>'Lastname', 'd.firstname'=>'Firstname', ); - - - + /* * View */ @@ -115,6 +113,12 @@ if (trim($search_name) != '') if ($search_amount) $sql.= natural_search(array('d.amount'), price2num(trim($search_amount)), 1); $sql.= $db->order($sortfield,$sortorder); +$nbtotalofrecords = 0; +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); @@ -124,18 +128,18 @@ if ($resql) $i = 0; $param = '&statut='.$statut; - if ($page > 0) $param.= '&page='.$page; + //if ($page > 0) $param.= '&page='.$page; if ($optioncss != '') $param.='&optioncss='.$optioncss; if ($statut >= 0) { $donationstatic->statut=$statut; $label=$donationstatic->getLibStatut(0); - print_barre_liste($label, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num); + print_barre_liste($langs->trans("Donations"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num,$nbtotalofrecords); } else { - print_barre_liste($langs->trans("Donations"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num); + print_barre_liste($langs->trans("Donations"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num,$nbtotalofrecords); } @@ -200,7 +204,7 @@ if ($resql) $var=True; while ($i < min($num,$limit)) { - $objp = $db->fetch_object($result); + $objp = $db->fetch_object($resql); $var=!$var; print ""; $donationstatic->id=$objp->rowid; diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 34b6a6e20b9..4a6a50c7926 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1967,6 +1967,7 @@ class Expedition extends CommonObject */ function set_billed() { + global $user; $error=0; $this->db->begin(); diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index 298a178f00c..1e4a3d50008 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -91,10 +91,10 @@ class ExpenseReports extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $user_ids User ids filter field. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * - * @return array Array of Expense Report objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of Expense Report objects */ - function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $user_ids = 0) { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $user_ids = 0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -112,14 +112,17 @@ class ExpenseReports extends DolibarrApi { $sql .= " AND sc.fk_user = ".$search_sale; } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 567e2660b94..849e873b96e 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -946,6 +946,7 @@ if ($action == 'create') if ($socid > 0) { + $soc=new Societe($db); $soc->fetch($socid); print ''; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index d34671b9806..9b3de478cc9 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2004 Christophe Combelles * Copyright (C) 2005 Marc Barilley * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2010-2015 Juanjo Menent + * Copyright (C) 2010-2016 Juanjo Menent * Copyright (C) 2013 Philippe Grand * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2016 Marcos García @@ -1440,7 +1440,14 @@ class FactureFournisseur extends CommonInvoice // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type=getLocalTaxesFromRate($vatrate,0,$mysoc, $this->thirdparty); - $vatrate = preg_replace('/\s*\(.*\)/','',$vatrate); // Remove code into vatrate. + + // Clean vat code + $vat_src_code=''; + if (preg_match('/\((.*)\)/', $vatrate, $reg)) + { + $vat_src_code = $reg[1]; + $vatrate = preg_replace('/\s*\(.*\)/', '', $vatrate); // Remove code into vatrate. + } $tabprice = calcul_price_total($qty, $pu, $remise_percent, $vatrate, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx); $total_ht = $tabprice[0]; @@ -1483,7 +1490,7 @@ class FactureFournisseur extends CommonInvoice $line->qty = $qty; $line->remise_percent = $remise_percent; - $this->line->vat_src_code=$vat_src_code; + $line->vat_src_code=$vat_src_code; $line->tva_tx = $vatrate; $line->localtax1_tx = $txlocaltax1; $line->localtax2_tx = $txlocaltax2; diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index bcf000bc3aa..764a875019d 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -349,21 +349,17 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print '
".$langs->trans("Parameter")."".$langs->trans("Value")."'.$langs->trans("Value")." 
'; - print ''; print ''; - print ''; + print ''; print ''; - print ''; - print ''; if (! empty($conf->banque->enabled)) { print ''; + print ''; } + print ''; + print ''; + print ''; print '
'.$langs->trans('Company').''; + print '
'.$langs->trans('Company').''; $supplierstatic->id=$obj->socid; $supplierstatic->name=$obj->name; print $supplierstatic->getNomUrl(1,'supplier'); print '
'.$langs->trans('Date').''; $form->select_date($dateinvoice,'','','','',"addpaiement",1,1,0,0,'','',$object->date); - print ''.$langs->trans('Comments').'
'.$langs->trans('PaymentMode').''; $form->select_types_paiements(empty($_POST['paiementid'])?$obj->fk_mode_reglement:$_POST['paiementid'],'paiementid'); print ''; - print '
'.$langs->trans('Numero').'
'.$langs->trans('Account').''; @@ -372,8 +368,12 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie } else { - print '
 
 
'.$langs->trans('Numero').'
'.$langs->trans('Comments').''; + print '
'; dol_fiche_end(); diff --git a/htdocs/includes/tcpdi/tcpdi_parser.php b/htdocs/includes/tcpdi/tcpdi_parser.php index c97d9c74dac..038994568ac 100644 --- a/htdocs/includes/tcpdi/tcpdi_parser.php +++ b/htdocs/includes/tcpdi/tcpdi_parser.php @@ -48,7 +48,8 @@ */ // include class for decoding filters -require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php'); +if (defined('TCPDF_PATH')) require_once(constant('TCPDF_PATH').'/include/tcpdf_filters.php'); +else require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php'); if (!defined ('PDF_TYPE_NULL')) define ('PDF_TYPE_NULL', 0); 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 74527f33aa1..0f77a358e84 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,3 +166,9 @@ create table llx_resource_extrafields ALTER TABLE llx_resource_extrafields ADD INDEX idx_resource_extrafields (fk_object); INSERT INTO llx_const (name, value, type, note, visible) values ('MAIN_SIZE_SHORTLIST_LIMIT','3','chaine','Max length for small lists (tabs)',0); + + +ALTER TABLE llx_bank_account ADD COLUMN note_public text; +ALTER TABLE llx_bank_account ADD COLUMN model_pdf varchar(255); +ALTER TABLE llx_bank_account ADD COLUMN import_key varchar(14); + diff --git a/htdocs/install/mysql/tables/llx_bank_account.sql b/htdocs/install/mysql/tables/llx_bank_account.sql index 0261bf70b56..7730ab79ef6 100644 --- a/htdocs/install/mysql/tables/llx_bank_account.sql +++ b/htdocs/install/mysql/tables/llx_bank_account.sql @@ -55,5 +55,8 @@ create table llx_bank_account currency_code varchar(3) NOT NULL, min_allowed integer DEFAULT 0, min_desired integer DEFAULT 0, - comment text + comment text, -- TODO rename in note_private + note_public text, + model_pdf varchar(255), + import_key varchar(14) )ENGINE=innodb; diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index 993d800aea3..ec437709487 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -66,7 +66,7 @@ $main_use_alt_dir = ((GETPOST("main_use_alt_dir") && (GETPOST("main_use_alt_dir" // Alternative root directory name $main_alt_dir_name = ((GETPOST("main_alt_dir_name") && GETPOST("main_alt_dir_name") != '') ? GETPOST("main_alt_dir_name") : 'custom'); -session_start(); // To be able to keep info into session (used for not losing password during navigation. The password must not transit through parameters) +session_start(); // To be able to keep info into session (used for not losing password during navigation. The password must not transit through parameters) // Save a flag to tell to restore input value if we do back $_SESSION['dol_save_pass']=$db_pass; diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index e64ae025f1e..a6e21b6ff8c 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -54,6 +54,7 @@ ShipmentValidatedInDolibarr=Shipment %s validated ShipmentClassifyClosedInDolibarr=Shipment %s classify billed ShipmentUnClassifyCloseddInDolibarr=Shipment %s classify reopened ShipmentDeletedInDolibarr=Shipment %s deleted +OrderCreatedInDolibarr=Order %s created OrderValidatedInDolibarr=Order %s validated OrderDeliveredInDolibarr=Order %s classified delivered OrderCanceledInDolibarr=Order %s canceled diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index 60d4050148a..5c57764bf97 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -99,15 +99,15 @@ class Loan extends CommonObject $this->account_capital = $obj->accountancy_account_capital; $this->account_insurance = $obj->accountancy_account_insurance; $this->account_interest = $obj->accountancy_account_interest; - - return 1; + $this->db->free($resql); + return 1; } else { + $this->db->free($resql); return 0; } - $this->db->free($resql); } else { @@ -482,13 +482,14 @@ class Loan extends CommonObject if (empty($obj->fk_user_modif)) $obj->tms = ""; $this->date_modification = $this->db->jdate($obj->tms); + $this->db->free($result); return 1; } else { - return 0; + $this->db->free($result); + return 0; } - $this->db->free($result); } else { diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index ab1890bfa58..d20cbdb1566 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -225,6 +225,7 @@ if (isset($_SERVER["HTTP_USER_AGENT"])) $conf->browser->tablet=$tmp['tablet']; // TODO deprecated, use ->layout //var_dump($conf->browser); + if ($conf->browser->layout == 'phone') $conf->dol_no_mouse_hover=1; if ($conf->browser->layout == 'phone') $conf->global->MAIN_TESTMENUHIDER=1; } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index db08c8303ce..0a493ef60bc 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -138,7 +138,8 @@ if (empty($reshook)) header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; } - /* + + /* * Build doc */ else if ($action == 'builddoc' && $user->rights->produit->creer) @@ -197,22 +198,6 @@ if (empty($reshook)) } } - /* - if ($action == 'setaccountancy_code_buy') { - - $result = $object->setAccountancyCode('buy', GETPOST('accountancy_code_buy')); - if ($result < 0) setEventMessages(join(',',$object->errors), null, 'errors'); - $action=""; - } - - if ($action == 'setaccountancy_code_sell') - { - $result = $object->setAccountancyCode('sell', GETPOST('accountancy_code_sell')); - if ($result < 0) setEventMessages(join(',',$object->errors), null, 'errors'); - $action=""; - } - */ - // Add a product or service if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service->creer)) { @@ -1133,27 +1118,27 @@ else if (! empty($conf->accounting->enabled)) { // Accountancy_code_sell - print ''.$langs->trans("ProductAccountancySellCode").''; - print ''; + print ''.$langs->trans("ProductAccountancySellCode").''; + print ''; print $formaccountancy->select_account($object->accountancy_code_sell, 'accountancy_code_sell', 1, '', 0, 1); print ''; // Accountancy_code_buy - print ''.$langs->trans("ProductAccountancyBuyCode").''; - print ''; + print ''.$langs->trans("ProductAccountancyBuyCode").''; + print ''; print $formaccountancy->select_account($object->accountancy_code_buy, 'accountancy_code_buy', 1, '', 0, 1); print ''; } else // For external software { // Accountancy_code_sell - print ''.$langs->trans("ProductAccountancySellCode").''; - print ''; + print ''.$langs->trans("ProductAccountancySellCode").''; + print ''; print ''; // Accountancy_code_buy - print ''.$langs->trans("ProductAccountancyBuyCode").''; - print ''; + print ''.$langs->trans("ProductAccountancyBuyCode").''; + print ''; print ''; } print ''; diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 210ea09d3d3..290d011d09c 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -93,49 +93,44 @@ class Products extends DolibarrApi * @param int $page Page number * @param int $mode Use this param to filter list (0 for all, 1 for only product, 2 for only service) * @param int $category Use this param to filter list by category - * @param mixed $to_sell Filter products to sell (1) or not to sell (0) - * @param mixed $to_buy Filter products to buy (1) or not to buy (0) - * - * @return array Array of product objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.tobuy:=:0) and (t.tosell:=:1)" + * @return array Array of product objects */ - function index($sortfield = "p.ref", $sortorder = 'ASC', $limit = 0, $page = 0, $mode=0, $category=0, $to_sell='', $to_buy='') { + function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 0, $page = 0, $mode=0, $category=0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; - $sql = "SELECT rowid, ref, ref_ext"; - $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; + $sql = "SELECT t.rowid, t.ref, t.ref_ext"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as t"; if ($category > 0) { $sql.= ", ".MAIN_DB_PREFIX."categorie_product as c"; } - $sql.= ' WHERE p.entity IN ('.getEntity('product', 1).')'; - + $sql.= ' WHERE t.entity IN ('.getEntity('product', 1).')'; // Select products of given category if ($category > 0) { $sql.= " AND c.fk_categorie = ".$db->escape($category); - $sql.= " AND c.fk_product = p.rowid "; + $sql.= " AND c.fk_product = t.rowid "; } - // Show products - if ($mode == 1) $sql.= " AND p.fk_product_type = 0"; + if ($mode == 1) $sql.= " AND t.fk_product_type = 0"; // Show services - if ($mode == 2) $sql.= " AND p.fk_product_type = 1"; - // Show product on sell - if ($to_sell !== '') $sql.= " AND p.tosell = ".$db->escape($to_sell); - // Show product on buy - if ($to_buy !== '') $sql.= " AND p.tobuy = ".$db->escape($to_buy); - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + if ($mode == 2) $sql.= " AND t.fk_product_type = 1"; + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) diff --git a/htdocs/product/stats/card.php b/htdocs/product/stats/card.php index 3f92cd11b18..e7af303d694 100644 --- a/htdocs/product/stats/card.php +++ b/htdocs/product/stats/card.php @@ -211,9 +211,9 @@ if (! empty($id) || ! empty($ref) || GETPOST('id') == 'all') //print ''; // Generation des graphs + $dir = (! empty($conf->product->multidir_temp[$object->entity])?$conf->product->multidir_temp[$object->entity]:$conf->service->multidir_temp[$object->entity]); if ($object->id > 0) // We are on statistics for a dedicated product { - $dir = (! empty($conf->product->multidir_temp[$object->entity])?$conf->product->multidir_temp[$object->entity]:$conf->service->multidir_temp[$object->entity]); if (! file_exists($dir.'/'.$object->id)) { if (dol_mkdir($dir.'/'.$object->id) < 0) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index cc224176634..1222a8c84d9 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -889,15 +889,17 @@ class Project extends CommonObject * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string * @param string $moreinpopup Text to add into popup * @param string $sep Separator between ref and label if option addlabel is set + * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ - function getNomUrl($withpicto=0, $option='', $addlabel=0, $moreinpopup='', $sep=' - ') + function getNomUrl($withpicto=0, $option='', $addlabel=0, $moreinpopup='', $sep=' - ', $notooltip=0) { - global $langs; + global $conf, $langs, $user; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + $result = ''; - $link = ''; - $linkend = ''; + $label=''; if ($option != 'nolink') $label = '' . $langs->trans("ShowProject") . ''; if (! empty($this->ref)) @@ -911,33 +913,44 @@ class Project extends CommonObject if (! empty($this->datee)) $label .= ($label?'
':'').'' . $langs->trans('DateEnd') . ': ' . dol_print_date($this->datee, 'day'); // The space must be after the : to not being explode when showing the title in img_picto if ($moreinpopup) $label.='
'.$moreinpopup; - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; if ($option != 'nolink') { if (preg_match('/\.php$/',$option)) { - $link = ''; + $url = DOL_URL_ROOT . '/projet/tasks.php?id=' . $this->id; } else { - $link = 'public) $picto = 'project'; - - if ($withpicto) $result.=($link . img_object($label, $picto, 'class="classfortooltip"') . $linkend); + $linkstart = ''; + $linkend=''; + + if ($withpicto) $result.=($linkstart . img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"')) . $linkend); if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$link . $this->ref . $linkend . (($addlabel && $this->title) ? $sep . dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)) : ''); + if ($withpicto != 2) $result.=$linkstart . $this->ref . $linkend . (($addlabel && $this->title) ? $sep . dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)) : ''); return $result; } diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index e5b7a3f3031..bb006f23a9d 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -59,6 +59,8 @@ class Task extends CommonObject var $timespent_fk_user; var $timespent_note; + public $oldcopy; + /** * Constructor @@ -317,6 +319,30 @@ class Task extends CommonObject } } + if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) + { + // We remove directory + if ($conf->projet->dir_output) + { + $project = new Project($this->db); + $project->fetch($this->fk_project); + + $olddir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->oldcopy->ref); + $newdir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->ref); + if (file_exists($olddir)) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $res=dol_move($olddir, $newdir); + if (! $res) + { + $langs->load("errors"); + $this->error=$langs->trans('ErrorFailToRenameDir',$olddir,$newdir); + $error++; + } + } + } + } + // Commit or rollback if ($error) { @@ -495,12 +521,15 @@ class Task extends CommonObject * @param string $mode Mode 'task', 'time', 'contact', 'note', document' define page to link to. * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string * @param string $sep Separator between ref and label if option addlabel is set + * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ - function getNomUrl($withpicto=0,$option='',$mode='task', $addlabel=0, $sep=' - ') + function getNomUrl($withpicto=0,$option='',$mode='task', $addlabel=0, $sep=' - ', $notooltip=0) { - global $langs; + global $conf, $langs, $user; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + $result=''; $label = '' . $langs->trans("ShowTask") . ''; if (! empty($this->ref)) @@ -511,17 +540,30 @@ class Task extends CommonObject { $label .= "
".get_date_range($this->date_start,$this->date_end,'',$langs,0); } - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + + $url = DOL_URL_ROOT.'/projet/tasks/'.$mode.'.php?id='.$this->id.($option=='withproject'?'&withproject=1':''); - $link = ''; $linkend=''; - + $picto='projecttask'; - - if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"')).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$link.$this->ref.$linkend . (($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + if ($withpicto != 2) $result.=$linkstart.$this->ref.$linkend . (($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); return $result; } diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index 809f33ca5cb..5a975b4ec1e 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -26,6 +26,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; $langs->load("projects"); @@ -71,6 +72,8 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP * View */ +$form = new Form($db); + $title=$langs->trans("Project").' - '.$object->ref.' '.$object->name; if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->ref.' '.$object->name.' - '.$langs->trans("Info"); $help_url="EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 9c785e08e6b..cbee3683f73 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -82,6 +82,7 @@ if ($action == 'update' && ! $_POST["cancel"] && $user->rights->projet->creer) if (! $error) { $object->fetch($id,$ref); + $object->oldcopy = clone $object; $tmparray=explode('_',$_POST['task_parent']); $task_parent=$tmparray[1]; diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 8431f294469..11cd1fee919 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -89,11 +89,12 @@ class Contacts extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param int $socid ID of thirdparty to filter list - * @return array Array of contact objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of contact objects * * @throws RestException */ - function index($sortfield = "c.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $socid = 0) { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $socid = 0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -107,37 +108,36 @@ class Contacts extends DolibarrApi if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; - $sql = "SELECT c.rowid"; - $sql.= " FROM " . MAIN_DB_PREFIX . "socpeople as c"; + $sql = "SELECT t.rowid"; + $sql.= " FROM " . MAIN_DB_PREFIX . "socpeople as t"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) { // We need this table joined to the select in order to filter by sale $sql.= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc"; } - $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON c.fk_soc = s.rowid"; - $sql.= ' WHERE c.entity IN (' . getEntity('contact', 1) . ')'; - if ($socid) - $sql.= " AND c.fk_soc = " . $socid; + $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON t.fk_soc = s.rowid"; + $sql.= ' WHERE t.entity IN (' . getEntity('contact', 1) . ')'; + if ($socid) $sql.= " AND t.fk_soc = " . $socid; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) - $sql.= " AND c.fk_soc = sc.fk_soc"; + $sql.= " AND t.fk_soc = sc.fk_soc"; 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; } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) - { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); - } - + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + $sql.= $db->order($sortfield, $sortorder); if ($limit) @@ -321,7 +321,7 @@ class Contacts extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * @throws RestException */ diff --git a/htdocs/societe/class/api_deprecated_contact.class.php b/htdocs/societe/class/api_deprecated_contact.class.php index e645c3e15ff..56ef1eec19a 100644 --- a/htdocs/societe/class/api_deprecated_contact.class.php +++ b/htdocs/societe/class/api_deprecated_contact.class.php @@ -278,7 +278,7 @@ class ContactApi extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * @throws RestException */ diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index a520a7c8f83..de21e4fbbe0 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -94,10 +94,10 @@ class Thirdparties extends DolibarrApi * @param int $mode Set to 1 to show only customers * Set to 2 to show only prospects * Set to 3 to show only those are not customer neither prospect - * @param string $email Search by email filter - * @return array Array of thirdparty objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of thirdparty objects */ - function index($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $mode=0, $email=NULL) { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $mode=0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -107,35 +107,37 @@ class Thirdparties extends DolibarrApi // 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"; + $sql = "SELECT t.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."societe as s"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as t"; 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"; - if ($mode == 1) $sql.= " AND s.client IN (1, 3)"; - if ($mode == 2) $sql.= " AND s.client IN (2, 3)"; - if ($mode == 3) $sql.= " AND s.client IN (0)"; - $sql.= ' AND s.entity IN ('.getEntity('societe', 1).')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; - if ($email != NULL) $sql.= " AND s.email = \"".$email."\""; - if ($socid) $sql.= " AND s.rowid = ".$socid; - if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + $sql.= " WHERE t.fk_stcomm = st.id"; + if ($mode == 1) $sql.= " AND t.client IN (1, 3)"; + if ($mode == 2) $sql.= " AND t.client IN (2, 3)"; + if ($mode == 3) $sql.= " AND t.client IN (0)"; + $sql.= ' AND t.entity IN ('.getEntity('societe', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; + //if ($email != NULL) $sql.= " AND s.email = \"".$email."\""; + if ($socid) $sql.= " AND t.rowid = ".$socid; + if ($search_sale > 0) $sql.= " AND t.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; } - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + // Add sql filters + if ($sqlfilters) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + 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) { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index c2c75c44e66..e69ce5d5490 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1828,17 +1828,17 @@ class Societe extends CommonObject * @param int $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only) * @param string $option Target of link ('', 'customer', 'prospect', 'supplier', 'project') * @param int $maxlen Max length of name - * @param integer $notooltip 1=Disable tooltip + * @param int $notooltip 1=Disable tooltip * @return string String with URL */ function getNomUrl($withpicto=0, $option='', $maxlen=0, $notooltip=0) { - global $conf,$langs, $hookmanager; + global $conf, $langs, $hookmanager; + + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips $name=$this->name?$this->name:$this->nom; - if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; - if (! empty($conf->global->SOCIETE_ADD_REF_IN_LIST) && (!empty($withpicto))) { if (($this->client) && (! empty ( $this->code_client ))) { @@ -1853,46 +1853,46 @@ class Societe extends CommonObject if (!empty($this->name_alias)) $name .= ' ('.$this->name_alias.')'; $result=''; $label=''; - $link=''; $linkend=''; + $linkstart=''; $linkend=''; $label.= '
'; if ($option == 'customer' || $option == 'compta' || $option == 'category' || $option == 'category_supplier') { $label.= '' . $langs->trans("ShowCustomer") . ''; - $link = 'global->SOCIETE_DISABLE_PROSPECTS)) { $label.= '' . $langs->trans("ShowProspect") . ''; - $link = 'trans("ShowSupplier") . ''; - $link = 'trans("ShowAgenda") . ''; - $link = 'trans("ShowProject") . ''; - $link = 'trans("ShowMargin") . ''; - $link = 'trans("ShowCompany") . ''; - $link = ''; // Add type of canvas - $link.=(!empty($this->canvas)?'&canvas='.$this->canvas:'').'"'; + $linkstart.=(!empty($this->canvas)?'&canvas='.$this->canvas:'').'"'; + $linkclose=''; if (empty($notooltip)) { @@ -1932,22 +1933,21 @@ class Societe extends CommonObject $linkclose.=' class="classfortooltip"'; if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('societedao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('societedao')); + $parameters=array('id'=>$this->id); + $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $linkclose = $hookmanager->resPrint; } - $link.=$linkclose.'>'; + $linkstart.=$linkclose.'>'; $linkend=''; - if ($withpicto) $result.=($link.img_object(($notooltip?'':$label), 'company', ($notooltip?'':'class="classfortooltip"')).$linkend); + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), 'company', ($notooltip?'':'class="classfortooltip"')).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$link.($maxlen?dol_trunc($name,$maxlen):$name).$linkend; + if ($withpicto != 2) $result.=$linkstart.($maxlen?dol_trunc($name,$maxlen):$name).$linkend; return $result; } diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 4610073d05c..02f0e8dd6b5 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2368,31 +2368,60 @@ class SupplierProposal extends CommonObject * @param int $withpicto Add picto into link * @param string $option Where point the link ('compta', 'expedition', 'document', ...) * @param string $get_params Parametres added to url + * @param int $notooltip 1=Disable tooltip * @return string String with URL */ - function getNomUrl($withpicto=0,$option='', $get_params='') + function getNomUrl($withpicto=0,$option='', $get_params='', $notooltip=0) { - global $langs; + global $langs, $conf, $user; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + + $url=''; $result=''; - $label=$langs->trans("ShowSupplierProposal").': '.$this->ref; - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + + $label=''.$langs->trans("ShowSupplierProposal").''; + if (! empty($this->ref)) + $label.= '
'.$langs->trans('Ref').': '.$this->ref; + if (! empty($this->ref_fourn)) + $label.= '
'.$langs->trans('RefSupplier').': '.$this->ref_fourn; + if (! empty($this->total_ht)) + $label.= '
' . $langs->trans('AmountHT') . ': ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_tva)) + $label.= '
' . $langs->trans('VAT') . ': ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_ttc)) + $label.= '
' . $langs->trans('AmountTTC') . ': ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); if ($option == '') { - $link = 'rights->propal->lire) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowSupplierProposal"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; + } + + $linkstart = ''; $linkend=''; $picto='supplier_proposal'; if ($withpicto) - $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); + $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"')).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - $result.=$link.$this->ref.$linkend; + $result.=$linkstart.$this->ref.$linkend; return $result; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index c805106d784..d1bf48c4656 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2692,8 +2692,6 @@ table.dataTable td { } tr.even td, tr.pair td, tr.odd td, tr.impair td, form.odd div.tagtd, form.impair div.tagtd, form.pair div.tagtd, div.impair div.tagtd, div.pair div.tagtd, div.liste_titre div.tagtd { padding: 5px 2px 5px 3px; -} -tr.even td, tr.pair td, tr.odd td, tr.impair td, form.odd div.tagtd, form.impair div.tagtd, form.pair div.tagtd, div.impair div.tagtd, div.pair div.tagtd, div.liste_titre div.tagtd { border-bottom: 1px solid #ddd; } tr.even:last-of-type td, tr.pair:last-of-type td, tr.odd:last-of-type td, tr.impair:last-of-type td { @@ -2746,11 +2744,6 @@ tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, tabl } div.liste_titre, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr { - /* TO MATCH BOOTSTRAP */ - /*background: #ddd; - 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%); @@ -4309,42 +4302,44 @@ ul.ulmenu { /* Style for first level menu with jmobile */ .ui-li .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li { - padding: .9em 15px; + padding: 1em 15px; display: block; } .ui-btn-up-c { font-weight: normal; } -.ui-bar-b { - border: 1px solid #888; - text-shadow: none; -} .ui-focus, .ui-btn:focus { -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; } -.ui-bar-b, .lilevel0 { -/* border: 1px solid #888 !important; */ - background: rgb(); - background-repeat: repeat-x; - -/* - background-image: -o-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: -ms-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%);*/ - font-weight: bold; - - color: rgb() !important; +.ui-bar-b { + /*border: 1px solid #888;*/ + border: none; + background: none; + text-shadow: none; + color: rgb() !important; } +.ui-bar-b, .lilevel0 { + background-repeat: repeat-x; + border: none; + background: none; + text-shadow: none; + color: rgb() !important; +} +.alilevel0 { + font-weight: normal !important; +} + .ui-li.ui-last-child, .ui-li.ui-field-contain.ui-last-child { border-bottom-width: 0px !important; } .alilevel0 { color: rgb() !important; - text-shadow: 1px 0px 1px #; +} +.ulmenu { + box-shadow: none !important; + border-bottom: 1px solid #444; } .ui-btn-icon-right { border-right: 1px solid #ccc !important; @@ -4372,6 +4367,7 @@ ul.ulmenu { 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; @@ -4380,25 +4376,26 @@ border-top-left-radius: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }*/ + .alilevel1 { - color: rgb() !important; - text-shadow: 1px 0px 1px #; + color: rgb() !important; } .lilevel1 { - background-image: -webkit-gradient(linear,left top,left bottom,from( #ddd ),to( #d1d1d1 )) !important; - background-image: -webkit-linear-gradient( #ddd,#d1d1d1 ) !important; - background-image: -moz-linear-gradient( #ddd,#d1d1d1 ) !important; - background-image: -ms-linear-gradient( #ddd,#d1d1d1 ) !important; - background-image: -o-linear-gradient( #ddd,#d1d1d1 ) !important; - background-image: linear-gradient( #ddd,#d1d1d1 ) !important; + border-top: 2px solid #444; + background: #fff ! important; +} +.lilevel1 div div a { + font-weight: bold !important; } .lilevel2 { padding-left: 22px; + background: #fff ! important; } .lilevel3 { padding-left: 54px; + background: #fff ! important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index d97f73045bc..d4b96595d61 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -918,6 +918,11 @@ table.noborder tr.liste_titre td { padding-left: 2px; padding-right: 2px; } +.pictostatus { + width: 15px; + vertical-align: middle; + margin-top: -3px +} .pictowarning, .pictopreview { padding-: 3px; } @@ -941,26 +946,34 @@ div.arearef { margin-bottom: 10px; } div.heightref { - min-height: 74px; + min-height: 80px; } div.divphotoref { padding-right: 20px; } div.statusref { float: right; - padding-right: 12px; + padding-left: 12px; margin-top: 8px; margin-bottom: 10px; clear: both; } -img.photoref { - height: 80px; - width: 80px; +img.photoref, div.photoref { border: 1px solid #CCC; -moz-box-shadow: 3px 3px 4px #DDD; -webkit-box-shadow: 3px 3px 4px #DDD; box-shadow: 3px 3px 4px #DDD; + padding: 4px; + height: 80px; + width: 80px; + object-fit: contain; } +div.photoref { + display:table-cell; + vertical-align:middle; + text-align:center; +} + img.photorefnoborder { padding: 2px; height: 48px; @@ -2190,10 +2203,15 @@ 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 */ } +table.borderplus { + border: 1px solid #BBB; +} .border tbody tr, .border tbody tr td { height: 20px; @@ -2216,7 +2234,7 @@ td.border, div.tagtable div div.border { } .table-key-border-col { - width: 25%; + /* width: 25%; */ vertical-align:top; } .table-val-border-col { @@ -2509,8 +2527,6 @@ div.pagination li.paginationafterarrows { { background: rgb() !important; - - /* background: rgba(0, 0, 0, 0.05) !important; */ } @@ -2585,7 +2601,7 @@ div.liste_titre { border-top-style: solid; } div.liste_titre_bydiv { - border-top-width: px; + border-top-width: px; border-top-color: rgb(); border-top-style: solid; @@ -2593,7 +2609,7 @@ div.liste_titre_bydiv { border-collapse: collapse; display: table; padding: 2px 0px 2px 0; - width: 100%; /* 1px more, i don't know why */ + width: 100%; } tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable.tr { @@ -2601,10 +2617,6 @@ tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, tabl } div.liste_titre, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr { - /* TO MATCH BOOTSTRAP */ - /* background: #ddd; */ - - /* TO MATCH ELDY */ background-image: -o-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(250,250,250,0.3) 100%); background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(250,250,250,0.3) 100%); @@ -2690,6 +2702,7 @@ tr.liste_sub_total, tr.liste_sub_total td { border-top-width: px !important; border-top-color: rgb() !important; border-top-style: solid !important; + margin: 0px 0px 0px 0px !important; } .paymenttable tr td:first-child, .margintable tr td:first-child { @@ -2818,8 +2831,13 @@ tr.box_pair { 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 #f4f4f4; } +.noborderbottom { + border-bottom: none !important; +} .formboxfilter { vertical-align: middle; @@ -3658,7 +3676,7 @@ ul.filedirelem li { border: solid 1px #f4f4f4; } -ui-layout-north { +.ui-layout-north { } @@ -4056,6 +4074,9 @@ li.ui-li-divider .ui-link { a.ui-link, a.ui-link:hover, .ui-btn:hover, span.ui-btn-text:hover, span.ui-btn-inner:hover { text-decoration: none !important; } +.ui-body-c { + background: #fff; +} .ui-btn-inner { min-width: .4em; @@ -4090,7 +4111,7 @@ select { /* display: inline-block; */ /* We can't set this. This disable ability to make */ /* TODO modified by jmobile, replace jmobile with pure css*/ overflow:hidden; - white-space: nowrap; + white-space: nowrap; /* Enabling this make behaviour strange when selecting the empty value if this empty value is '' instead of ' ' */ text-overflow: ellipsis; } .fiche .ui-controlgroup { @@ -4123,7 +4144,7 @@ a.tab span.ui-btn-inner color: rgb(); } .liste_titre .ui-link { - color: rgb() !important; + color: rgb() !important; } a.ui-link { @@ -4135,7 +4156,7 @@ a.ui-link { { white-space: normal; overflow: hidden; - text-overflow: hidden; + text-overflow: clip; /* "hidden" : do not exists as a text-overflow value (https://developer.mozilla.org/fr/docs/Web/CSS/text-overflow) */ } /* Warning: setting this may make screen not beeing refreshed after a combo selection */ @@ -4175,23 +4196,45 @@ ul.ulmenu { } /* Style for first level menu with jmobile */ +.ui-li .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li { + padding: 1em 15px; + display: block; +} +.ui-btn-up-c { + font-weight: normal; +} +.ui-focus, .ui-btn:focus { + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} +.ui-bar-b { + /*border: 1px solid #888;*/ + border: none; + background: none; + text-shadow: none; + color: rgb() !important; +} .ui-bar-b, .lilevel0 { - border: 1px solid #888 !important; - background: rgb(); background-repeat: repeat-x; + border: none; + background: none; + text-shadow: none; + color: rgb() !important; +} +.alilevel0 { + font-weight: normal !important; +} - /*background-image: -o-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: -ms-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%); - background-image: linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0.3) 100%);*/ - font-weight: bold; - - color: rgb() !important; +.ui-li.ui-last-child, .ui-li.ui-field-contain.ui-last-child { + border-bottom-width: 0px !important; } .alilevel0 { color: rgb() !important; - text-shadow: 1px 0px 1px #; +} +.ulmenu { + box-shadow: none !important; + border-bottom: 1px solid #444; } .ui-btn-icon-right { border-right: 1px solid #ccc !important; @@ -4201,7 +4244,7 @@ ul.ulmenu { text-shadow: none; } .ui-btn-up-c, .ui-btn-hover-c { - border: 1px solid #ccc; + /* border: 1px solid #ccc; */ text-shadow: none; } .ui-body-c .ui-link, .ui-body-c .ui-link:visited, .ui-body-c .ui-link:hover { @@ -4211,33 +4254,43 @@ ul.ulmenu { color: # !important; text-shadow: none !important; } -.ui-controlgroup-horizontal .ui-btn.ui-first-child { +/* +.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; - text-shadow: 1px 0px 1px #; + color: rgb() !important; } .lilevel1 { - background-image: -webkit-gradient(linear,left top,left bottom,from( #f4f4f4 ),to( #d1d1d1 )) !important; - background-image: -webkit-linear-gradient( #f4f4f4,#d1d1d1 ) !important; - background-image: -moz-linear-gradient( #f4f4f4,#d1d1d1 ) !important; - background-image: -ms-linear-gradient( #f4f4f4,#d1d1d1 ) !important; - background-image: -o-linear-gradient( #f4f4f4,#d1d1d1 ) !important; - background-image: linear-gradient( #f4f4f4,#d1d1d1 ) !important; + border-top: 2px solid #444; + background: #fff ! important; +} +.lilevel1 div div a { + font-weight: bold !important; } .lilevel2 { padding-left: 22px; + background: #fff ! important; } .lilevel3 { padding-left: 54px; + background: #fff ! important; } @@ -4342,7 +4395,9 @@ img.demothumb { -/***** CSS style used for small screen *****/ +/* ============================================================================== */ +/* CSS style used for small screen */ +/* ============================================================================== */ .imgopensurveywizard { @@ -4357,6 +4412,13 @@ img.demothumb { width: px; } + img.demothumb { + box-shadow: 1px 1px 4px #BBB; + margin-right: 6px; + margin-left: 4px; + width: 80px; + } + div.tabBar { padding-left: 0px; padding-right: 0px; diff --git a/htdocs/user/class/api_deprecated_user.class.php b/htdocs/user/class/api_deprecated_user.class.php index c9fcb2b0dd7..f080e8a3b45 100644 --- a/htdocs/user/class/api_deprecated_user.class.php +++ b/htdocs/user/class/api_deprecated_user.class.php @@ -256,7 +256,7 @@ class UserApi extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * @throws RestException */ diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index c046c9869cf..e177b4d52ec 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -60,10 +60,10 @@ class Users extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $user_ids User ids filter field. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * - * @return array Array of User objects + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of User objects */ - function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $user_ids = 0) { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $user_ids = 0, $sqlfilters = '') { global $db, $conf; $obj_ret = array(); @@ -79,14 +79,17 @@ class Users extends DolibarrApi $sql.= " FROM ".MAIN_DB_PREFIX."user as t"; $sql.= ' WHERE t.entity IN ('.getEntity('user', 1).')'; if ($user_ids) $sql.=" AND t.rowid IN (".$user_ids.")"; - - $nbtotalofrecords = 0; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) - { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); - } - + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -274,7 +277,7 @@ class Users extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate + * @param array|null $data Data to validate * @return array * @throws RestException */