From d77f7556d8f19f4f622083eebf771e75962a6acb Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Wed, 9 Oct 2019 16:00:14 +0200 Subject: [PATCH 01/20] NEW add parent category id or label in import category module --- .../modules/import/import_csv.modules.php | 6 +++++- .../modules/import/import_xlsx.modules.php | 6 +++++- htdocs/core/modules/modCategorie.class.php | 20 ++++++++++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index de428900ba9..734f516fa78 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -459,10 +459,14 @@ class ImportCsv extends ModeleImports $error++; }*/ $param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart. + } elseif ($class == 'Categorie') { + if ($objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') { + $param_array = array('', $newval, $arrayrecord[1]['val']); + } } call_user_func_array(array($classinstance, $method), $param_array); // If not found, try the fetch from label - if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') + if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel' && $class!='Categorie') { $param_array = array('', '', $newval); call_user_func_array(array($classinstance, $method), $param_array); diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index c4799ba557e..1a92062b15f 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -486,10 +486,14 @@ class ImportXlsx extends ModeleImports $error++; }*/ $param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart. + } elseif ($class == 'Categorie') { + if ($objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') { + $param_array = array('', $newval, $arrayrecord[1]['val']); + } } call_user_func_array(array($classinstance, $method), $param_array); // If not found, try the fetch from label - if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') + if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel' && $class!='Categorie') { $param_array = array('', '', $newval); call_user_func_array(array($classinstance, $method), $param_array); diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index c04a4d6b346..e8a1bd218cd 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -406,15 +406,29 @@ class modCategorie extends DolibarrModules $this->import_icon[$r]=$this->picto; $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('ca'=>MAIN_DB_PREFIX.'categorie'); - $this->import_fields_array[$r]=array('ca.label'=>"Label*",'ca.type'=>"Type*",'ca.description'=>"Description"); - + $this->import_fields_array[$r]=array( + 'ca.label'=>"Label*",'ca.type'=>"Type*",'ca.description'=>"Description", + 'ca.fk_parent' => 'Parent' + ); $this->import_regex_array[$r]=array('ca.type'=>'^[0|1|2|3]'); + $this->import_convertvalue_array[$r] = array( + 'ca.fk_parent' => array( + 'rule' => 'fetchidfromcodeorlabel', + 'classfile' => '/categories/class/categorie.class.php', + 'class' => 'Categorie', + 'method' => 'fetch', + 'element' => 'category' + ) + ); $typeexample=""; if ($conf->product->enabled) { $typeexample.=($typeexample?"/":"")."0=Product"; } if ($conf->fournisseur->enabled) { $typeexample.=($typeexample?"/":"")."1=Supplier"; } if ($conf->societe->enabled) { $typeexample.=($typeexample?"/":"")."2=Customer-Prospect"; } if ($conf->adherent->enabled) { $typeexample.=($typeexample?"/":"")."3=Member"; } - $this->import_examplevalues_array[$r]=array('ca.label'=>"Supplier Category",'ca.type'=>$typeexample,'ca.description'=>"Imported category"); + $this->import_examplevalues_array[$r] = array( + 'ca.label'=>"Supplier Category",'ca.type'=>$typeexample,'ca.description'=>"Imported category", + 'ca.fk_parent' => '0' + ); if (! empty($conf->product->enabled)) { From 612c80b290ff2abc52bc9437ea80a227a071865b Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 10 Oct 2019 13:07:19 +0200 Subject: [PATCH 02/20] Update api_setup.class.php --- htdocs/api/class/api_setup.class.php | 66 +++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index dd0a08039ef..9552380f090 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -358,6 +358,70 @@ class Setup extends DolibarrApi } + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror()); + } + + return $list; + } + + /** + * Get the list of contacts types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $type To filter on type of contact + * @param string $module To filter on module contacts + * @param int $active Payment term is active or not {@min 0} {@max 1} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return array List of Contacts types + * + * @url GET dictionary/contact_types + * + * @throws RestException + */ + public function getListOfContactTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT rowid, code, element as type, libelle as label, source, module, position"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as t"; + $sql.= " WHERE t.active = ".$active; + if ($type) $sql.=" AND type LIKE '%" . $this->db->escape($type) . "%'"; + if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $this->db->order($sortfield, $sortorder); if ($limit) { @@ -394,7 +458,7 @@ class Setup extends DolibarrApi * @param string $module To filter on module events * @param int $active Payment term is active or not {@min 0} {@max 1} * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return array List of civility types + * @return array List of civility types * * @url GET dictionary/civilities * From 56b6223bba5149115b125d16d1a59c678e0f8880 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 10 Oct 2019 14:23:18 +0200 Subject: [PATCH 03/20] Update api_setup.class.php --- htdocs/api/class/api_setup.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 9552380f090..4ef09e5ae78 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -329,7 +329,7 @@ class Setup extends DolibarrApi * @param int $page Page number (starting from zero) * @param string $type To filter on type of event * @param string $module To filter on module events - * @param int $active Payment term is active or not {@min 0} {@max 1} + * @param int $active Event's type is active or not {@min 0} {@max 1} * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" * @return array List of events types * @@ -393,7 +393,7 @@ class Setup extends DolibarrApi * @param int $page Page number (starting from zero) * @param string $type To filter on type of contact * @param string $module To filter on module contacts - * @param int $active Payment term is active or not {@min 0} {@max 1} + * @param int $active Contact's type is active or not {@min 0} {@max 1} * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" * @return array List of Contacts types * @@ -456,7 +456,7 @@ class Setup extends DolibarrApi * @param int $limit Number of items per page * @param int $page Page number (starting from zero) * @param string $module To filter on module events - * @param int $active Payment term is active or not {@min 0} {@max 1} + * @param int $active Civility is active or not {@min 0} {@max 1} * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" * @return array List of civility types * From e5cb9bc22eaa7f8e014aee1ae8bcd3b5e6b2fe2f Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 10 Oct 2019 15:56:36 +0200 Subject: [PATCH 04/20] Update api_setup.class.php --- htdocs/api/class/api_setup.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 4ef09e5ae78..1d4bb6a8cb7 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -442,7 +442,7 @@ class Setup extends DolibarrApi $list[] = $this->db->fetch_object($result); } } else { - throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror()); + throw new RestException(503, 'Error when retrieving list of contacts types : '.$this->db->lasterror()); } return $list; From c80d055af31d21131c1fe02c19889f2ef45017f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 10 Oct 2019 23:51:54 +0200 Subject: [PATCH 05/20] fix search by roles --- htdocs/core/lib/company.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 36657d48dbc..76606c4a54e 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1052,12 +1052,12 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '') if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; if ($key == 'status' || $key == 'statut') $align.=($align?' ':'').'center'; - if (! empty($arrayfields['t.'.$key]['checked'])) + if (! empty($arrayfields['t.'.$key]['checked']) || ! empty($arrayfields['sc.'.$key]['checked'])) { print ''; if (in_array($key, array('statut'))){ print $form->selectarray('search_status', array('-1'=>'','0'=>$contactstatic->LibStatut(0, 1),'1'=>$contactstatic->LibStatut(1, 1)), $search_status); - }elseif (in_array($key, array('role'))) { + } elseif (in_array($key, array('role'))) { print $formcompany->showRoles("search_roles", $contactstatic, 'edit', $search_roles); } else { print ''; From 2fb776ee347e3e051ff0a9e52f93773aa46cd6af Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 11 Oct 2019 11:57:11 +0200 Subject: [PATCH 06/20] NEW add new rule fetchidfromcodeandlabel for categories import --- .../modules/import/import_csv.modules.php | 49 +++++++++++++++++-- .../modules/import/import_xlsx.modules.php | 49 +++++++++++++++++-- htdocs/core/modules/modCategorie.class.php | 11 +++-- 3 files changed, 94 insertions(+), 15 deletions(-) diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 734f516fa78..cb3ae176026 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -381,6 +381,11 @@ class ImportCsv extends ModeleImports //dol_syslog("Table ".$tablename." check for entity into cache is ".$tablewithentity_cache[$tablename]); } + // array of fields to column index + $arrayfield = array(); + foreach($sort_array_match_file_to_database as $key => $val) { + $arrayfield[$val] = ($key-1); + } // Loop on each fields in the match array: $key = 1..n, $val=alias of field (s.nom) foreach($sort_array_match_file_to_database as $key => $val) @@ -459,14 +464,10 @@ class ImportCsv extends ModeleImports $error++; }*/ $param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart. - } elseif ($class == 'Categorie') { - if ($objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') { - $param_array = array('', $newval, $arrayrecord[1]['val']); - } } call_user_func_array(array($classinstance, $method), $param_array); // If not found, try the fetch from label - if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel' && $class!='Categorie') + if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') { $param_array = array('', '', $newval); call_user_func_array(array($classinstance, $method), $param_array); @@ -489,6 +490,44 @@ class ImportCsv extends ModeleImports } } } + elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeandlabel') + { + $isidorref='id'; + if (! is_numeric($newval) && $newval != '' && ! preg_match('/^id:/i', $newval)) $isidorref='ref'; + $newval=preg_replace('/^(id|ref):/i', '', $newval); + + if ($isidorref == 'ref') { + $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']); + $class = $objimport->array_import_convertvalue[0][$val]['class']; + $method = $objimport->array_import_convertvalue[0][$val]['method']; + $codefromfield = $objimport->array_import_convertvalue[0][$val]['codefromfield']; + $code = $arrayrecord[$arrayfield[$codefromfield]]['val']; + if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] != '') { + $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval]; + } else { + $resultload = dol_include_once($file); + if (empty($resultload)) { + dol_print_error('', 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method . ', code=' . $code); + break; + } + $classinstance = new $class($this->db); + // Try the fetch from code and ref + $param_array = array('', $newval, $code); + call_user_func_array(array($classinstance, $method), $param_array); + $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] = $classinstance->id; + if ($classinstance->id > 0) // we found record + { + $newval = $classinstance->id; + } else { + if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); + else $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; + $this->errors[$error]['type'] = 'FOREIGNKEY'; + $errorforthistable++; + $error++; + } + } + } + } elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='zeroifnull') { if (empty($newval)) $newval='0'; diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 1a92062b15f..c5fcc1441e3 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -408,6 +408,11 @@ class ImportXlsx extends ModeleImports //dol_syslog("Table ".$tablename." check for entity into cache is ".$tablewithentity_cache[$tablename]); } + // array of fields to column index + $arrayfield = array(); + foreach($sort_array_match_file_to_database as $key => $val) { + $arrayfield[$val] = ($key-1); + } // Loop on each fields in the match array: $key = 1..n, $val=alias of field (s.nom) foreach($sort_array_match_file_to_database as $key => $val) @@ -486,14 +491,10 @@ class ImportXlsx extends ModeleImports $error++; }*/ $param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart. - } elseif ($class == 'Categorie') { - if ($objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') { - $param_array = array('', $newval, $arrayrecord[1]['val']); - } } call_user_func_array(array($classinstance, $method), $param_array); // If not found, try the fetch from label - if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel' && $class!='Categorie') + if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') { $param_array = array('', '', $newval); call_user_func_array(array($classinstance, $method), $param_array); @@ -516,6 +517,44 @@ class ImportXlsx extends ModeleImports } } } + elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeandlabel') + { + $isidorref='id'; + if (! is_numeric($newval) && $newval != '' && ! preg_match('/^id:/i', $newval)) $isidorref='ref'; + $newval=preg_replace('/^(id|ref):/i', '', $newval); + + if ($isidorref == 'ref') { + $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']); + $class = $objimport->array_import_convertvalue[0][$val]['class']; + $method = $objimport->array_import_convertvalue[0][$val]['method']; + $codefromfield = $objimport->array_import_convertvalue[0][$val]['codefromfield']; + $code = $arrayrecord[$arrayfield[$codefromfield]]['val']; + if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] != '') { + $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval]; + } else { + $resultload = dol_include_once($file); + if (empty($resultload)) { + dol_print_error('', 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method . ', code=' . $code); + break; + } + $classinstance = new $class($this->db); + // Try the fetch from code and ref + $param_array = array('', $newval, $code); + call_user_func_array(array($classinstance, $method), $param_array); + $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] = $classinstance->id; + if ($classinstance->id > 0) // we found record + { + $newval = $classinstance->id; + } else { + if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); + else $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; + $this->errors[$error]['type'] = 'FOREIGNKEY'; + $errorforthistable++; + $error++; + } + } + } + } elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='zeroifnull') { if (empty($newval)) $newval='0'; diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index e8a1bd218cd..eb9e2c6b4a1 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -413,11 +413,12 @@ class modCategorie extends DolibarrModules $this->import_regex_array[$r]=array('ca.type'=>'^[0|1|2|3]'); $this->import_convertvalue_array[$r] = array( 'ca.fk_parent' => array( - 'rule' => 'fetchidfromcodeorlabel', - 'classfile' => '/categories/class/categorie.class.php', - 'class' => 'Categorie', - 'method' => 'fetch', - 'element' => 'category' + 'rule' => 'fetchidfromcodeandlabel', + 'classfile' => '/categories/class/categorie.class.php', + 'class' => 'Categorie', + 'method' => 'fetch', + 'element' => 'category', + 'codefromfield' => 'ca.type' ) ); $typeexample=""; From b276abea26c58e78320137fc22a7e1d431ff71bb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 16:49:58 +0200 Subject: [PATCH 07/20] Fix missing token in form Fix date lost after search --- htdocs/accountancy/bookkeeping/list.php | 4 +-- .../accountancy/bookkeeping/listbyaccount.php | 31 +++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 5cf64a70e67..b5f0c06738a 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -502,9 +502,9 @@ if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&con if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; print '
'; +print ''; print ''; if ($optioncss != '') print ''; -print ''; print ''; print ''; print ''; @@ -542,7 +542,7 @@ if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; else $moreforfilter = $hookmanager->resPrint; print '
'; -print ''; +print '
'; // Filters lines print ''; diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 640cf87d496..d91772a6ab3 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -37,9 +37,6 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; // Load translation files required by the page $langs->loadLangs(array("accountancy")); -$page = GETPOST("page"); -$sortorder = GETPOST("sortorder"); -$sortfield = GETPOST("sortfield"); $action = GETPOST('action', 'alpha'); $search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int')); $search_date_end = dol_mktime(0, 0, 0, GETPOST('search_date_endmonth', 'int'), GETPOST('search_date_endday', 'int'), GETPOST('search_date_endyear', 'int')); @@ -71,9 +68,9 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if ($sortorder == "") $sortorder = "ASC"; -if ($sortfield == "") $sortfield = "t.doc_date"; +if ($sortfield == "") $sortfield = "t.doc_date,t.rowid"; -if (empty($search_date_start) && empty($search_date_end)) { +if (empty($search_date_start) && empty($search_date_end) && GETPOSTISSET('search_date_startday') && GETPOSTISSET('search_date_startmonth') && GETPOSTISSET('search_date_starthour')) { $sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; $sql.= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."'"; $sql.= $db->plimit(1); @@ -255,6 +252,14 @@ if ($action == 'delbookkeepingyear') { print ''; +print ''; +print ''; +if ($optioncss != '') print ''; +print ''; +print ''; +print ''; +print ''; + $newcardbutton.= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); $newcardbutton.= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', './card.php?action=create'); @@ -265,12 +270,11 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($lim print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $viewflat.$newcardbutton, '', $limit); // Reverse sort order -if ( preg_match('/^asc/i', $sortorder) ) - $sortorder = "asc"; -else - $sortorder = "desc"; +if (preg_match('/^asc/i', $sortorder)) $sortorder = "asc"; +else $sortorder = "desc"; -print '
'; +print '
'; +print '
'; print ''; print ''; +print ''; print ''; print_liste_field_titre("AccountAccountingShort", $_SERVER['PHP_SELF']); @@ -313,8 +318,6 @@ print_liste_field_titre("Codejournal", $_SERVER['PHP_SELF'], "t.code_journal", " print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $param, "", 'width="60"', $sortfield, $sortorder, 'center '); print "\n"; -print ''; - $total_debit = 0; $total_credit = 0; @@ -400,7 +403,7 @@ while ($i < min($num, $limit)) // Show sub-total of last shown account print ''; print ''; -print ''; print ''; @@ -421,6 +424,8 @@ print ''; print ''; print "
'; @@ -300,6 +304,7 @@ print ''; $searchpicto=$form->showFilterAndCheckAddButtons(0); print $searchpicto; print '
'.$langs->trans("SubTotal").':'.price($sous_total_debit).''.price($sous_total_credit).''; +print ''; print price($sous_total_debit - $sous_total_credit); print '
"; +print '
'; + print '
'; // End of page From b58c2c38b2fbb13ef05a7d45ae64fcfb4c142efc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 16:57:47 +0200 Subject: [PATCH 08/20] Fix missing token --- htdocs/core/lib/company.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 36657d48dbc..9b6876aefe9 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -993,7 +993,8 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '') $title = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("ContactsForCompany") : $langs->trans("ContactsAddressesForCompany")); print load_fiche_titre($title, $newcardbutton, ''); - print '
'; + print ''; + print ''; print ''; print ''; print ''; From 95305a313d7b70daa137475b243ee930ec624863 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 17:02:35 +0200 Subject: [PATCH 09/20] Fix trans --- htdocs/core/lib/company.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 864d5d85c53..ced8c37c6d7 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -932,7 +932,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '') 't.name'=>array('label'=>"Name", 'checked'=>1, 'position'=>10), 't.poste'=>array('label'=>"PostOrFunction", 'checked'=>1, 'position'=>20), 't.address'=>array('label'=>(empty($conf->dol_optimize_smallscreen) ? $langs->trans("Address").' / '.$langs->trans("Phone").' / '.$langs->trans("Email") : $langs->trans("Address")), 'checked'=>1, 'position'=>30), - 'sc.role'=>array('label'=>"Roles", 'checked'=>1, 'position'=>40), + 'sc.role'=>array('label'=>"ContactByDefaultFor", 'checked'=>1, 'position'=>40), 't.statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>50, 'class'=>'center'), ); // Extra fields @@ -1091,7 +1091,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '') if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; if ($key == 'status' || $key == 'statut') $align.=($align?' ':'').'center'; if (! empty($arrayfields['t.'.$key]['checked'])) print getTitleFieldOfList($val['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($align?'class="'.$align.'"':''), $sortfield, $sortorder, $align.' ')."\n"; - if ($key == 'role') $align.=($align?' ':'').'center'; + if ($key == 'role') $align.=($align?' ':'').'left'; if (! empty($arrayfields['sc.'.$key]['checked'])) { print getTitleFieldOfList($arrayfields['sc.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 'sc.'.$key, '', $param, ($align?'class="'.$align.'"':''), $sortfield, $sortorder, $align.' ')."\n"; } From d9dde34ba6eb8ca86ba5bc0bad249279de60abd1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 17:24:02 +0200 Subject: [PATCH 10/20] Fix phpcs --- .../modulebuilder/template/myobject_list.php | 36 +++++++++---------- htdocs/theme/eldy/manifest.json.php | 12 +++---- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 54885f8e380..1c1d0e101b9 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -22,24 +22,24 @@ * \brief List page for myobject */ -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Do not load object $user -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // Do not load object $mysoc -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Do not load object $langs -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check injection attack on GET parameters -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check injection attack on POST parameters -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) -//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value -//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler -//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message -//if (! defined("XFRAMEOPTIONS_ALLOWALL")) define('XFRAMEOPTIONS_ALLOWALL',1); // Do not add the HTTP header 'X-Frame-Options: SAMEORIGIN' but 'X-Frame-Options: ALLOWALL' +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session) +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', '1'); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("XFRAMEOPTIONS_ALLOWALL")) define('XFRAMEOPTIONS_ALLOWALL', '1'); // Do not add the HTTP header 'X-Frame-Options: SAMEORIGIN' but 'X-Frame-Options: ALLOWALL' // Load Dolibarr environment $res=0; diff --git a/htdocs/theme/eldy/manifest.json.php b/htdocs/theme/eldy/manifest.json.php index 8809286ed1e..889b406ab3f 100644 --- a/htdocs/theme/eldy/manifest.json.php +++ b/htdocs/theme/eldy/manifest.json.php @@ -28,12 +28,12 @@ if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); -if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', 1); -if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', 1); -if (! defined('NOLOGIN')) define('NOLOGIN', 1); -if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU',1); -if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', 1); +if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); +if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); +if (! defined('NOLOGIN')) define('NOLOGIN', '1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); require_once __DIR__.'/../../main.inc.php'; From fa928f7dc333d3a2e086830b7e47a080a24daf6c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 17:33:13 +0200 Subject: [PATCH 11/20] Update modCategorie.class.php --- htdocs/core/modules/modCategorie.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index eb9e2c6b4a1..d157e35a555 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -427,7 +427,7 @@ class modCategorie extends DolibarrModules if ($conf->societe->enabled) { $typeexample.=($typeexample?"/":"")."2=Customer-Prospect"; } if ($conf->adherent->enabled) { $typeexample.=($typeexample?"/":"")."3=Member"; } $this->import_examplevalues_array[$r] = array( - 'ca.label'=>"Supplier Category",'ca.type'=>$typeexample,'ca.description'=>"Imported category", + 'ca.label'=>"Supplier Category",'ca.type'=>$typeexample,'ca.description'=>"My Category description", 'ca.fk_parent' => '0' ); From 5446a7bd8e6d78c1092469398de6e6777d961ebe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 17:43:15 +0200 Subject: [PATCH 12/20] Try phpunit fix --- test/phpunit/BOMTest.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test/phpunit/BOMTest.php b/test/phpunit/BOMTest.php index 73603a5f336..b69e59c6283 100644 --- a/test/phpunit/BOMTest.php +++ b/test/phpunit/BOMTest.php @@ -39,8 +39,11 @@ $langs->load("main"); /** - * Class BillOfMaterialsTest - * @package Testbillofmaterials + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. */ class BOMTest extends PHPUnit\Framework\TestCase { @@ -77,13 +80,6 @@ class BOMTest extends PHPUnit\Framework\TestCase global $conf,$user,$langs,$db; $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. - if (! empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { - print "\n".__METHOD__." Company must be setup to have name-firstname in order 'Firstname Lastname'\n"; - die(); - } - if (! empty($conf->global->MAIN_MODULE_LDAP)) { print "\n".__METHOD__." module LDAP must be disabled.\n"; die(); } - if (! empty($conf->global->MAIN_MODULE_MAILMANSPIP)) { print "\n".__METHOD__." module MailmanSpip must be disabled.\n"; die(); } - print __METHOD__."\n"; } @@ -142,6 +138,6 @@ class BOMTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertLessThan($result, 0); - return $localobject; + return $result; } } From 51383ce6afe742fba85502b83bac04008c1a8c87 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 18:42:07 +0200 Subject: [PATCH 13/20] FIX Reset of password can use email like the login. --- htdocs/user/class/user.class.php | 7 ++++++- htdocs/user/passwordforgotten.php | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index e8a45efcd62..fecbafe1dba 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -238,9 +238,10 @@ class User extends CommonObject * @param string $sid If defined, sid to used for search * @param int $loadpersonalconf 1=also load personal conf of user (in $user->conf->xxx), 0=do not load personal conf. * @param int $entity If a value is >= 0, we force the search on a specific entity. If -1, means search depens on default setup. + * @param int $email If defined, email to used for search * @return int <0 if KO, 0 not found, >0 if OK */ - public function fetch($id = '', $login = '', $sid = '', $loadpersonalconf = 0, $entity = -1) + public function fetch($id = '', $login = '', $sid = '', $loadpersonalconf = 0, $entity = -1, $email = '') { global $conf, $user; @@ -305,6 +306,10 @@ class User extends CommonObject { $sql.= " AND u.login = '".$this->db->escape($login)."'"; } + elseif ($email) + { + $sql.= " AND u.email = '".$this->db->escape($email)."'"; + } else { $sql.= " AND u.rowid = ".$id; diff --git a/htdocs/user/passwordforgotten.php b/htdocs/user/passwordforgotten.php index ada75da6110..8f85465cde2 100644 --- a/htdocs/user/passwordforgotten.php +++ b/htdocs/user/passwordforgotten.php @@ -45,8 +45,8 @@ $action=GETPOST('action', 'alpha'); $mode=$dolibarr_main_authentication; if (! $mode) $mode='http'; -$username = GETPOST('username', 'alpha'); -$passwordhash = GETPOST('passwordhash', 'alpha'); +$username = trim(GETPOST('username', 'alpha')); +$passwordhash = trim(GETPOST('passwordhash', 'alpha')); $conf->entity = (GETPOST('entity', 'int') ? GETPOST('entity', 'int') : 1); // Instantiate hooks of thirdparty module only if not already define @@ -104,6 +104,11 @@ if ($action == 'buildnewpassword' && $username) { $edituser = new User($db); $result=$edituser->fetch('', $username, '', 1); + if ($result == 0 && preg_match('/@/', $username)) + { + $result=$edituser->fetch('', '', '', 1, -1, $username); + } + if ($result <= 0 && $edituser->error == 'USERNOTFOUND') { $message = '
'.$langs->trans("ErrorLoginDoesNotExists", $username).'
'; From dfaf2ae34b20383a8c18d06efca2bf4e03bdf267 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Oct 2019 19:20:52 +0200 Subject: [PATCH 14/20] Trans --- htdocs/install/mysql/migration/repair.sql | 2 +- htdocs/langs/en_US/compta.lang | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 4d87203b068..eac0d5b3bd9 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -471,7 +471,7 @@ UPDATE llx_accounting_bookkeeping set date_creation = tms where date_creation IS -- Note to make all deposit as payed when there is already a discount generated from it. --drop table tmp_invoice_deposit_mark_as_available; --create table tmp_invoice_deposit_mark_as_available as select * from llx_facture as f where f.type = 3 and f.paye = 0 and f.rowid in (select fk_facture_source from llx_societe_remise_except); ---update llx_facture set paye = 1 where rowid in (select rowid from tmp_invoice_deposit_mark_as_available); +--update llx_facture set paye = 1, fk_statut = 2 where rowid in (select rowid from tmp_invoice_deposit_mark_as_available); diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 42d88f3f722..eb76d9c64a2 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -112,7 +112,7 @@ ShowVatPayment=Show VAT payment TotalToPay=Total to pay BalanceVisibilityDependsOnSortAndFilters=Balance is visible in this list only if table is sorted ascending on %s and filtered for 1 bank account CustomerAccountancyCode=Customer accounting code -SupplierAccountancyCode=vendor accounting code +SupplierAccountancyCode=Vendor accounting code CustomerAccountancyCodeShort=Cust. account. code SupplierAccountancyCodeShort=Sup. account. code AccountNumber=Account number From 9f596565898857b7503b597a00e9bfc64d7c2bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 11 Oct 2019 23:08:33 +0200 Subject: [PATCH 15/20] fix typo inspired by grandoc --- dev/tools/dolibarr-mysql2pgsql.pl | 86 +++++++++---------- htdocs/adherents/class/adherent.class.php | 2 +- .../compta/facture/invoicetemplate_list.php | 4 +- .../core/class/commondocgenerator.class.php | 10 +-- .../supplier_order/pdf/pdf_cornas.modules.php | 6 +- .../jquery/plugins/flot/jquery.flot.js | 6 +- 6 files changed, 57 insertions(+), 57 deletions(-) diff --git a/dev/tools/dolibarr-mysql2pgsql.pl b/dev/tools/dolibarr-mysql2pgsql.pl index 1f510ad60f1..2fe03aaf2b5 100755 --- a/dev/tools/dolibarr-mysql2pgsql.pl +++ b/dev/tools/dolibarr-mysql2pgsql.pl @@ -58,7 +58,7 @@ foreach my $file (keys %filelist) { $ARGV[1]="$DESTI/$file"; print "Convert file $ARGV[0] into $ARGV[1]\n"; - + # MySQL to PostgreSQL dump file converter # # For usage: perl mysql2pgsql.perl --help @@ -76,18 +76,18 @@ foreach my $file (keys %filelist) { # 4) add debug option # see rest of changelog at http://cvs.linux.hr/cvsweb.cgi/sql/mysql2pgsql # 2003-12-16 jsp -- Joe Speigle : - # converts: s/\) *Type=MyISAM;/);/i, enum data type -> references, + # converts: s/\) *Type=MyISAM;/);/i, enum data type -> references, # auto_increment->sequences # 2004-01-13 jsp -- moved project to gborg; both the above declined ownership # 2004-06-29 converts: year(4), year(2) - # homepage: gborg.postgresql.org - + # homepage: gborg.postgresql.org + GetOptions("debug", "help"); - + my $DEBUG = $opt_debug || 0; my $HELP = $opt_help || 0; - - + + if (($HELP) || ! defined($ARGV[0]) || ! defined($ARGV[1])) { print "Usage: perl $0 {--verbose|--help|--debug} mysql_dump_file.sql pg_dump_file.sql\n"; print "\t* OPTIONS\n"; @@ -106,15 +106,15 @@ foreach my $file (keys %filelist) { print "\tpg_dump_file.sql (undefined)\n"; } exit 1; - } - + } + open(IN,"<$ARGV[0]") || die "can't open mysql dump file $ARGV[0]"; open(OUT,">$ARGV[1]") || die "can't open pg dump file $ARGV[1]"; print OUT "-- Generated by $PROG\n"; print OUT "-- (c) 2004, PostgreSQL Inc.\n"; print OUT "-- (c) 2005, Laurent Destailleur.\n"; print OUT "\n"; - + # Output for create table and create index sub output_create { # If command ends with "xxx,);", we change to "xxx);" @@ -128,7 +128,7 @@ foreach my $file (keys %filelist) { print OUT $create_index; } } - + # Reset when moving from each "create table" to "insert" part of dump sub reset_vars() { $create_sql=""; @@ -137,24 +137,24 @@ foreach my $file (keys %filelist) { $enum_column=''; } - + # Boucle sur contenu fichier source #---------------------------------- while() { - + # comments or empty lines - if (/^-- \$Id/) { + if (/^-- \$Id/) { $_ =~ s/\$//g; - print OUT $_; + print OUT $_; next; } # comments or empty lines if (/^#/ || /^$/ || /^--/) { - print OUT $_; + print OUT $_; next; } - if (/^USE\s*([^;]*);/) { - print OUT "\\c ". $1; + if (/^USE\s*([^;]*);/) { + print OUT "\\c ". $1; next; } if ($create_sql ne "") { # we are inside create table statement so lets process datatypes @@ -167,14 +167,14 @@ foreach my $file (keys %filelist) { # LDR Added "innodb" and "engine" } elsif (/(ISAM|innodb)/i) { # end of create table sequence - s/\) *type=(MyISAM|innodb);/);/i; - s/\) *engine=(MyISAM|innodb);/);/i; + s/\) *type=(MyISAM|innodb);/);/i; + s/\) *engine=(MyISAM|innodb);/);/i; $create_sql =~ s/,$//g; # strip last , inside create table $create_sql .= $_; &output_create; &reset_vars(); next; - } + } # enum -> check if (/([\w\"]*)\s+enum\s*\(((?:['"][\?\w]+['"]\s*,)+['"][\?\w]+['"])\)(.*)$/i) { @@ -189,7 +189,7 @@ foreach my $file (keys %filelist) { $enum_datafield{$enum_column} =~ s/\"/\'/g; $_ = qq~ $enum_column CHAR($maxlength) CHECK ($enum_column IN ($enum_datafield{$enum_column})) $suite\n~; # int, auto_increment -> serial - } elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) { + } elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) { $seq = qq~${table}_${1}_seq~; s/[\s\t]*([a-zA-Z_0-9]*)\s*.*int.*auto_increment[^,]*/ $1 SERIAL PRIMARY KEY/ig; $create_sql.=$_; @@ -211,40 +211,40 @@ foreach my $file (keys %filelist) { elsif (/tinyint/i) { s/tinyint/smallint/g; } - + # nuke unsigned s/(int\w+|smallint)\s+unsigned/$1/gi; - + # blob -> text s/\w*blob/text/gi; # tinytext/mediumtext -> text s/tinytext/text/gi; s/mediumtext/text/gi; - + # char -> varchar # PostgreSQL would otherwise pad with spaces as opposed # to MySQL! Your user interface may depend on this! s/(\s+)char/${1}varchar/gi; - + # nuke date representation (not supported in PostgreSQL) s/datetime default '[^']+'/datetime/i; s/date default '[^']+'/datetime/i; s/time default '[^']+'/datetime/i; - + # change not null datetime field to null valid ones # (to support remapping of "zero time" to null s/datetime not null/datetime/i; s/datetime/timestamp/i; - + # nuke size of timestamp s/timestamp\([^)]*\)/timestamp/i; - + # double -> numeric s/^double/numeric/i; s/(\s*)double/${1}numeric/i; - + # float -> numeric s/^float/numeric/i; s/(\s*)float/${1}numeric/i; @@ -261,7 +261,7 @@ foreach my $file (keys %filelist) { $create_sql.=$_; next; } - + # unique key [name] (field) if (/unique key\s*(\w*)\s*\((\w+)\)/i) { s/unique key\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i; @@ -288,30 +288,30 @@ foreach my $file (keys %filelist) { $create_index .= "CREATE INDEX $idxname ON $table ($fieldlist);\n"; next; } - + # index(field) if (/index\s*(\w*)\s*\((\w+)\)/i) { my $idxname=($1?"$1":"idx_${table}_$2"); $create_index .= "CREATE INDEX $idxname ON $table ($2);\n"; next; } - + # primary key if (/\bkey\b/i && !/^\s+primary key\s+/i) { s/KEY(\s+)[^(]*(\s+)/$1 UNIQUE $2/i; # hack off name of the non-primary key } - + # key(xxx) if (/key\s*\((\w+)\)/i) { my $idxname="idx_${table}_$1"; $create_index .= "CREATE INDEX $idxname ON $table ($1);\n"; next; } - + # Quote column names s/(^\s*)([^\s\-\(]+)(\s*)/$1"$2"$3/gi if (!/\bkey\b/i); - - # Remap colums with names of existing system attribute + + # Remap columns with names of existing system attribute if (/"oid"/i) { s/"oid"/"_oid"/g; print STDERR "WARNING: table $table uses column \"oid\" which is renamed to \"_oid\"\nYou should fix application manually! Press return to continue."; @@ -330,13 +330,13 @@ foreach my $file (keys %filelist) { s!\x85!... !g; # \ldots s!\x92!`!g; } - + # fix dates '0000-00-00 00:00:00' (should be null) s/'0000-00-00 00:00:00'/null/gi; s/'0000-00-00'/null/gi; s/'00:00:00'/null/gi; s/([12]\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-6]\d)([0-6]\d)/'$1-$2-$3 $4:$5:$6'/; - + if (/create\s+table\s+(\w+)/i) { $create_sql = $_; /create\s*table\s*(\w+)/i; @@ -345,11 +345,11 @@ foreach my $file (keys %filelist) { print OUT $_; } } # end of if inside create_table - } # END while() - + } # END while() + close IN; close OUT; - + } print "\n"; @@ -358,4 +358,4 @@ print "\n"; print "Press a key to finish...\n"; $stop=; -0; \ No newline at end of file +0; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 14eb401866a..2bcbc21c3a0 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1282,7 +1282,7 @@ class Adherent extends CommonObject $this->societe = $obj->company; $this->company = $obj->company; $this->socid = $obj->fk_soc; - $this->fk_soc = $obj->fk_soc; // For backward comaptibility + $this->fk_soc = $obj->fk_soc; // For backward compatibility $this->address = $obj->address; $this->zip = $obj->zip; $this->town = $obj->town; diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php index 3e9011bb74b..e13dc30204f 100644 --- a/htdocs/compta/facture/invoicetemplate_list.php +++ b/htdocs/compta/facture/invoicetemplate_list.php @@ -416,7 +416,7 @@ if ($resql) print ''; if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; print ''; - $formother->select_year($search_year?$search_year:-1, 'search_year', 1, 20, 5, 0, 0, '', 'witdhauto valignmiddle'); + $formother->select_year($search_year?$search_year:-1, 'search_year', 1, 20, 5, 0, 0, '', 'widthauto valignmiddle'); print ''; } // Date next generation @@ -425,7 +425,7 @@ if ($resql) print ''; if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; print ''; - $formother->select_year($search_year_date_when?$search_year_date_when:-1, 'search_year_date_when', 1, 20, 5, 0, 0, '', 'witdhauto valignmiddle'); + $formother->select_year($search_year_date_when?$search_year_date_when:-1, 'search_year_date_when', 1, 20, 5, 0, 0, '', 'widthauto valignmiddle'); print ''; } // Extra fields diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 84f49bafe3f..c99f78c3483 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -63,7 +63,7 @@ abstract class CommonDocGenerator // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Define array with couple subtitution key => subtitution value + * Define array with couple substitution key => substitution value * * @param User $user User * @param Translate $outputlangs Language object for output @@ -101,7 +101,7 @@ abstract class CommonDocGenerator // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Define array with couple subtitution key => subtitution value + * Define array with couple substitution key => substitution value * * @param Societe $mysoc Object thirdparty * @param Translate $outputlangs Language object for output @@ -161,7 +161,7 @@ abstract class CommonDocGenerator // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Define array with couple subtitution key => subtitution value + * Define array with couple substitution key => substitution value * * @param Societe $object Object * @param Translate $outputlangs Language object for output @@ -242,7 +242,7 @@ abstract class CommonDocGenerator // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Define array with couple subtitution key => subtitution value + * Define array with couple substitution key => substitution value * * @param Contact $object contact * @param Translate $outputlangs object for output @@ -723,7 +723,7 @@ abstract class CommonDocGenerator // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Define array with couple subtitution key => subtitution value + * Define array with couple substitution key => substitution value * * @param Object $object Dolibarr Object * @param Translate $outputlangs Language object for output diff --git a/htdocs/core/modules/supplier_order/pdf/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/pdf/pdf_cornas.modules.php index 04a62d3d924..ee858c35cf7 100644 --- a/htdocs/core/modules/supplier_order/pdf/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/pdf/pdf_cornas.modules.php @@ -1625,7 +1625,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders */ /** - * uasort callback function to Sort colums fields + * uasort callback function to Sort columns fields * * @param array $a PDF lines array fields configs * @param array $b PDF lines array fields configs @@ -1663,7 +1663,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders // Positionning $curX = $this->page_largeur-$this->marge_droite; // start from right - // Array witdh + // Array width $arrayWidth = $this->page_largeur-$this->marge_droite-$this->marge_gauche; // Count flexible column @@ -1671,7 +1671,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders $countFlexCol = 0; foreach ($this->cols as $colKey => &$colDef) { - if (!$this->getColumnStatus($colKey)) continue; // continue if desable + if (!$this->getColumnStatus($colKey)) continue; // continue if disabled if (!empty($colDef['scale'])){ // In case of column widht is defined by percentage diff --git a/htdocs/includes/jquery/plugins/flot/jquery.flot.js b/htdocs/includes/jquery/plugins/flot/jquery.flot.js index 39f3e4cf3ef..c97ceb1bf44 100644 --- a/htdocs/includes/jquery/plugins/flot/jquery.flot.js +++ b/htdocs/includes/jquery/plugins/flot/jquery.flot.js @@ -2010,7 +2010,7 @@ Licensed under the MIT license. ctx.lineTo(xrange.to + subPixel, yrange.to); } else { ctx.moveTo(xrange.from, yrange.to + subPixel); - ctx.lineTo(xrange.to, yrange.to + subPixel); + ctx.lineTo(xrange.to, yrange.to + subPixel); } ctx.stroke(); } else { @@ -2525,9 +2525,9 @@ Licensed under the MIT license. radius = series.points.radius, symbol = series.points.symbol; - // If the user sets the line width to 0, we change it to a very + // If the user sets the line width to 0, we change it to a very // small value. A line width of 0 seems to force the default of 1. - // Doing the conditional here allows the shadow setting to still be + // Doing the conditional here allows the shadow setting to still be // optional even with a lineWidth of 0. if( lw == 0 ) From 849eda20232f47e91bf9afe1874365d1586fe0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 12 Oct 2019 00:05:26 +0200 Subject: [PATCH 16/20] Update index.php --- htdocs/comm/mailing/index.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/mailing/index.php b/htdocs/comm/mailing/index.php index d6ade738e3e..0f3e42d366f 100644 --- a/htdocs/comm/mailing/index.php +++ b/htdocs/comm/mailing/index.php @@ -175,13 +175,15 @@ if ($result) { while ($i < $num ) { $obj = $db->fetch_object($result); + $mailstatic=new Mailing($db); + $mailstatic->id = $obj->rowid; + $mailstatic->ref = $obj->rowid; print ''; - print ''.img_object($langs->trans("ShowEMail"), "email").' '.$obj->rowid.''; + print ''.$mailstatic->getNomUrl(1).''; print ''.dol_trunc($obj->titre, 38).''; print ''.dol_print_date($db->jdate($obj->date_creat), 'day').''; print ''.($obj->nbemail?$obj->nbemail:"0").''; - $mailstatic=new Mailing($db); print ''.$mailstatic->LibStatut($obj->statut, 5).''; print ''; $i++; From 71227e43faf1f7f9a98df7d73f47710fbe50f54e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Oct 2019 04:51:41 +0200 Subject: [PATCH 17/20] Debug stripe deprecated page --- htdocs/stripe/class/stripe.class.php | 122 ++++++++++++++++++++++----- htdocs/stripe/payment.php | 2 +- 2 files changed, 101 insertions(+), 23 deletions(-) diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 1f1610438e8..593447919a7 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -803,7 +803,8 @@ class Stripe extends CommonObject } /** - * Create charge with public/payment/newpayment.php, stripe/card.php, cronjobs or REST API + * Create charge. + * This is called by page htdocs/stripe/payment.php and may be deprecated. * * @param int $amount Amount to pay * @param string $currency EUR, GPB... @@ -854,12 +855,12 @@ class Stripe extends CommonObject $description = ""; $ref = ""; - if ($origin == order) { + if ($origin == 'order') { $order = new Commande($this->db); $order->fetch($item); $ref = $order->ref; $description = "ORD=" . $ref . ".CUS=" . $societe->id.".PM=stripe"; - } elseif ($origin == invoice) { + } elseif ($origin == 'invoice') { $invoice = new Facture($this->db); $invoice->fetch($item); $ref = $invoice->ref; @@ -881,9 +882,42 @@ class Stripe extends CommonObject global $stripearrayofkeysbyenv; \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); - if (empty($conf->stripeconnect->enabled)) + if (empty($conf->stripeconnect->enabled)) // With a common Stripe account { - if (preg_match('/acct_/i', $source)) + if (preg_match('/pm_/i', $source)) + { + $stripecard = $source; + $amountstripe = $stripeamount; + $FULLTAG = 'PFBO'; // Payment From Back Office + $stripe = $return; + $amounttopay = $amount; + $servicestatus = $status; + + dol_syslog("* createPaymentStripe get stripeacc", LOG_DEBUG); + $stripeacc = $stripe->getStripeAccount($service); // Get Stripe OAuth connect account if it exists (no network access here) + + dol_syslog("* createPaymentStripe Create payment on card ".$stripecard->id.", amounttopay=".$amounttopay.", amountstripe=".$amountstripe.", FULLTAG=".$FULLTAG, LOG_DEBUG); + + // Create payment intent and charge payment (confirmnow = true) + $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1); + + $charge = new stdClass(); + if ($paymentintent->status == 'succeeded') + { + $charge->status = 'ok'; + } + else + { + $charge->status = 'failed'; + $charge->failure_code = $stripe->code; + $charge->failure_message = $stripe->error; + $charge->failure_declinecode = $stripe->declinecode; + $stripefailurecode = $stripe->code; + $stripefailuremessage = $stripe->error; + $stripefailuredeclinecode = $stripe->declinecode; + } + } + elseif (preg_match('/acct_/i', $source)) { $charge = \Stripe\Charge::create(array( "amount" => "$stripeamount", @@ -914,12 +948,14 @@ class Stripe extends CommonObject $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description")); } } else { - $fee = $amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE; - if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { - $fee = $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL; - } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { - $fee = $conf->global->STRIPE_APPLICATION_FEE_MINIMAL; - } + // With Stripe Connect + $fee = $amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE; + if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { + $fee = $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL; + } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { + $fee = $conf->global->STRIPE_APPLICATION_FEE_MINIMAL; + } + if (! in_array($currency, $arrayzerounitcurrency)) $stripefee = round($fee * 100); else $stripefee = round($fee); @@ -942,22 +978,64 @@ class Stripe extends CommonObject $paymentarray["receipt_email"] = $societe->email; } - $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description", "stripe_account" => "$account")); + if (preg_match('/pm_/i', $source)) + { + $stripecard = $source; + $amountstripe = $stripeamount; + $FULLTAG = 'PFBO'; // Payment From Back Office + $stripe = $return; + $amounttopay = $amount; + $servicestatus = $status; + + dol_syslog("* createPaymentStripe get stripeacc", LOG_DEBUG); + $stripeacc = $stripe->getStripeAccount($service); // Get Stripe OAuth connect account if it exists (no network access here) + + dol_syslog("* createPaymentStripe Create payment on card ".$stripecard->id.", amounttopay=".$amounttopay.", amountstripe=".$amountstripe.", FULLTAG=".$FULLTAG, LOG_DEBUG); + + // Create payment intent and charge payment (confirmnow = true) + $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1); + + $charge = new stdClass(); + if ($paymentintent->status == 'succeeded') + { + $charge->status = 'ok'; + $charge->id = $paymentintent->id; + } + else + { + $charge->status = 'failed'; + $charge->failure_code = $stripe->code; + $charge->failure_message = $stripe->error; + $charge->failure_declinecode = $stripe->declinecode; + } + } + else + { + $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description", "stripe_account" => "$account")); + } } if (isset($charge->id)) {} $return->statut = 'success'; $return->id = $charge->id; - if ($charge->source->type == 'card') { - $return->message = $charge->source->card->brand . " ...." . $charge->source->card->last4; - } elseif ($charge->source->type == 'three_d_secure') { - $stripe = new Stripe($this->db); - $src = \Stripe\Source::retrieve("" . $charge->source->three_d_secure->card . "", array( - "stripe_account" => $stripe->getStripeAccount($service) - )); - $return->message = $src->card->brand . " ...." . $src->card->last4; - } else { - $return->message = $charge->id; + + if (preg_match('/pm_/i', $source)) + { + $return->message = 'Payment retreived by card status = '.$charge->status; + } + else + { + if ($charge->source->type == 'card') { + $return->message = $charge->source->card->brand . " ...." . $charge->source->card->last4; + } elseif ($charge->source->type == 'three_d_secure') { + $stripe = new Stripe($this->db); + $src = \Stripe\Source::retrieve("" . $charge->source->three_d_secure->card . "", array( + "stripe_account" => $stripe->getStripeAccount($service) + )); + $return->message = $src->card->brand . " ...." . $src->card->last4; + } else { + $return->message = $charge->id; + } } } catch (\Stripe\Error\Card $e) { include DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; diff --git a/htdocs/stripe/payment.php b/htdocs/stripe/payment.php index dfcb79e18a0..894753f6440 100644 --- a/htdocs/stripe/payment.php +++ b/htdocs/stripe/payment.php @@ -28,7 +28,7 @@ /** * \file htdocs/stripe/payment.php * \ingroup stripe - * \brief Payment page for customers invoices. TODO Seems deprecated and bugged ! + * \brief Payment page for customers invoices. @TODO Seems deprecated and bugged and not used (no link to this page) ! */ // Load Dolibarr environment From dccfdad9dda6d9b7660c63b4530358a9b4b092a3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Oct 2019 11:25:44 +0200 Subject: [PATCH 18/20] Work on inventory feature --- htdocs/langs/en_US/stocks.lang | 3 + .../modulebuilder/template/myobject_card.php | 2 +- htdocs/product/inventory/card.php | 8 +- htdocs/product/inventory/inventory.php | 283 ++++++++++++++++++ .../product/inventory/lib/inventory.lib.php | 3 +- .../product/inventory/tpl/inventory.tpl.php | 202 +------------ htdocs/theme/eldy/btn.inc.php | 2 +- htdocs/theme/md/btn.inc.php | 13 + 8 files changed, 308 insertions(+), 208 deletions(-) create mode 100644 htdocs/product/inventory/inventory.php diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index a98d4e18cbf..18dc7faaeb9 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -212,3 +212,6 @@ StockIncreaseAfterCorrectTransfer=Increase by correction/transfer StockDecreaseAfterCorrectTransfer=Decrease by correction/transfer StockIncrease=Stock increase StockDecrease=Stock decrease +InventoryForASpecificWarehouse=Inventory for a specific warehouse +InventoryForASpecificProduct=Inventory for a specific product + diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 7f28794d51b..6af2312938b 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -228,7 +228,7 @@ if (($id || $ref) && $action == 'edit') dol_fiche_head(); - print ''."\n"; + print '
'."\n"; // Common attributes include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php'; diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index eb9181c8060..87e6fadb57a 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -148,7 +148,7 @@ jQuery(document).ready(function() { // Part to create if ($action == 'create') { - print load_fiche_titre($langs->trans("NewInventory", $langs->transnoentitiesnoconv("MyInventory")), '', 'products'); + print load_fiche_titre($langs->trans("NewInventory"), '', 'products'); print ''; print ''; @@ -183,7 +183,7 @@ if ($action == 'create') // Part to edit record if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans("Inventory")); + print load_fiche_titre($langs->trans("Inventory"), '', 'products'); print ''; print ''; @@ -193,7 +193,7 @@ if (($id || $ref) && $action == 'edit') dol_fiche_head(); - print '
'."\n"; + print '
'."\n"; // Common attributes include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php'; @@ -218,7 +218,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $res = $object->fetch_optionals(); $head = inventoryPrepareHead($object); - dol_fiche_head($head, 'inventory', $langs->trans("Inventory"), -1, 'inventory'); + dol_fiche_head($head, 'card', $langs->trans("Inventory"), -1, 'stock'); $formconfirm = ''; diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php new file mode 100644 index 00000000000..ab1a31fe4de --- /dev/null +++ b/htdocs/product/inventory/inventory.php @@ -0,0 +1,283 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/product/inventory/inventory.php + * \ingroup inventory + * \brief Tabe to enter counting + */ + +require '../../main.inc.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; +include_once DOL_DOCUMENT_ROOT.'/product/inventory/lib/inventory.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("stocks","other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage= GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'myobjectcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); + +if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) +{ + $result = restrictedArea($user, 'stock', $id); +} +else +{ + $result = restrictedArea($user, 'stock', $id, '', 'inventory_advance'); +} + +// Initialize technical objects +$object=new Inventory($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction=$conf->stock->dir_output . '/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('inventorycard')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +$search_array_options=$extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Initialize array of search criterias +$search_all=trim(GETPOST("search_all", 'alpha')); +$search=array(); +foreach($object->fields as $key => $val) +{ + if (GETPOST('search_'.$key, 'alpha')) $search[$key]=GETPOST('search_'.$key, 'alpha'); +} + +if (empty($action) && empty($id) && empty($ref)) $action='view'; + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +// Security check - Protection if external user +//if ($user->societe_id > 0) access_forbidden(); +//if ($user->societe_id > 0) $socid = $user->societe_id; +//$result = restrictedArea($user, 'mymodule', $id); + +if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) +{ + $permissiontoadd = $user->rights->stock->creer; + $permissiontodelete = $user->rights->stock->supprimer; +} +else +{ + $permissiontoadd = $user->rights->stock->inventory_advance->write; + $permissiontodelete = $user->rights->stock->inventory_advance->write; +} + + +/* + * Actions + */ + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + $error=0; + + $backurlforlist = DOL_URL_ROOT.'/product/inventory/list.php'; + + // Actions cancel, add, update, delete or clone + include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; + + // Actions when linking object each other + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + + // Actions to send emails + /*$trigger_name='MYOBJECT_SENTBYMAIL'; + $autocopy='MAIN_MAIL_AUTOCOPY_MYOBJECT_TO'; + $trackid='myobject'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';*/ +} + + + + +/* + * View + */ + +$form=new Form($db); + +llxHeader('', $langs->trans('Inventory'), ''); + +// Example : Adding jquery code +print ''; + + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) +{ + $res = $object->fetch_optionals(); + + $head = inventoryPrepareHead($object); + dol_fiche_head($head, 'inventory', $langs->trans("Inventory"), -1, 'stock'); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteInventory'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', '', 0, 1); + } + // Confirmation to delete line + if ($action == 'deleteline') + { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + } + + // Clone confirmation + if ($action == 'clone') { + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneMyObject', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } + + // Call Hook formConfirm + $parameters = array('lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) $formconfirm.=$hookmanager->resPrint; + elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint; + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref='
'; + /* + // Ref bis + $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->inventory->creer, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->inventory->creer, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
'.$langs->trans('Project') . ' '; + if ($user->rights->inventory->creer) + { + if ($action != 'classify') + { + $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.=''; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref.=$proj->getNomUrl(); + } else { + $morehtmlref.=''; + } + } + } + */ + $morehtmlref.='
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + print '
'; + print '
'."\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; + + // Other attributes. Fields from hook formObjectOptions and Extrafields. + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + + print '
'; + print ''; + print ''; + + print '
'; + + dol_fiche_end(); + + + // Buttons for actions + if ($action != 'presend' && $action != 'editline') { + print '
'."\n"; + $parameters=array(); + $reshook=$hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + if (empty($reshook)) + { + if ($permissiontoadd) + { + print ''.$langs->trans("Validate").''."\n"; + } + else + { + print ''.$langs->trans('Validate').''."\n"; + } + } + print '
'."\n"; + } + + + include DOL_DOCUMENT_ROOT.'/product/inventory/tpl/inventory.tpl.php'; + +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/product/inventory/lib/inventory.lib.php b/htdocs/product/inventory/lib/inventory.lib.php index 361a89c923c..e0af60588ed 100644 --- a/htdocs/product/inventory/lib/inventory.lib.php +++ b/htdocs/product/inventory/lib/inventory.lib.php @@ -69,7 +69,8 @@ function inventoryPrepareHead(&$inventory, $title = 'Inventory', $get = '') global $langs; return array( - array(dol_buildpath('/product/inventory/card.php?id='.$inventory->id.$get, 1), $langs->trans($title),'inventory') + array(dol_buildpath('/product/inventory/card.php?id='.$inventory->id.$get, 1), $langs->trans('Card'), 'card'), + array(dol_buildpath('/product/inventory/inventory.php?id='.$inventory->id.$get, 1), $langs->trans('Inventory'), 'inventory') ); } diff --git a/htdocs/product/inventory/tpl/inventory.tpl.php b/htdocs/product/inventory/tpl/inventory.tpl.php index 8d85b20dc43..992557505db 100644 --- a/htdocs/product/inventory/tpl/inventory.tpl.php +++ b/htdocs/product/inventory/tpl/inventory.tpl.php @@ -8,207 +8,7 @@ if (empty($conf) || ! is_object($conf)) } ?> - - -status != 1) { ?> - trans('AddInventoryProduct'); ?> : -
- - - - - - -

- - -
- - -
Cet inventaire est validé
- - - - - - - $row) { - - $total_pmp+=$row['pmp_stock']; - $total_pa+=$row['pa_stock']; - $total_pmp_actual+=$row['pmp_actual']; - $total_pa_actual+=$row['pa_actual']; - - if($i%20 === 0) - { - _headerList($view); - } // Fin IF principal - ?> - - - - barcode->enabled)) { ?> - - - - - - - global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){ - echo ''; - $total_current_pa+=$row['current_pa_stock']; - } - - ?> - - - - - rights->stock->changePMP)) { - echo ''; - } - ?> - - global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){ - echo ''; - $total_current_pa_actual+=$row['current_pa_actual']; - } - - ?> - - - - - - - -
  '.price($row['current_pa_stock']).'   - - '.$row['pmp_new'].''.price($row['current_pa_actual']).'
- - status != 1) { ?> -
- - - trans('Modify') ?> - rights->stock->changePMP)) { - echo ''.$langs->trans('ApplyPMP').''; - } - - if ($can_validate == 1) { ?> - trans('RegulateStock') ?> - - - - - - - trans('Flush'); ?> -     - trans('Delete') ?> - -
- - status == 1) { ?> -
- - - - trans('Delete') ?> - - -
- -
-

Date de création : getDate('datec') ?> -
Dernière mise à jour : getDate('tms') ?>

+TODO... diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index a3000715712..c69ee57c17b 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -61,7 +61,7 @@ span.butAction, span.butActionDelete { cursor: pointer; } -.tableforfieldcreate a.butActionNew>span.fa-plus-circle, a.butActionNew>span.fa-plus-circle:hover, +.tableforfieldcreate a.butActionNew>span.fa-plus-circle, .tableforfieldcreate a.butActionNew>span.fa-plus-circle:hover, span.butActionNew>span.fa-plus-circle, span.butActionNew>span.fa-plus-circle:hover, a.butActionNewRefused>span.fa-plus-circle, a.butActionNewRefused>span.fa-plus-circle:hover, span.butActionNewRefused>span.fa-plus-circle, span.butActionNewRefused>span.fa-plus-circle:hover, diff --git a/htdocs/theme/md/btn.inc.php b/htdocs/theme/md/btn.inc.php index 384b968d220..be897e8f841 100644 --- a/htdocs/theme/md/btn.inc.php +++ b/htdocs/theme/md/btn.inc.php @@ -77,6 +77,19 @@ span.butAction, span.butActionDelete { a.butActionNew>span.fa-plus-circle { padding-left: 6px; font-size: 1.5em; } a.butActionNewRefused>span.fa-plus-circle { padding-left: 6px; font-size: 1.5em; } +.tableforfieldcreate a.butActionNew>span.fa-plus-circle, .tableforfieldcreate a.butActionNew>span.fa-plus-circle:hover, +span.butActionNew>span.fa-plus-circle, span.butActionNew>span.fa-plus-circle:hover, +a.butActionNewRefused>span.fa-plus-circle, a.butActionNewRefused>span.fa-plus-circle:hover, +span.butActionNewRefused>span.fa-plus-circle, span.butActionNewRefused>span.fa-plus-circle:hover, +a.butActionNew>span.fa-list-alt, a.butActionNew>span.fa-list-alt:hover, +span.butActionNew>span.fa-list-alt, span.butActionNew>span.fa-list-alt:hover, +a.butActionNewRefused>span.fa-list-alt, a.butActionNewRefused>span.fa-list-alt:hover, +span.butActionNewRefused>span.fa-list-alt, span.butActionNewRefused>span.fa-list-alt:hover +{ + font-size: 1em; + padding-left: 0px; +} + .button, .butAction { color: #ffffff !important; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); From 9ba992b8b6cc936cae7869395444fd4de63c7375 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Oct 2019 12:31:35 +0200 Subject: [PATCH 19/20] Work on inventory module --- htdocs/bom/bom_list.php | 8 ++--- htdocs/comm/action/card.php | 2 ++ htdocs/core/lib/functions2.lib.php | 35 +++++++++++-------- .../modulebuilder/template/myobject_list.php | 5 +-- htdocs/product/inventory/card.php | 11 +++++- .../inventory/class/inventory.class.php | 22 +++++++----- htdocs/product/inventory/inventory.php | 23 +++++++++--- htdocs/product/inventory/list.php | 31 ++++++++++------ 8 files changed, 93 insertions(+), 44 deletions(-) diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php index 4b0a6ff29be..635f0f9db65 100644 --- a/htdocs/bom/bom_list.php +++ b/htdocs/bom/bom_list.php @@ -375,14 +375,14 @@ print ''; foreach($object->fields as $key => $val) { $cssforfield=(empty($val['css'])?'':$val['css']); - if ($key == 'status') $cssforfield='center'; + if ($key == 'status') $cssforfield.=($cssforfield?' ':'').'center'; elseif (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; elseif (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; - elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real'))) $cssforfield.=($cssforfield?' ':'').'right'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield.=($cssforfield?' ':'').'right'; if (! empty($arrayfields['t.'.$key]['checked'])) { print ''; - if (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 0, 0, 0, '', 'maxwidth75'); + if (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth75'); else print ''; print ''; } @@ -411,7 +411,7 @@ foreach($object->fields as $key => $val) if ($key == 'status') $cssforfield.=($cssforfield?' ':'').'center'; elseif (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; elseif (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; - elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real'))) $cssforfield.=($cssforfield?' ':'').'right'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield.=($cssforfield?' ':'').'right'; if (! empty($arrayfields['t.'.$key]['checked'])) { print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield?'class="'.$cssforfield.'"':''), $sortfield, $sortorder, ($cssforfield?$cssforfield.' ':''))."\n"; diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index baf454fdf67..cc3accde763 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1080,6 +1080,8 @@ if ($action == 'create') $formproject->selectTasks((! empty($societe->id)?$societe->id:-1), $tid, 'taskid', 24, 0, '1', 1, 0, 0, 'maxwidth500', $projectsListId); print ''; } + + // Object linked if (!empty($origin) && !empty($originid)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 8ff78fe5be0..c2c3528c869 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1820,69 +1820,76 @@ function dolGetElementUrl($objectid, $objecttype, $withpicto = 0, $option = '') $subelement = $regs[2]; } + // Generic case for $classpath $classpath = $element.'/class'; - // To work with non standard path + // Special cases, to work with non standard path if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'compta/facture/class'; $module='facture'; $subelement='facture'; } - if ($objecttype == 'commande' || $objecttype == 'order') { + elseif ($objecttype == 'commande' || $objecttype == 'order') { $classpath = 'commande/class'; $module='commande'; $subelement='commande'; } - if ($objecttype == 'propal') { + elseif ($objecttype == 'propal') { $classpath = 'comm/propal/class'; } - if ($objecttype == 'supplier_proposal') { + elseif ($objecttype == 'supplier_proposal') { $classpath = 'supplier_proposal/class'; } - if ($objecttype == 'shipping') { + elseif ($objecttype == 'shipping') { $classpath = 'expedition/class'; $subelement = 'expedition'; $module = 'expedition_bon'; } - if ($objecttype == 'delivery') { + elseif ($objecttype == 'delivery') { $classpath = 'livraison/class'; $subelement = 'livraison'; $module = 'livraison_bon'; } - if ($objecttype == 'contract') { + elseif ($objecttype == 'contract') { $classpath = 'contrat/class'; $module='contrat'; $subelement='contrat'; } - if ($objecttype == 'member') { + elseif ($objecttype == 'member') { $classpath = 'adherents/class'; $module='adherent'; $subelement='adherent'; } - if ($objecttype == 'cabinetmed_cons') { + elseif ($objecttype == 'cabinetmed_cons') { $classpath = 'cabinetmed/class'; $module='cabinetmed'; $subelement='cabinetmedcons'; } - if ($objecttype == 'fichinter') { + elseif ($objecttype == 'fichinter') { $classpath = 'fichinter/class'; $module='ficheinter'; $subelement='fichinter'; } - if ($objecttype == 'task') { + elseif ($objecttype == 'task') { $classpath = 'projet/class'; $module='projet'; $subelement='task'; } - if ($objecttype == 'stock') { + elseif ($objecttype == 'stock') { $classpath = 'product/stock/class'; $module='stock'; $subelement='stock'; } + elseif ($objecttype == 'inventory') { + $classpath = 'product/inventory/class'; + $module='stock'; + $subelement='inventory'; + } - //print "objecttype=".$objecttype." module=".$module." subelement=".$subelement; - + // Generic case for $classfile and $classname $classfile = strtolower($subelement); $classname = ucfirst($subelement); + //print "objecttype=".$objecttype." module=".$module." subelement=".$subelement." classfile=".$classfile." classname=".$classname; + if ($objecttype == 'invoice_supplier') { $classfile = 'fournisseur.facture'; $classname='FactureFournisseur'; diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 1c1d0e101b9..bf24be61023 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -219,8 +219,9 @@ foreach($object->fields as $key => $val) $sql.='t.'.$key.', '; } // Add fields from extrafields -if (! empty($extrafields->attributes[$object->table_element]['label'])) +if (! empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.' as options_'.$key.', ' : ''); +} // Add fields from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook @@ -414,7 +415,7 @@ foreach($object->fields as $key => $val) if (! empty($arrayfields['t.'.$key]['checked'])) { print ''; - if (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 0, 0, 0, '', 'maxwidth75'); + if (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth75'); else print ''; print ''; } diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index 87e6fadb57a..639b04cdbcc 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -340,6 +340,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''.$langs->trans('Modify').''."\n"; } + if ($permissiontoadd) + { + print ''.$langs->trans("Validate").''."\n"; + } + else + { + print ''.$langs->trans('Validate').''."\n"; + } + if ($permissiontodelete) { print ''.$langs->trans('Delete').''."\n"; @@ -382,7 +391,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $MAXEVENT = 10; - $morehtmlright = ''; + $morehtmlright = ''; $morehtmlright.= $langs->trans("SeeAll"); $morehtmlright.= ''; diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index 2445934b98c..e9284781a5d 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -54,22 +54,29 @@ class Inventory extends CommonObject */ public $picto = 'stock'; + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_RECORDED = 2; + const STATUS_CANCELED = 9; /** - * 'type' if the field format. + * 'type' if the field format ('integer', 'integer:Class:pathtoclass', 'varchar(x)', 'double(24,8)', 'text', 'html', 'datetime', 'timestamp', 'float') * 'label' the translation key. * 'enabled' is a condition when the field must be managed. * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'default' is a default value for creation (can still be replaced by the global setup of default values) * 'index' if we want an index in database. * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). * 'position' is the sort order of field. * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' * 'help' is a string visible as a tooltip on field * 'comment' is not used. You can store here any text of your choice. It is not used by application. - * 'default' is a default value for creation (can still be replaced by the global setup of default values) - * 'showoncombobox' if field must be shown into the label of combobox + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") */ // BEGIN MODULEBUILDER PROPERTIES @@ -85,18 +92,15 @@ class Inventory extends CommonObject 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'visible'=>1, 'enabled'=>1, 'position'=>32, 'index'=>1, 'help'=>'InventoryForASpecificProduct'), 'date_inventory' => array('type'=>'date', 'label'=>'DateValue', 'visible'=>1, 'enabled'=>1, 'position'=>35), - 'date_validation' => array('type'=>'datetime', 'label'=>'DateValidation', 'visible'=>-2, 'enabled'=>1, 'position'=>502,), - 'fk_user_valid' => array('type'=>'integer', 'label'=>'UserValidation', 'visible'=>-2, 'enabled'=>1, 'position'=>512,), - 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>500), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501), - //'date_valid' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502), + 'date_validation' => array('type'=>'datetime', 'label'=>'DateValidation', 'visible'=>-2, 'enabled'=>1, 'position'=>502), 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>510), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511), - //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>512), + 'fk_user_valid' => array('type'=>'integer', 'label'=>'UserValidation', 'visible'=>-2, 'enabled'=>1, 'position'=>512), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000), - 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>4, 'enabled'=>1, 'position'=>1000, 'default'=>0, 'arrayofkeyval'=>array(0=>'ToDo', 1=>'Done', -1=>'Cancel')), + 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>4, 'enabled'=>1, 'position'=>1000, 'default'=>0, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Recorded', -1=>'Canceled')), ); /** diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index ab1a31fe4de..c91834e54e5 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -261,13 +261,28 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (empty($reshook)) { - if ($permissiontoadd) + if ($object->status == Inventory::STATUS_DRAFT) { - print ''.$langs->trans("Validate").''."\n"; + if ($permissiontoadd) + { + print ''.$langs->trans("Validate").''."\n"; + } + else + { + print ''.$langs->trans('Validate').''."\n"; + } } - else + + if ($object->status == Inventory::STATUS_VALIDATED) { - print ''.$langs->trans('Validate').''."\n"; + if ($permissiontoadd) + { + print ''.$langs->trans("RecordVerb").''."\n"; + } + else + { + print ''.$langs->trans('RecordVerb').''."\n"; + } } } print ''."\n"; diff --git a/htdocs/product/inventory/list.php b/htdocs/product/inventory/list.php index f2e4853908d..b81e989cbb9 100644 --- a/htdocs/product/inventory/list.php +++ b/htdocs/product/inventory/list.php @@ -366,11 +366,18 @@ print ''; foreach($object->fields as $key => $val) { - $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; - if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; - if ($key == 'status') $align.=($align?' ':'').'center'; - if (! empty($arrayfields['t.'.$key]['checked'])) print ''; + $cssforfield=(empty($val['css'])?'':$val['css']); + if ($key == 'status') $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield.=($cssforfield?' ':'').'right'; + if (! empty($arrayfields['t.'.$key]['checked'])) + { + print ''; + } } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -392,11 +399,15 @@ print ''."\n"; print ''; foreach($object->fields as $key => $val) { - $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; - if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; - if ($key == 'status') $align.=($align?' ':'').'center'; - if (! empty($arrayfields['t.'.$key]['checked'])) print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($align?'class="'.$align.'"':''), $sortfield, $sortorder, $align.' ')."\n"; + $cssforfield=(empty($val['css'])?'':$val['css']); + if ($key == 'status') $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield.=($cssforfield?' ':'').'right'; + if (! empty($arrayfields['t.'.$key]['checked'])) + { + print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield?'class="'.$cssforfield.'"':''), $sortfield, $sortorder, ($cssforfield?$cssforfield.' ':''))."\n"; + } } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; From bcc41c2a3389da42e480780babbfd1e4010eefe7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Oct 2019 13:16:12 +0200 Subject: [PATCH 20/20] NEW Can filter on description on bank account transaction lists. --- htdocs/compta/bank/bankentries_list.php | 79 ++++++++++++++++--------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index cd964c7f4f4..1b0f7feffe4 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -75,15 +75,15 @@ else $result=restrictedArea($user, 'banque'); } -$description=GETPOST("description", 'alpha'); $dateop = dol_mktime(12, 0, 0, GETPOST("opmonth", 'int'), GETPOST("opday", 'int'), GETPOST("opyear", 'int')); -$debit=GETPOST("debit", 'alpha'); -$credit=GETPOST("credit", 'alpha'); +$search_debit=GETPOST("search_debit", 'alpha'); +$search_credit=GETPOST("search_credit", 'alpha'); $search_type=GETPOST("search_type", 'alpha'); $search_account=GETPOST("search_account", 'int')?GETPOST("search_account", 'int'):GETPOST("account", 'int'); $search_accountancy_code=GETPOST('search_accountancy_code', 'alpha')?GETPOST('search_accountancy_code', 'alpha'):GETPOST('accountancy_code', 'alpha'); $search_bid=GETPOST("search_bid", "int")?GETPOST("search_bid", "int"):GETPOST("bid", "int"); $search_ref=GETPOST('search_ref', 'alpha'); +$search_description=GETPOST("search_description", 'alpha'); $search_dt_start = dol_mktime(0, 0, 0, GETPOST('search_start_dtmonth', 'int'), GETPOST('search_start_dtday', 'int'), GETPOST('search_start_dtyear', 'int')); $search_dt_end = dol_mktime(0, 0, 0, GETPOST('search_end_dtmonth', 'int'), GETPOST('search_end_dtday', 'int'), GETPOST('search_end_dtyear', 'int')); $search_dv_start = dol_mktime(0, 0, 0, GETPOST('search_start_dvmonth', 'int'), GETPOST('search_start_dvday', 'int'), GETPOST('search_start_dvyear', 'int')); @@ -142,7 +142,7 @@ $search_array_options=$extrafields->getOptionalsFromPost('banktransaction', '', $arrayfields=array( 'b.rowid'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), - 'description'=>array('label'=>$langs->trans("Description"), 'checked'=>1), + 'b.label'=>array('label'=>$langs->trans("Description"), 'checked'=>1), 'b.dateo'=>array('label'=>$langs->trans("DateOperationShort"), 'checked'=>1), 'b.datev'=>array('label'=>$langs->trans("DateValueShort"), 'checked'=>1), 'type'=>array('label'=>$langs->trans("Type"), 'checked'=>1), @@ -186,13 +186,13 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_dt_end=''; $search_dv_start=''; $search_dv_end=''; - $description=""; $search_type=""; - $debit=""; - $credit=""; + $search_debit=""; + $search_credit=""; $search_bid=""; $search_ref=""; $search_req_nb=''; + $search_description=''; $search_thirdparty=''; $search_num_releve=''; $search_conciliated=''; @@ -263,6 +263,7 @@ if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', ' if ($offset) $param.='&offset='.urlencode($offset); if ($search_thirdparty) $param.='&search_thirdparty='.urlencode($search_thirdparty); if ($search_num_releve) $param.='&search_num_releve='.urlencode($search_num_releve); + if ($search_description) $param.='&search_description='.urlencode($search_description); if ($search_start_dt) $param.='&search_start_dt='.urlencode($search_start_dt); if ($search_end_dt) $param.='&search_end_dt='.urlencode($search_end_dt); if ($search_start_dv) $param.='&search_start_dv='.urlencode($search_start_dv); @@ -393,11 +394,11 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($lim if ($id > 0) $param.='&id='.urlencode($id); if (!empty($ref)) $param.='&ref='.urlencode($ref); if (!empty($search_ref)) $param.='&search_ref='.urlencode($search_ref); -if (!empty($description)) $param.='&description='.urlencode($description); +if (!empty($search_description)) $param.='&search_description='.urlencode($search_description); if (!empty($search_type)) $param.='&type='.urlencode($search_type); if (!empty($search_thirdparty)) $param.='&search_thirdparty='.urlencode($search_thirdparty); -if (!empty($debit)) $param.='&debit='.urlencode($debit); -if (!empty($credit)) $param.='&credit='.urlencode($credit); +if (!empty($search_debit)) $param.='&search_debit='.urlencode($search_debit); +if (!empty($search_credit)) $param.='&search_credit='.urlencode($search_credit); if (!empty($search_account)) $param.='&search_account='.urlencode($search_account); if (!empty($search_num_releve)) $param.='&search_num_releve='.urlencode($search_num_releve); if ($search_conciliated != '' && $search_conciliated != '-1') $param.='&search_conciliated='.urlencode($search_conciliated); @@ -498,14 +499,36 @@ if ($search_req_nb) $sql.= natural_search("b.num_chq", $search_req_nb); if ($search_num_releve) $sql.= natural_search("b.num_releve", $search_num_releve); if ($search_conciliated != '' && $search_conciliated != '-1') $sql.= " AND b.rappro = ".$search_conciliated; if ($search_thirdparty) $sql.= natural_search("s.nom", $search_thirdparty); -if ($description) $sql.= natural_search("b.label", $description); // Warning some text are just translation keys, not translated strings +if ($search_description) +{ + $search_description_to_use = $search_description; + $arrayoffixedlabels=array( + 'payment_salary', + 'CustomerInvoicePayment', 'CustomerInvoicePaymentBack', + 'SupplierInvoicePayment', 'SupplierInvoicePaymentBack', + 'DonationPayment', + 'ExpenseReportPayment', + 'SocialContributionPayment', + 'SubscriptionPayment', + 'WithdrawalPayment' + ); + foreach($arrayoffixedlabels as $keyforlabel) + { + $translatedlabel = $langs->transnoentitiesnoconv($keyforlabel); + if (preg_match('/'.$search_description.'/i', $translatedlabel)) + { + $search_description_to_use.="|".$keyforlabel; + } + } + $sql.= natural_search("b.label", $search_description_to_use); // Warning some text are just translation keys, not translated strings +} if ($search_bid > 0) $sql.= " AND b.rowid=l.lineid AND l.fk_categ=".$search_bid; if (! empty($search_type)) $sql.= " AND b.fk_type = '".$db->escape($search_type)."' "; // Search criteria amount -$debit = price2num(str_replace('-', '', $debit)); -$credit = price2num(str_replace('-', '', $credit)); -if ($debit) $sql.= natural_search('- b.amount', $debit, 1); -if ($credit) $sql.= natural_search('b.amount', $credit, 1); +$search_debit = price2num(str_replace('-', '', $search_debit)); +$search_credit = price2num(str_replace('-', '', $search_credit)); +if ($search_debit) $sql.= natural_search('- b.amount', $search_debit, 1); +if ($search_credit) $sql.= natural_search('b.amount', $search_credit, 1); // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -853,10 +876,10 @@ if ($resql) print ''; print ''; } - if (! empty($arrayfields['description']['checked'])) + if (! empty($arrayfields['b.label']['checked'])) { print ''; } if (! empty($arrayfields['b.dateo']['checked'])) @@ -891,13 +914,13 @@ if ($resql) if (! empty($arrayfields['b.debit']['checked'])) { print ''; } if (! empty($arrayfields['b.credit']['checked'])) { print ''; } if (! empty($arrayfields['balancebefore']['checked'])) @@ -937,7 +960,7 @@ if ($resql) // Fields title print ''; if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'], $_SERVER['PHP_SELF'], 'b.rowid', '', $param, '', $sortfield, $sortorder); - if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder); + if (! empty($arrayfields['b.label']['checked'])) print_liste_field_titre($arrayfields['b.label']['label'], $_SERVER['PHP_SELF'], 'b.label', '', $param, '', $sortfield, $sortorder); if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'], $_SERVER['PHP_SELF'], 'b.dateo', '', $param, '', $sortfield, $sortorder, "center "); if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'], $_SERVER['PHP_SELF'], 'b.datev,b.dateo,b.rowid', '', $param, 'align="center"', $sortfield, $sortorder); if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'align="center"', $sortfield, $sortorder); @@ -1142,7 +1165,7 @@ if ($resql) } // Description - if (! empty($arrayfields['description']['checked'])) + if (! empty($arrayfields['b.label']['checked'])) { print "'; } + // If no record found + if ($num == 0) + { + $colspan=1; + foreach($arrayfields as $key => $val) { if (! empty($val['checked'])) $colspan++; } + print ''; + } + print "
'; + if (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth75'); + else print ''; + print '
'; - //print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print '
"; @@ -1557,6 +1580,14 @@ if ($resql) print '
'.$langs->trans("NoRecordFound").'
"; print ""; @@ -1568,12 +1599,6 @@ else dol_print_error($db); } -// If no data to display after a search -if ($_POST["action"] == "search" && ! $num) -{ - print '
'.$langs->trans("NoRecordFound").'
'; -} - // End of page llxFooter(); $db->close();