diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index 66f2e156b4ca4a26811802acd878e1f979e834d8..03565528fc19f02f3ea8dc591b921afafe4b76b5 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -158,309 +158,309 @@ $sourceList=array(); if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x')) { - $search_country_id = ''; + $search_country_id = ''; } // Actions add or modify an entry into a dictionary if (GETPOST('actionadd') || GETPOST('actionmodify')) { - $listfield=explode(',', str_replace(' ', '',$tabfield[$id])); - $listfieldinsert=explode(',',$tabfieldinsert[$id]); - $listfieldmodify=explode(',',$tabfieldinsert[$id]); - $listfieldvalue=explode(',',$tabfieldvalue[$id]); - - // Check that all fields are filled - $ok=1; - foreach ($listfield as $f => $value) - { - if ($value == 'country_id' && in_array($tablib[$id],array('DictionaryVAT','DictionaryRegion','DictionaryCompanyType','DictionaryHolidayTypes','DictionaryRevenueStamp','DictionaryAccountancysystem','DictionaryAccountancyCategory'))) continue; // For some pages, country is not mandatory - if ($value == 'country' && in_array($tablib[$id],array('DictionaryCanton','DictionaryCompanyType','DictionaryRevenueStamp'))) continue; // For some pages, country is not mandatory - if ($value == 'localtax1' && empty($_POST['localtax1_type'])) continue; - if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue; - if ($value == 'color' && empty($_POST['color'])) continue; + $listfield=explode(',', str_replace(' ', '',$tabfield[$id])); + $listfieldinsert=explode(',',$tabfieldinsert[$id]); + $listfieldmodify=explode(',',$tabfieldinsert[$id]); + $listfieldvalue=explode(',',$tabfieldvalue[$id]); + + // Check that all fields are filled + $ok=1; + foreach ($listfield as $f => $value) + { + if ($value == 'country_id' && in_array($tablib[$id],array('DictionaryVAT','DictionaryRegion','DictionaryCompanyType','DictionaryHolidayTypes','DictionaryRevenueStamp','DictionaryAccountancysystem','DictionaryAccountancyCategory'))) continue; // For some pages, country is not mandatory + if ($value == 'country' && in_array($tablib[$id],array('DictionaryCanton','DictionaryCompanyType','DictionaryRevenueStamp'))) continue; // For some pages, country is not mandatory + if ($value == 'localtax1' && empty($_POST['localtax1_type'])) continue; + if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue; + if ($value == 'color' && empty($_POST['color'])) continue; if ($value == 'formula' && empty($_POST['formula'])) continue; - if ((! isset($_POST[$value]) || $_POST[$value]=='') - && (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy')) // Fields that are not mandatory - && (! ($id == 10 && $listfield[$f] == 'code')) // Code is mandatory fir table 10 - ) + if ((! isset($_POST[$value]) || $_POST[$value]=='') + && (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy')) // Fields that are not mandatory + && (! ($id == 10 && $listfield[$f] == 'code')) // Code is mandatory fir table 10 + ) ) - { - $ok=0; - $fieldnamekey=$listfield[$f]; - // We take translate key of field - if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) $fieldnamekey='Label'; - if ($fieldnamekey == 'libelle_facture') $fieldnamekey = 'LabelOnDocuments'; - if ($fieldnamekey == 'nbjour') $fieldnamekey='NbOfDays'; - if ($fieldnamekey == 'decalage') $fieldnamekey='Offset'; - if ($fieldnamekey == 'module') $fieldnamekey='Module'; - if ($fieldnamekey == 'code') $fieldnamekey = 'Code'; - if ($fieldnamekey == 'note') $fieldnamekey = 'Note'; - if ($fieldnamekey == 'taux') $fieldnamekey = 'Rate'; - if ($fieldnamekey == 'type') $fieldnamekey = 'Type'; - if ($fieldnamekey == 'position') $fieldnamekey = 'Position'; - if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode'; - if ($fieldnamekey == 'deductible') $fieldnamekey = 'Deductible'; - if ($fieldnamekey == 'sortorder') $fieldnamekey = 'SortOrder'; + { + $ok=0; + $fieldnamekey=$listfield[$f]; + // We take translate key of field + if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) $fieldnamekey='Label'; + if ($fieldnamekey == 'libelle_facture') $fieldnamekey = 'LabelOnDocuments'; + if ($fieldnamekey == 'nbjour') $fieldnamekey='NbOfDays'; + if ($fieldnamekey == 'decalage') $fieldnamekey='Offset'; + if ($fieldnamekey == 'module') $fieldnamekey='Module'; + if ($fieldnamekey == 'code') $fieldnamekey = 'Code'; + if ($fieldnamekey == 'note') $fieldnamekey = 'Note'; + if ($fieldnamekey == 'taux') $fieldnamekey = 'Rate'; + if ($fieldnamekey == 'type') $fieldnamekey = 'Type'; + if ($fieldnamekey == 'position') $fieldnamekey = 'Position'; + if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode'; + if ($fieldnamekey == 'deductible') $fieldnamekey = 'Deductible'; + if ($fieldnamekey == 'sortorder') $fieldnamekey = 'SortOrder'; if ($fieldnamekey == 'category_type') $fieldnamekey = 'Calculated'; - setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); - } - } - // Other checks - if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && isset($_POST["type"]) && in_array($_POST["type"],array('system','systemauto'))) { - $ok=0; - setEventMessages($langs->transnoentities('ErrorReservedTypeSystemSystemAuto'), null, 'errors'); - } - if (isset($_POST["code"])) - { - if ($_POST["code"]=='0') - { - $ok=0; - setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); - } - /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base + setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); + } + } + // Other checks + if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && isset($_POST["type"]) && in_array($_POST["type"],array('system','systemauto'))) { + $ok=0; + setEventMessages($langs->transnoentities('ErrorReservedTypeSystemSystemAuto'), null, 'errors'); + } + if (isset($_POST["code"])) + { + if ($_POST["code"]=='0') + { + $ok=0; + setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); + } + /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base { $ok = 0; $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'<br>'; }*/ - } - if (isset($_POST["country"]) && ($_POST["country"]=='0') && ($id != 2)) - { - if (in_array($tablib[$id],array('DictionaryCompanyType','DictionaryHolidayTypes'))) // Field country is no mandatory for such dictionaries - { - $_POST["country"]=''; - } - else - { - $ok=0; - setEventMessages($langs->transnoentities("ErrorFieldRequired",$langs->transnoentities("Country")), null, 'errors'); - } - } - if ($id == 3 && ! is_numeric($_POST["code"])) - { - $ok=0; - setEventMessages($langs->transnoentities("ErrorFieldMustBeANumeric",$langs->transnoentities("Code")), null, 'errors'); - } + } + if (isset($_POST["country"]) && ($_POST["country"]=='0') && ($id != 2)) + { + if (in_array($tablib[$id],array('DictionaryCompanyType','DictionaryHolidayTypes'))) // Field country is no mandatory for such dictionaries + { + $_POST["country"]=''; + } + else + { + $ok=0; + setEventMessages($langs->transnoentities("ErrorFieldRequired",$langs->transnoentities("Country")), null, 'errors'); + } + } + if ($id == 3 && ! is_numeric($_POST["code"])) + { + $ok=0; + setEventMessages($langs->transnoentities("ErrorFieldMustBeANumeric",$langs->transnoentities("Code")), null, 'errors'); + } // Clean some parameters - if (isset($_POST["localtax1"]) && empty($_POST["localtax1"])) $_POST["localtax1"]='0'; // If empty, we force to 0 - if (isset($_POST["localtax2"]) && empty($_POST["localtax2"])) $_POST["localtax2"]='0'; // If empty, we force to 0 + if (isset($_POST["localtax1"]) && empty($_POST["localtax1"])) $_POST["localtax1"]='0'; // If empty, we force to 0 + if (isset($_POST["localtax2"]) && empty($_POST["localtax2"])) $_POST["localtax2"]='0'; // If empty, we force to 0 if ($_POST["accountancy_code"] <= 0) $_POST["accountancy_code"]=''; // If empty, we force to null if ($_POST["accountancy_code_sell"] <= 0) $_POST["accountancy_code_sell"]=''; // If empty, we force to null if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"]=''; // If empty, we force to null - // Si verif ok et action add, on ajoute la ligne - if ($ok && GETPOST('actionadd')) - { - if ($tabrowid[$id]) - { - // Recupere id libre pour insertion - $newid=0; - $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; - $result = $db->query($sql); - if ($result) - { - $obj = $db->fetch_object($result); - $newid=($obj->newid + 1); - - } else { - dol_print_error($db); - } - } - - // Add new entry - $sql = "INSERT INTO ".$tabname[$id]." ("; - // List of fields - if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) - $sql.= $tabrowid[$id].","; - $sql.= $tabfieldinsert[$id]; - $sql.=",active)"; - $sql.= " VALUES("; - - // List of values - if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) - $sql.= $newid.","; - $i=0; - foreach ($listfieldinsert as $f => $value) - { - if ($value == 'price' || preg_match('/^amount/i',$value) || $value == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]],'MU'); - } - else if ($value == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } - if ($i) $sql.=","; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; - $i++; - } - $sql.=",1)"; - - dol_syslog("actionadd", LOG_DEBUG); - $result = $db->query($sql); - if ($result) // Add is ok - { - setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); - $_POST=array('id'=>$id); // Clean $_POST array, we keep only - } - else - { - if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); - } - else { - dol_print_error($db); - } - } - } - - // Si verif ok et action modify, on modifie la ligne - if ($ok && GETPOST('actionmodify')) - { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - // Modify entry - $sql = "UPDATE ".$tabname[$id]." SET "; - // Modifie valeur des champs - if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldmodify)) - { - $sql.= $tabrowid[$id]."="; - $sql.= "'".$db->escape($rowid)."', "; - } - $i = 0; - foreach ($listfieldmodify as $field) - { - if ($field == 'price' || preg_match('/^amount/i',$field) || $field == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]],'MU'); - } - else if ($field == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } - if ($i) $sql.=","; - $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; - $i++; - } - $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; - - dol_syslog("actionmodify", LOG_DEBUG); - //print $sql; - $resql = $db->query($sql); - if (! $resql) - { - setEventMessages($db->error(), null, 'errors'); - } - } - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition + // Si verif ok et action add, on ajoute la ligne + if ($ok && GETPOST('actionadd')) + { + if ($tabrowid[$id]) + { + // Recupere id libre pour insertion + $newid=0; + $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; + $result = $db->query($sql); + if ($result) + { + $obj = $db->fetch_object($result); + $newid=($obj->newid + 1); + + } else { + dol_print_error($db); + } + } + + // Add new entry + $sql = "INSERT INTO ".$tabname[$id]." ("; + // List of fields + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) + $sql.= $tabrowid[$id].","; + $sql.= $tabfieldinsert[$id]; + $sql.=",active)"; + $sql.= " VALUES("; + + // List of values + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) + $sql.= $newid.","; + $i=0; + foreach ($listfieldinsert as $f => $value) + { + if ($value == 'price' || preg_match('/^amount/i',$value) || $value == 'taux') { + $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]],'MU'); + } + else if ($value == 'entity') { + $_POST[$listfieldvalue[$i]] = $conf->entity; + } + if ($i) $sql.=","; + if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; + else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $i++; + } + $sql.=",1)"; + + dol_syslog("actionadd", LOG_DEBUG); + $result = $db->query($sql); + if ($result) // Add is ok + { + setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); + $_POST=array('id'=>$id); // Clean $_POST array, we keep only + } + else + { + if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); + } + else { + dol_print_error($db); + } + } + } + + // Si verif ok et action modify, on modifie la ligne + if ($ok && GETPOST('actionmodify')) + { + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + // Modify entry + $sql = "UPDATE ".$tabname[$id]." SET "; + // Modifie valeur des champs + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldmodify)) + { + $sql.= $tabrowid[$id]."="; + $sql.= "'".$db->escape($rowid)."', "; + } + $i = 0; + foreach ($listfieldmodify as $field) + { + if ($field == 'price' || preg_match('/^amount/i',$field) || $field == 'taux') { + $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]],'MU'); + } + else if ($field == 'entity') { + $_POST[$listfieldvalue[$i]] = $conf->entity; + } + if ($i) $sql.=","; + $sql.= $field."="; + if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; + else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $i++; + } + $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; + + dol_syslog("actionmodify", LOG_DEBUG); + //print $sql; + $resql = $db->query($sql); + if (! $resql) + { + setEventMessages($db->error(), null, 'errors'); + } + } + //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } if (GETPOST('actioncancel')) { - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition + //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } if ($action == 'confirm_delete' && $confirm == 'yes') // delete { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."='".$rowid."'"; - - dol_syslog("delete", LOG_DEBUG); - $result = $db->query($sql); - if (! $result) - { - if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') - { - setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); - } - else - { - dol_print_error($db); - } - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."='".$rowid."'"; + + dol_syslog("delete", LOG_DEBUG); + $result = $db->query($sql); + if (! $result) + { + if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') + { + setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); + } + else + { + dol_print_error($db); + } + } } // activate if ($action == $acts[0]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$rowid."'"; - } - elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".$code."'"; - } - - $result = $db->query($sql); - if (!$result) - { - dol_print_error($db); - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".$code."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } } // disable if ($action == $acts[1]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$rowid."'"; - } - elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".$code."'"; - } - - $result = $db->query($sql); - if (!$result) - { - dol_print_error($db); - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".$code."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } } // favorite if ($action == 'activate_favorite') { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE ".$rowidcol."='".$rowid."'"; - } - elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE code='".$code."'"; - } - - $result = $db->query($sql); - if (!$result) - { - dol_print_error($db); - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE code='".$code."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } } // disable favorite if ($action == 'disable_favorite') { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE ".$rowidcol."='".$rowid."'"; - } - elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE code='".$code."'"; - } - - $result = $db->query($sql); - if (!$result) - { - dol_print_error($db); - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE code='".$code."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } } @@ -480,8 +480,8 @@ print load_fiche_titre($titre,$linkback,'title_accountancy'); if (empty($id)) { - print $langs->trans("DictionaryDesc"); - print " ".$langs->trans("OnlyActiveElementsAreShown")."<br>\n"; + print $langs->trans("DictionaryDesc"); + print " ".$langs->trans("OnlyActiveElementsAreShown")."<br>\n"; } print "<br>\n"; @@ -489,7 +489,7 @@ print "<br>\n"; // Confirmation de la suppression de la ligne if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete','',0,1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete','',0,1); } //var_dump($elementList); @@ -498,557 +498,557 @@ if ($action == 'delete') */ if ($id) { - // Complete requete recherche valeurs avec critere de tri - $sql=$tabsql[$id]; - - if ($search_country_id > 0) - { - if (preg_match('/ WHERE /',$sql)) $sql.= " AND "; - else $sql.=" WHERE "; - $sql.= " c.rowid = ".$search_country_id; - } - - if ($sortfield) - { - // If sort order is "country", we use country_code instead - if ($sortfield == 'country') $sortfield='country_code'; - $sql.= " ORDER BY ".$sortfield; - if ($sortorder) - { - $sql.=" ".strtoupper($sortorder); - } - $sql.=", "; - // Clear the required sort criteria for the tabsqlsort to be able to force it with selected value - $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.' '.$sortorder.',/i','',$tabsqlsort[$id]); - $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.',/i','',$tabsqlsort[$id]); - } - else { - $sql.=" ORDER BY "; - } - $sql.=$tabsqlsort[$id]; - $sql.=$db->plimit($listlimit+1,$offset); - //print $sql; - - $fieldlist=explode(',',$tabfield[$id]); - - print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + // Complete requete recherche valeurs avec critere de tri + $sql=$tabsql[$id]; + + if ($search_country_id > 0) + { + if (preg_match('/ WHERE /',$sql)) $sql.= " AND "; + else $sql.=" WHERE "; + $sql.= " c.rowid = ".$search_country_id; + } + + if ($sortfield) + { + // If sort order is "country", we use country_code instead + if ($sortfield == 'country') $sortfield='country_code'; + $sql.= " ORDER BY ".$sortfield; + if ($sortorder) + { + $sql.=" ".strtoupper($sortorder); + } + $sql.=", "; + // Clear the required sort criteria for the tabsqlsort to be able to force it with selected value + $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.' '.$sortorder.',/i','',$tabsqlsort[$id]); + $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.',/i','',$tabsqlsort[$id]); + } + else { + $sql.=" ORDER BY "; + } + $sql.=$tabsqlsort[$id]; + $sql.=$db->plimit($listlimit+1,$offset); + //print $sql; + + $fieldlist=explode(',',$tabfield[$id]); + + print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; print '<div class="div-table-responsive">'; - print '<table class="noborder" width="100%">'; - - // Form to add a new line - if ($tabname[$id]) - { - $alabelisused=0; - $var=false; - - $fieldlist=explode(',',$tabfield[$id]); - - // Line for title - print '<tr class="liste_titre">'; - foreach ($fieldlist as $field => $value) - { - // Determine le nom du champ par rapport aux noms possibles - // dans les dictionnaires de donnees - $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut - $valuetoshow=$langs->trans($valuetoshow); // try to translate - $align="left"; - if ($fieldlist[$field]=='source') { $valuetoshow=$langs->trans("Contact"); } - if ($fieldlist[$field]=='price') { $valuetoshow=$langs->trans("PriceUHT"); } - if ($fieldlist[$field]=='taux') { + print '<table class="noborder" width="100%">'; + + // Form to add a new line + if ($tabname[$id]) + { + $alabelisused=0; + $var=false; + + $fieldlist=explode(',',$tabfield[$id]); + + // Line for title + print '<tr class="liste_titre">'; + foreach ($fieldlist as $field => $value) + { + // Determine le nom du champ par rapport aux noms possibles + // dans les dictionnaires de donnees + $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut + $valuetoshow=$langs->trans($valuetoshow); // try to translate + $align="left"; + if ($fieldlist[$field]=='source') { $valuetoshow=$langs->trans("Contact"); } + if ($fieldlist[$field]=='price') { $valuetoshow=$langs->trans("PriceUHT"); } + if ($fieldlist[$field]=='taux') { if ($tabname[$id] != MAIN_DB_PREFIX."c_revenuestamp") $valuetoshow=$langs->trans("Rate"); else $valuetoshow=$langs->trans("Amount"); $align='right'; - } - if ($fieldlist[$field]=='localtax1_type') { $valuetoshow=$langs->trans("UseLocalTax")." 2"; $align="center"; $sortable=0; } - if ($fieldlist[$field]=='localtax1') { $valuetoshow=$langs->trans("Rate")." 2";} - if ($fieldlist[$field]=='localtax2_type') { $valuetoshow=$langs->trans("UseLocalTax")." 3"; $align="center"; $sortable=0; } - if ($fieldlist[$field]=='localtax2') { $valuetoshow=$langs->trans("Rate")." 3";} - if ($fieldlist[$field]=='organization') { $valuetoshow=$langs->trans("Organization"); } - if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } - if ($fieldlist[$field]=='type') { + } + if ($fieldlist[$field]=='localtax1_type') { $valuetoshow=$langs->trans("UseLocalTax")." 2"; $align="center"; $sortable=0; } + if ($fieldlist[$field]=='localtax1') { $valuetoshow=$langs->trans("Rate")." 2";} + if ($fieldlist[$field]=='localtax2_type') { $valuetoshow=$langs->trans("UseLocalTax")." 3"; $align="center"; $sortable=0; } + if ($fieldlist[$field]=='localtax2') { $valuetoshow=$langs->trans("Rate")." 3";} + if ($fieldlist[$field]=='organization') { $valuetoshow=$langs->trans("Organization"); } + if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } + if ($fieldlist[$field]=='type') { if ($tabname[$id] == MAIN_DB_PREFIX."c_paiement") $valuetoshow=$form->textwithtooltip($langs->trans("Type"),$langs->trans("TypePaymentDesc"),2,1,img_help(1,'')); else $valuetoshow=$langs->trans("Type"); - } - if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') - { - $valuetoshow=$langs->trans("Label"); - if ($id != 25) $valuetoshow.="*"; - } - if ($fieldlist[$field]=='libelle_facture') { $valuetoshow=$langs->trans("LabelOnDocuments")."*"; } - if ($fieldlist[$field]=='country') { - if (in_array('region_id',$fieldlist)) { print '<td> </td>'; continue; } // For region page, we do not show the country input - $valuetoshow=$langs->trans("Country"); - } - if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; } - if ($fieldlist[$field]=='nbjour') { $valuetoshow=$langs->trans("NbOfDays"); } - if ($fieldlist[$field]=='type_cdr') { $valuetoshow=$langs->trans("AtEndOfMonth"); $align="center"; } - if ($fieldlist[$field]=='decalage') { $valuetoshow=$langs->trans("Offset"); } - if ($fieldlist[$field]=='width') { $valuetoshow=$langs->trans("Width"); } - if ($fieldlist[$field]=='height') { $valuetoshow=$langs->trans("Height"); } - if ($fieldlist[$field]=='unit') { $valuetoshow=$langs->trans("MeasuringUnit"); } - if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $valuetoshow=''; } - if ($fieldlist[$field]=='accountancy_code'){ $valuetoshow=$langs->trans("AccountancyCode"); } - if ($fieldlist[$field]=='accountancy_code_sell'){ $valuetoshow=$langs->trans("AccountancyCodeSell"); } - if ($fieldlist[$field]=='accountancy_code_buy'){ $valuetoshow=$langs->trans("AccountancyCodeBuy"); } - if ($fieldlist[$field]=='pcg_version' || $fieldlist[$field]=='fk_pcg_version') { $valuetoshow=$langs->trans("Pcg_version"); } - if ($fieldlist[$field]=='account_parent') { $valuetoshow=$langs->trans("Accountparent"); } - if ($fieldlist[$field]=='pcg_type') { $valuetoshow=$langs->trans("Pcg_type"); } - if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } - if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } - if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } - if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } + } + if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') + { + $valuetoshow=$langs->trans("Label"); + if ($id != 25) $valuetoshow.="*"; + } + if ($fieldlist[$field]=='libelle_facture') { $valuetoshow=$langs->trans("LabelOnDocuments")."*"; } + if ($fieldlist[$field]=='country') { + if (in_array('region_id',$fieldlist)) { print '<td> </td>'; continue; } // For region page, we do not show the country input + $valuetoshow=$langs->trans("Country"); + } + if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; } + if ($fieldlist[$field]=='nbjour') { $valuetoshow=$langs->trans("NbOfDays"); } + if ($fieldlist[$field]=='type_cdr') { $valuetoshow=$langs->trans("AtEndOfMonth"); $align="center"; } + if ($fieldlist[$field]=='decalage') { $valuetoshow=$langs->trans("Offset"); } + if ($fieldlist[$field]=='width') { $valuetoshow=$langs->trans("Width"); } + if ($fieldlist[$field]=='height') { $valuetoshow=$langs->trans("Height"); } + if ($fieldlist[$field]=='unit') { $valuetoshow=$langs->trans("MeasuringUnit"); } + if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $valuetoshow=''; } + if ($fieldlist[$field]=='accountancy_code'){ $valuetoshow=$langs->trans("AccountancyCode"); } + if ($fieldlist[$field]=='accountancy_code_sell'){ $valuetoshow=$langs->trans("AccountancyCodeSell"); } + if ($fieldlist[$field]=='accountancy_code_buy'){ $valuetoshow=$langs->trans("AccountancyCodeBuy"); } + if ($fieldlist[$field]=='pcg_version' || $fieldlist[$field]=='fk_pcg_version') { $valuetoshow=$langs->trans("Pcg_version"); } + if ($fieldlist[$field]=='account_parent') { $valuetoshow=$langs->trans("Accountparent"); } + if ($fieldlist[$field]=='pcg_type') { $valuetoshow=$langs->trans("Pcg_type"); } + if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } + if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } + if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } + if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } if ($fieldlist[$field]=='range_account') { $valuetoshow=$langs->trans("Range"); } if ($fieldlist[$field]=='sens') { $valuetoshow=$langs->trans("Sens"); } if ($fieldlist[$field]=='category_type') { $valuetoshow=$langs->trans("Calculated"); } if ($fieldlist[$field]=='formula') { $valuetoshow=$langs->trans("Formula"); } - if ($id == 2) // Special cas for state page - { - if ($fieldlist[$field]=='region_id') { $valuetoshow=' '; $showfield=1; } - if ($fieldlist[$field]=='region') { $valuetoshow=$langs->trans("Country").'/'.$langs->trans("Region"); $showfield=1; } - } - - if ($valuetoshow != '') - { - print '<td align="'.$align.'">'; - if (! empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i',$tabhelp[$id][$value])) print '<a href="'.$tabhelp[$id][$value].'" target="_blank">'.$valuetoshow.' '.img_help(1,$valuetoshow).'</a>'; - else if (! empty($tabhelp[$id][$value])) print $form->textwithpicto($valuetoshow,$tabhelp[$id][$value]); - else print $valuetoshow; - print '</td>'; - } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $alabelisused=1; - } - - print '<td>'; - print '<input type="hidden" name="id" value="'.$id.'">'; - print '</td>'; - print '<td style="min-width: 26px;"></td>'; - print '<td style="min-width: 26px;"></td>'; - print '</tr>'; - - // Line to enter new values - print "<tr ".$bcnd[$var].">"; - - $obj = new stdClass(); - // If data was already input, we define them in obj to populate input fields. - if (GETPOST('actionadd')) - { - foreach ($fieldlist as $key=>$val) - { - if (GETPOST($val)) - $obj->$val=GETPOST($val); - } - } - - $tmpaction = 'create'; - $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('createDictionaryFieldlist',$parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; - - if ($id == 3) unset($fieldlist[2]); - - if (empty($reshook)) - { - if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates' && $action == 'edit') - { + if ($id == 2) // Special cas for state page + { + if ($fieldlist[$field]=='region_id') { $valuetoshow=' '; $showfield=1; } + if ($fieldlist[$field]=='region') { $valuetoshow=$langs->trans("Country").'/'.$langs->trans("Region"); $showfield=1; } + } + + if ($valuetoshow != '') + { + print '<td align="'.$align.'">'; + if (! empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i',$tabhelp[$id][$value])) print '<a href="'.$tabhelp[$id][$value].'" target="_blank">'.$valuetoshow.' '.img_help(1,$valuetoshow).'</a>'; + else if (! empty($tabhelp[$id][$value])) print $form->textwithpicto($valuetoshow,$tabhelp[$id][$value]); + else print $valuetoshow; + print '</td>'; + } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $alabelisused=1; + } + + print '<td>'; + print '<input type="hidden" name="id" value="'.$id.'">'; + print '</td>'; + print '<td style="min-width: 26px;"></td>'; + print '<td style="min-width: 26px;"></td>'; + print '</tr>'; + + // Line to enter new values + print "<tr ".$bcnd[$var].">"; + + $obj = new stdClass(); + // If data was already input, we define them in obj to populate input fields. + if (GETPOST('actionadd')) + { + foreach ($fieldlist as $key=>$val) + { + if (GETPOST($val)) + $obj->$val=GETPOST($val); + } + } + + $tmpaction = 'create'; + $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('createDictionaryFieldlist',$parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error=$hookmanager->error; $errors=$hookmanager->errors; + + if ($id == 3) unset($fieldlist[2]); + + if (empty($reshook)) + { + if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates' && $action == 'edit') + { fieldListAccountModel($fieldlist,$obj,$tabname[$id],'hide'); - } - else - { - fieldListAccountModel($fieldlist,$obj,$tabname[$id],'add'); - } - } - - print '<td colspan="3" align="right">'; - if ($tabname[$id] != MAIN_DB_PREFIX.'c_email_templates' || $action != 'edit') - { - print '<input type="submit" class="button" name="actionadd" value="'.$langs->trans("Add").'">'; - } - print '</td>'; - print "</tr>"; - - $colspan=count($fieldlist)+3; - - if (! empty($alabelisused)) // If there is one label among fields, we show legend of * - { - print '<tr><td colspan="'.$colspan.'">* '.$langs->trans("LabelUsedByDefault").'.</td></tr>'; - } - print '<tr><td colspan="'.$colspan.'"> </td></tr>'; // Keep to have a line with enough height - } - - - - // List of available values in database - dol_syslog("htdocs/admin/dict", LOG_DEBUG); - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - $var=true; - - $param = '&id='.$id; - if ($search_country_id > 0) $param.= '&search_country_id='.$search_country_id; - $paramwithsearch = $param; - if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder; - if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield; - - // There is several pages - if ($num > $listlimit) - { - print '<tr class="none"><td align="right" colspan="'.(3+count($fieldlist)).'">'; - print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), '<li class="pagination"><span>'.$langs->trans("Page").' '.($page+1).'</span></li>'); - print '</td></tr>'; - } - - // Title line with search boxes - print '<tr class="liste_titre liste_titre_add">'; - foreach ($fieldlist as $field => $value) - { - $showfield=1; // By defaut - - if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } - - if ($showfield) - { - if ($value == 'country') - { - print '<td class="liste_titre">'; - print $form->select_country($search_country_id, 'search_country_id', '', 28, 'maxwidth200 maxwidthonsmartphone'); - print '</td>'; - } - else - { - print '<td class="liste_titre"></td>'; - } - } - } - print '<td class="liste_titre"></td>'; - print '<td class="liste_titre" colspan="2" align="right">'; - $searchpicto=$form->showFilterAndCheckAddButtons(0); - print $searchpicto; - print '</td>'; - print '</tr>'; - - // Title of lines - print '<tr class="liste_titre">'; - foreach ($fieldlist as $field => $value) - { - // Determine le nom du champ par rapport aux noms possibles - // dans les dictionnaires de donnees - $showfield=1; // By defaut - $align="left"; - $sortable=1; - $valuetoshow=''; - /* + } + else + { + fieldListAccountModel($fieldlist,$obj,$tabname[$id],'add'); + } + } + + print '<td colspan="3" align="right">'; + if ($tabname[$id] != MAIN_DB_PREFIX.'c_email_templates' || $action != 'edit') + { + print '<input type="submit" class="button" name="actionadd" value="'.$langs->trans("Add").'">'; + } + print '</td>'; + print "</tr>"; + + $colspan=count($fieldlist)+3; + + if (! empty($alabelisused)) // If there is one label among fields, we show legend of * + { + print '<tr><td colspan="'.$colspan.'">* '.$langs->trans("LabelUsedByDefault").'.</td></tr>'; + } + print '<tr><td colspan="'.$colspan.'"> </td></tr>'; // Keep to have a line with enough height + } + + + + // List of available values in database + dol_syslog("htdocs/admin/dict", LOG_DEBUG); + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + $var=true; + + $param = '&id='.$id; + if ($search_country_id > 0) $param.= '&search_country_id='.$search_country_id; + $paramwithsearch = $param; + if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder; + if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield; + + // There is several pages + if ($num > $listlimit) + { + print '<tr class="none"><td align="right" colspan="'.(3+count($fieldlist)).'">'; + print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), '<li class="pagination"><span>'.$langs->trans("Page").' '.($page+1).'</span></li>'); + print '</td></tr>'; + } + + // Title line with search boxes + print '<tr class="liste_titre liste_titre_add">'; + foreach ($fieldlist as $field => $value) + { + $showfield=1; // By defaut + + if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } + + if ($showfield) + { + if ($value == 'country') + { + print '<td class="liste_titre">'; + print $form->select_country($search_country_id, 'search_country_id', '', 28, 'maxwidth200 maxwidthonsmartphone'); + print '</td>'; + } + else + { + print '<td class="liste_titre"></td>'; + } + } + } + print '<td class="liste_titre"></td>'; + print '<td class="liste_titre" colspan="2" align="right">'; + $searchpicto=$form->showFilterAndCheckAddButtons(0); + print $searchpicto; + print '</td>'; + print '</tr>'; + + // Title of lines + print '<tr class="liste_titre">'; + foreach ($fieldlist as $field => $value) + { + // Determine le nom du champ par rapport aux noms possibles + // dans les dictionnaires de donnees + $showfield=1; // By defaut + $align="left"; + $sortable=1; + $valuetoshow=''; + /* $tmparray=getLabelOfField($fieldlist[$field]); $showfield=$tmp['showfield']; $valuetoshow=$tmp['valuetoshow']; $align=$tmp['align']; $sortable=$tmp['sortable']; */ - $valuetoshow=ucfirst($fieldlist[$field]); // By defaut - $valuetoshow=$langs->trans($valuetoshow); // try to translate - if ($fieldlist[$field]=='source') { $valuetoshow=$langs->trans("Contact"); } - if ($fieldlist[$field]=='price') { $valuetoshow=$langs->trans("PriceUHT"); } - if ($fieldlist[$field]=='taux') { + $valuetoshow=ucfirst($fieldlist[$field]); // By defaut + $valuetoshow=$langs->trans($valuetoshow); // try to translate + if ($fieldlist[$field]=='source') { $valuetoshow=$langs->trans("Contact"); } + if ($fieldlist[$field]=='price') { $valuetoshow=$langs->trans("PriceUHT"); } + if ($fieldlist[$field]=='taux') { if ($tabname[$id] != MAIN_DB_PREFIX."c_revenuestamp") $valuetoshow=$langs->trans("Rate"); else $valuetoshow=$langs->trans("Amount"); $align='right'; - } - if ($fieldlist[$field]=='localtax1_type') { $valuetoshow=$langs->trans("UseLocalTax")." 2"; $align="center"; $sortable=0; } - if ($fieldlist[$field]=='localtax1') { $valuetoshow=$langs->trans("Rate")." 2"; $sortable=0; } - if ($fieldlist[$field]=='localtax2_type') { $valuetoshow=$langs->trans("UseLocalTax")." 3"; $align="center"; $sortable=0; } - if ($fieldlist[$field]=='localtax2') { $valuetoshow=$langs->trans("Rate")." 3"; $sortable=0; } - if ($fieldlist[$field]=='organization') { $valuetoshow=$langs->trans("Organization"); } - if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } - if ($fieldlist[$field]=='type') { $valuetoshow=$langs->trans("Type"); } - if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') - { - $valuetoshow=$langs->trans("Label"); - if ($id != 25) $valuetoshow.="*"; - } - if ($fieldlist[$field]=='libelle_facture') { $valuetoshow=$langs->trans("LabelOnDocuments")."*"; } - if ($fieldlist[$field]=='country') { $valuetoshow=$langs->trans("Country"); } - if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; } - if ($fieldlist[$field]=='nbjour') { $valuetoshow=$langs->trans("NbOfDays"); } - if ($fieldlist[$field]=='type_cdr') { $valuetoshow=$langs->trans("AtEndOfMonth"); $align="center"; } - if ($fieldlist[$field]=='decalage') { $valuetoshow=$langs->trans("Offset"); } - if ($fieldlist[$field]=='width') { $valuetoshow=$langs->trans("Width"); } - if ($fieldlist[$field]=='height') { $valuetoshow=$langs->trans("Height"); } - if ($fieldlist[$field]=='unit') { $valuetoshow=$langs->trans("MeasuringUnit"); } - if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } - if ($fieldlist[$field]=='accountancy_code'){ $valuetoshow=$langs->trans("AccountancyCode"); } - if ($fieldlist[$field]=='accountancy_code_sell'){ $valuetoshow=$langs->trans("AccountancyCodeSell"); $sortable=0; } - if ($fieldlist[$field]=='accountancy_code_buy'){ $valuetoshow=$langs->trans("AccountancyCodeBuy"); $sortable=0; } + } + if ($fieldlist[$field]=='localtax1_type') { $valuetoshow=$langs->trans("UseLocalTax")." 2"; $align="center"; $sortable=0; } + if ($fieldlist[$field]=='localtax1') { $valuetoshow=$langs->trans("Rate")." 2"; $sortable=0; } + if ($fieldlist[$field]=='localtax2_type') { $valuetoshow=$langs->trans("UseLocalTax")." 3"; $align="center"; $sortable=0; } + if ($fieldlist[$field]=='localtax2') { $valuetoshow=$langs->trans("Rate")." 3"; $sortable=0; } + if ($fieldlist[$field]=='organization') { $valuetoshow=$langs->trans("Organization"); } + if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } + if ($fieldlist[$field]=='type') { $valuetoshow=$langs->trans("Type"); } + if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') + { + $valuetoshow=$langs->trans("Label"); + if ($id != 25) $valuetoshow.="*"; + } + if ($fieldlist[$field]=='libelle_facture') { $valuetoshow=$langs->trans("LabelOnDocuments")."*"; } + if ($fieldlist[$field]=='country') { $valuetoshow=$langs->trans("Country"); } + if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; } + if ($fieldlist[$field]=='nbjour') { $valuetoshow=$langs->trans("NbOfDays"); } + if ($fieldlist[$field]=='type_cdr') { $valuetoshow=$langs->trans("AtEndOfMonth"); $align="center"; } + if ($fieldlist[$field]=='decalage') { $valuetoshow=$langs->trans("Offset"); } + if ($fieldlist[$field]=='width') { $valuetoshow=$langs->trans("Width"); } + if ($fieldlist[$field]=='height') { $valuetoshow=$langs->trans("Height"); } + if ($fieldlist[$field]=='unit') { $valuetoshow=$langs->trans("MeasuringUnit"); } + if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } + if ($fieldlist[$field]=='accountancy_code'){ $valuetoshow=$langs->trans("AccountancyCode"); } + if ($fieldlist[$field]=='accountancy_code_sell'){ $valuetoshow=$langs->trans("AccountancyCodeSell"); $sortable=0; } + if ($fieldlist[$field]=='accountancy_code_buy'){ $valuetoshow=$langs->trans("AccountancyCodeBuy"); $sortable=0; } if ($fieldlist[$field]=='fk_pcg_version') { $valuetoshow=$langs->trans("Pcg_version"); } - if ($fieldlist[$field]=='account_parent') { $valuetoshow=$langs->trans("Accountsparent"); } - if ($fieldlist[$field]=='pcg_type') { $valuetoshow=$langs->trans("Pcg_type"); } - if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } - if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } - if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } - if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } + if ($fieldlist[$field]=='account_parent') { $valuetoshow=$langs->trans("Accountsparent"); } + if ($fieldlist[$field]=='pcg_type') { $valuetoshow=$langs->trans("Pcg_type"); } + if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } + if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } + if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } + if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } if ($fieldlist[$field]=='range_account') { $valuetoshow=$langs->trans("Range"); } if ($fieldlist[$field]=='sens') { $valuetoshow=$langs->trans("Sens"); } if ($fieldlist[$field]=='category_type') { $valuetoshow=$langs->trans("Calculated"); } if ($fieldlist[$field]=='formula') { $valuetoshow=$langs->trans("Formula"); } - // Affiche nom du champ - if ($showfield) - { - print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder); - } - } + // Affiche nom du champ + if ($showfield) + { + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder); + } + } print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page?'page='.$page.'&':''), $param, 'align="center"', $sortfield, $sortorder); - print getTitleFieldOfList(''); - print getTitleFieldOfList(''); - print '</tr>'; - - if ($num) - { - // Lines with values - while ($i < $num) - { - $obj = $db->fetch_object($resql); - //print_r($obj); - print '<tr class="oddeven" id="rowid-'.$obj->rowid.'">'; - if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) - { - print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="page" value="'.$page.'">'; - print '<input type="hidden" name="rowid" value="'.$rowid.'">'; - - $tmpaction='edit'; - $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('editDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; - - if (empty($reshook)) fieldListAccountModel($fieldlist,$obj,$tabname[$id],'edit'); - - print '<td colspan="3" align="right"><a name="'.(! empty($obj->rowid)?$obj->rowid:$obj->code).'"> </a><input type="submit" class="button" name="actionmodify" value="'.$langs->trans("Modify").'">'; - print ' <input type="submit" class="button" name="actioncancel" value="'.$langs->trans("Cancel").'"></td>'; - } - else - { - $tmpaction = 'view'; - $parameters=array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('viewDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - - $error=$hookmanager->error; $errors=$hookmanager->errors; - - if (empty($reshook)) - { - foreach ($fieldlist as $field => $value) - { - - $showfield=1; - $align="left"; - $valuetoshow=$obj->{$fieldlist[$field]}; - if ($value == 'type_template') - { - $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; - } - if ($value == 'element') - { - $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; - } - else if ($value == 'source') - { - $valuetoshow = isset($sourceList[$valuetoshow])?$sourceList[$valuetoshow]:$valuetoshow; - } - else if ($valuetoshow=='all') { - $valuetoshow=$langs->trans('All'); - } - else if ($fieldlist[$field]=='country') { - if (empty($obj->country_code)) - { - $valuetoshow='-'; - } - else - { - $key=$langs->trans("Country".strtoupper($obj->country_code)); - $valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country); - } - } - else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='type_cdr' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') { - if(empty($valuetoshow)) $valuetoshow = $langs->trans('None'); - elseif($valuetoshow == 1) $valuetoshow = $langs->trans('AtEndOfMonth'); - elseif($valuetoshow == 2) $valuetoshow = $langs->trans('CurrentNext'); - $align="center"; - } - else if ($fieldlist[$field]=='price' || preg_match('/^amount/i',$fieldlist[$field])) { - $valuetoshow=price($valuetoshow); - } - else if ($fieldlist[$field]=='libelle_facture') { - $langs->load("bills"); - $key=$langs->trans("PaymentCondition".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "PaymentCondition".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - $valuetoshow=nl2br($valuetoshow); - } - else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_country') { - $key=$langs->trans("Country".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "Country".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_availability') { - $langs->load("propal"); - $key=$langs->trans("AvailabilityType".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "AvailabilityType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_actioncomm') { - $key=$langs->trans("Action".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "Action".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if (! empty($obj->code_iso) && $fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_currencies') { - $key=$langs->trans("Currency".strtoupper($obj->code_iso)); - $valuetoshow=($obj->code_iso && $key != "Currency".strtoupper($obj->code_iso)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_typent') { - $key=$langs->trans(strtoupper($obj->code)); - $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_prospectlevel') { - $key=$langs->trans(strtoupper($obj->code)); - $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_civility') { - $key=$langs->trans("Civility".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_type_contact') { - $langs->load('agenda'); - $key=$langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_payment_term') { - $langs->load("bills"); - $key=$langs->trans("PaymentConditionShort".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "PaymentConditionShort".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paiement') { - $langs->load("bills"); - $key=$langs->trans("PaymentType".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "PaymentType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_reason') { - $key=$langs->trans("DemandReasonType".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "DemandReasonType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_method') { - $langs->load("orders"); - $key=$langs->trans($obj->code); - $valuetoshow=($obj->code && $key != $obj->code)?$key:$obj->{$fieldlist[$field]}; - } - else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_shipment_mode') { - $langs->load("sendings"); - $key=$langs->trans("SendingMethod".strtoupper($obj->code)); - $valuetoshow=($obj->code && $key != "SendingMethod".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field] == 'libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paper_format') - { - $key = $langs->trans('PaperFormat'.strtoupper($obj->code)); - $valuetoshow = ($obj->code && $key != 'PaperFormat'.strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field] == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_type_fees') - { - $langs->load('trips'); - $key = $langs->trans(strtoupper($obj->code)); - $valuetoshow = ($obj->code && $key != strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { - $showfield=0; - } - else if ($fieldlist[$field]=='unicode') { - $valuetoshow = $langs->getCurrencySymbol($obj->code,1); - } - else if ($fieldlist[$field]=='label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') { - $langs->load("products"); - $valuetoshow=$langs->trans($obj->{$fieldlist[$field]}); - } - else if ($fieldlist[$field]=='short_label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') { - $langs->load("products"); - $valuetoshow = $langs->trans($obj->{$fieldlist[$field]}); - } - else if (($fieldlist[$field] == 'unit') && ($tabname[$id] == MAIN_DB_PREFIX.'c_paper_format')) - { - $key = $langs->trans('SizeUnit'.strtolower($obj->unit)); - $valuetoshow = ($obj->code && $key != 'SizeUnit'.strtolower($obj->unit) ? $key : $obj->{$fieldlist[$field]}); - } + print getTitleFieldOfList(''); + print getTitleFieldOfList(''); + print '</tr>'; + + if ($num) + { + // Lines with values + while ($i < $num) + { + $obj = $db->fetch_object($resql); + //print_r($obj); + print '<tr class="oddeven" id="rowid-'.$obj->rowid.'">'; + if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) + { + print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="page" value="'.$page.'">'; + print '<input type="hidden" name="rowid" value="'.$rowid.'">'; + + $tmpaction='edit'; + $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('editDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error=$hookmanager->error; $errors=$hookmanager->errors; + + if (empty($reshook)) fieldListAccountModel($fieldlist,$obj,$tabname[$id],'edit'); + + print '<td colspan="3" align="right"><a name="'.(! empty($obj->rowid)?$obj->rowid:$obj->code).'"> </a><input type="submit" class="button" name="actionmodify" value="'.$langs->trans("Modify").'">'; + print ' <input type="submit" class="button" name="actioncancel" value="'.$langs->trans("Cancel").'"></td>'; + } + else + { + $tmpaction = 'view'; + $parameters=array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('viewDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + + $error=$hookmanager->error; $errors=$hookmanager->errors; + + if (empty($reshook)) + { + foreach ($fieldlist as $field => $value) + { + + $showfield=1; + $align="left"; + $valuetoshow=$obj->{$fieldlist[$field]}; + if ($value == 'type_template') + { + $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; + } + if ($value == 'element') + { + $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; + } + else if ($value == 'source') + { + $valuetoshow = isset($sourceList[$valuetoshow])?$sourceList[$valuetoshow]:$valuetoshow; + } + else if ($valuetoshow=='all') { + $valuetoshow=$langs->trans('All'); + } + else if ($fieldlist[$field]=='country') { + if (empty($obj->country_code)) + { + $valuetoshow='-'; + } + else + { + $key=$langs->trans("Country".strtoupper($obj->country_code)); + $valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country); + } + } + else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='type_cdr' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') { + if(empty($valuetoshow)) $valuetoshow = $langs->trans('None'); + elseif($valuetoshow == 1) $valuetoshow = $langs->trans('AtEndOfMonth'); + elseif($valuetoshow == 2) $valuetoshow = $langs->trans('CurrentNext'); + $align="center"; + } + else if ($fieldlist[$field]=='price' || preg_match('/^amount/i',$fieldlist[$field])) { + $valuetoshow=price($valuetoshow); + } + else if ($fieldlist[$field]=='libelle_facture') { + $langs->load("bills"); + $key=$langs->trans("PaymentCondition".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "PaymentCondition".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + $valuetoshow=nl2br($valuetoshow); + } + else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_country') { + $key=$langs->trans("Country".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "Country".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_availability') { + $langs->load("propal"); + $key=$langs->trans("AvailabilityType".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "AvailabilityType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_actioncomm') { + $key=$langs->trans("Action".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "Action".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if (! empty($obj->code_iso) && $fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_currencies') { + $key=$langs->trans("Currency".strtoupper($obj->code_iso)); + $valuetoshow=($obj->code_iso && $key != "Currency".strtoupper($obj->code_iso)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_typent') { + $key=$langs->trans(strtoupper($obj->code)); + $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_prospectlevel') { + $key=$langs->trans(strtoupper($obj->code)); + $valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_civility') { + $key=$langs->trans("Civility".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_type_contact') { + $langs->load('agenda'); + $key=$langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_payment_term') { + $langs->load("bills"); + $key=$langs->trans("PaymentConditionShort".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "PaymentConditionShort".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paiement') { + $langs->load("bills"); + $key=$langs->trans("PaymentType".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "PaymentType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_reason') { + $key=$langs->trans("DemandReasonType".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "DemandReasonType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_method') { + $langs->load("orders"); + $key=$langs->trans($obj->code); + $valuetoshow=($obj->code && $key != $obj->code)?$key:$obj->{$fieldlist[$field]}; + } + else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_shipment_mode') { + $langs->load("sendings"); + $key=$langs->trans("SendingMethod".strtoupper($obj->code)); + $valuetoshow=($obj->code && $key != "SendingMethod".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field] == 'libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paper_format') + { + $key = $langs->trans('PaperFormat'.strtoupper($obj->code)); + $valuetoshow = ($obj->code && $key != 'PaperFormat'.strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field] == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_type_fees') + { + $langs->load('trips'); + $key = $langs->trans(strtoupper($obj->code)); + $valuetoshow = ($obj->code && $key != strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { + $showfield=0; + } + else if ($fieldlist[$field]=='unicode') { + $valuetoshow = $langs->getCurrencySymbol($obj->code,1); + } + else if ($fieldlist[$field]=='label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') { + $langs->load("products"); + $valuetoshow=$langs->trans($obj->{$fieldlist[$field]}); + } + else if ($fieldlist[$field]=='short_label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') { + $langs->load("products"); + $valuetoshow = $langs->trans($obj->{$fieldlist[$field]}); + } + else if (($fieldlist[$field] == 'unit') && ($tabname[$id] == MAIN_DB_PREFIX.'c_paper_format')) + { + $key = $langs->trans('SizeUnit'.strtolower($obj->unit)); + $valuetoshow = ($obj->code && $key != 'SizeUnit'.strtolower($obj->unit) ? $key : $obj->{$fieldlist[$field]}); + } else if ($fieldlist[$field]=='taux') { - $valuetoshow = price($valuetoshow, 0, $langs, 0, 0); - $align="right"; + $valuetoshow = price($valuetoshow, 0, $langs, 0, 0); + $align="right"; } else if (in_array($fieldlist[$field],array('recuperableonly'))) { $align="center"; } else if ($fieldlist[$field]=='accountancy_code' || $fieldlist[$field]=='accountancy_code_sell' || $fieldlist[$field]=='accountancy_code_buy') { - $valuetoshow = length_accountg($valuetoshow); - } + $valuetoshow = length_accountg($valuetoshow); + } - $class='tddict'; - if ($fieldlist[$field] == 'tracking') $class.=' tdoverflowauto'; + $class='tddict'; + if ($fieldlist[$field] == 'tracking') $class.=' tdoverflowauto'; // Show value for field if ($showfield) print '<!-- '.$fieldlist[$field].' --><td align="'.$align.'" class="'.$class.'">'.$valuetoshow.'</td>'; - } - } - - // Can an entry be erased or disabled ? - $iserasable=1;$canbedisabled=1;$canbemodified=1; // true by default - if (isset($obj->code) && $id != 10) - { - if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) { $iserasable = 0; $canbedisabled = 0; } - else if ($obj->code == 'RECEP') { $iserasable = 0; $canbedisabled = 0; } - else if ($obj->code == 'EF0') { $iserasable = 0; $canbedisabled = 0; } - } - - if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) { $iserasable=0; } - if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO')) || in_array($obj->type, array('systemauto'))) { $canbedisabled=0; $canbedisabled = 0; } - $canbemodified=$iserasable; - if ($obj->code == 'RECEP') $canbemodified=1; - - $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); - if ($param) $url .= '&'.$param; - $url.='&'; - - // Active - print '<td align="center" class="nowrap">'; - if ($canbedisabled) print '<a href="'.$url.'action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>'; - else - { - if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO'))) print $langs->trans("AlwaysActive"); - else if (isset($obj->type) && in_array($obj->type, array('systemauto')) && empty($obj->active)) print $langs->trans("Deprecated"); - else if (isset($obj->type) && in_array($obj->type, array('system')) && ! empty($obj->active) && $obj->code != 'AC_OTH') print $langs->trans("UsedOnlyWithTypeOption"); - else print $langs->trans("AlwaysActive"); - } - print "</td>"; - - // Modify link - if ($canbemodified) print '<td align="center"><a class="reposition" href="'.$url.'action=edit">'.img_edit().'</a></td>'; - else print '<td> </td>'; - - // Delete link - if ($iserasable) print '<td align="center"><a href="'.$url.'action=delete">'.img_delete().'</a></td>'; - else print '<td> </td>'; - - print "</tr>\n"; - } - $i++; - } - } - } - else { - dol_print_error($db); - } - - print '</table>'; + } + } + + // Can an entry be erased or disabled ? + $iserasable=1;$canbedisabled=1;$canbemodified=1; // true by default + if (isset($obj->code) && $id != 10) + { + if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) { $iserasable = 0; $canbedisabled = 0; } + else if ($obj->code == 'RECEP') { $iserasable = 0; $canbedisabled = 0; } + else if ($obj->code == 'EF0') { $iserasable = 0; $canbedisabled = 0; } + } + + if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) { $iserasable=0; } + if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO')) || in_array($obj->type, array('systemauto'))) { $canbedisabled=0; $canbedisabled = 0; } + $canbemodified=$iserasable; + if ($obj->code == 'RECEP') $canbemodified=1; + + $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); + if ($param) $url .= '&'.$param; + $url.='&'; + + // Active + print '<td align="center" class="nowrap">'; + if ($canbedisabled) print '<a href="'.$url.'action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>'; + else + { + if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO'))) print $langs->trans("AlwaysActive"); + else if (isset($obj->type) && in_array($obj->type, array('systemauto')) && empty($obj->active)) print $langs->trans("Deprecated"); + else if (isset($obj->type) && in_array($obj->type, array('system')) && ! empty($obj->active) && $obj->code != 'AC_OTH') print $langs->trans("UsedOnlyWithTypeOption"); + else print $langs->trans("AlwaysActive"); + } + print "</td>"; + + // Modify link + if ($canbemodified) print '<td align="center"><a class="reposition" href="'.$url.'action=edit">'.img_edit().'</a></td>'; + else print '<td> </td>'; + + // Delete link + if ($iserasable) print '<td align="center"><a href="'.$url.'action=delete">'.img_delete().'</a></td>'; + else print '<td> </td>'; + + print "</tr>\n"; + } + $i++; + } + } + } + else { + dol_print_error($db); + } + + print '</table>'; print '</div>'; - print '</form>'; + print '</form>'; } print '<br>'; @@ -1152,8 +1152,8 @@ function fieldListAccountModel($fieldlist, $obj='', $tabname='', $context='') print '</td>'; } elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'type_cdr' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') { - if ($fieldlist[$field] == 'type_cdr') print '<td align="center">'; - else print '<td>'; + if ($fieldlist[$field] == 'type_cdr') print '<td align="center">'; + else print '<td>'; if ($fieldlist[$field] == 'type_cdr') { print $form->selectarray($fieldlist[$field], array(0=>$langs->trans('None'), 1=>$langs->trans('AtEndOfMonth'), 2=>$langs->trans('CurrentNext')), (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')); } else { diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php index 9bbd37449bec072924de538347e6df5ea05a677e..220b36c6a52fcc9fa1775beaf386ff4288477136 100644 --- a/htdocs/accountancy/admin/journals_list.php +++ b/htdocs/accountancy/admin/journals_list.php @@ -128,8 +128,8 @@ complete_dictionary_with_modules($taborder,$tabname,$tablib,$tabsql,$tabsqlsort, // Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact") $elementList = array(); - // Must match ids defined into eldy.lib.php - $sourceList = array( + // Must match ids defined into eldy.lib.php + $sourceList = array( '1' => $langs->trans('AccountingJournalType1'), '2' => $langs->trans('AccountingJournalType2'), '3' => $langs->trans('AccountingJournalType3'), @@ -144,214 +144,214 @@ $elementList = array(); if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x')) { - $search_country_id = ''; + $search_country_id = ''; } // Actions add or modify an entry into a dictionary if (GETPOST('actionadd') || GETPOST('actionmodify')) { - $listfield=explode(',', str_replace(' ', '',$tabfield[$id])); - $listfieldinsert=explode(',',$tabfieldinsert[$id]); - $listfieldmodify=explode(',',$tabfieldinsert[$id]); - $listfieldvalue=explode(',',$tabfieldvalue[$id]); - - // Check that all fields are filled - $ok=1; - foreach ($listfield as $f => $value) - { + $listfield=explode(',', str_replace(' ', '',$tabfield[$id])); + $listfieldinsert=explode(',',$tabfieldinsert[$id]); + $listfieldmodify=explode(',',$tabfieldinsert[$id]); + $listfieldvalue=explode(',',$tabfieldvalue[$id]); + + // Check that all fields are filled + $ok=1; + foreach ($listfield as $f => $value) + { if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) $fieldnamekey='Label'; - if ($fieldnamekey == 'code') $fieldnamekey = 'Code'; + if ($fieldnamekey == 'code') $fieldnamekey = 'Code'; if ($fieldnamekey == 'nature') $fieldnamekey = 'Nature'; - } - // Other checks - if (isset($_POST["code"])) - { - if ($_POST["code"]=='0') - { - $ok=0; - setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); - } - /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base + } + // Other checks + if (isset($_POST["code"])) + { + if ($_POST["code"]=='0') + { + $ok=0; + setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); + } + /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base { $ok = 0; $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'<br>'; }*/ - } + } // Clean some parameters - if ($_POST["accountancy_code"] <= 0) $_POST["accountancy_code"]=''; // If empty, we force to null + if ($_POST["accountancy_code"] <= 0) $_POST["accountancy_code"]=''; // If empty, we force to null if ($_POST["accountancy_code_sell"] <= 0) $_POST["accountancy_code_sell"]=''; // If empty, we force to null if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"]=''; // If empty, we force to null - // Si verif ok et action add, on ajoute la ligne - if ($ok && GETPOST('actionadd')) - { - if ($tabrowid[$id]) - { - // Recupere id libre pour insertion - $newid=0; - $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; - $result = $db->query($sql); - if ($result) - { - $obj = $db->fetch_object($result); - $newid=($obj->newid + 1); - - } else { - dol_print_error($db); - } - } - - // Add new entry - $sql = "INSERT INTO ".$tabname[$id]." ("; - // List of fields - if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) - $sql.= $tabrowid[$id].","; - $sql.= $tabfieldinsert[$id]; - $sql.=",active)"; - $sql.= " VALUES("; - - // List of values - if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) - $sql.= $newid.","; - $i=0; - foreach ($listfieldinsert as $f => $value) - { - if ($value == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } - if ($i) $sql.=","; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; - $i++; - } - $sql.=",1)"; - - dol_syslog("actionadd", LOG_DEBUG); - $result = $db->query($sql); - if ($result) // Add is ok - { - setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); - $_POST=array('id'=>$id); // Clean $_POST array, we keep only - } - else - { - if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); - } - else { - dol_print_error($db); - } - } - } - - // Si verif ok et action modify, on modifie la ligne - if ($ok && GETPOST('actionmodify')) - { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - // Modify entry - $sql = "UPDATE ".$tabname[$id]." SET "; - // Modifie valeur des champs - if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldmodify)) - { - $sql.= $tabrowid[$id]."="; - $sql.= "'".$db->escape($rowid)."', "; - } - $i = 0; - foreach ($listfieldmodify as $field) - { - if ($field == 'price' || preg_match('/^amount/i',$field) || $field == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]],'MU'); - } - else if ($field == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } - if ($i) $sql.=","; - $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; - $i++; - } - $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; - - dol_syslog("actionmodify", LOG_DEBUG); - //print $sql; - $resql = $db->query($sql); - if (! $resql) - { - setEventMessages($db->error(), null, 'errors'); - } - } - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition + // Si verif ok et action add, on ajoute la ligne + if ($ok && GETPOST('actionadd')) + { + if ($tabrowid[$id]) + { + // Recupere id libre pour insertion + $newid=0; + $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; + $result = $db->query($sql); + if ($result) + { + $obj = $db->fetch_object($result); + $newid=($obj->newid + 1); + + } else { + dol_print_error($db); + } + } + + // Add new entry + $sql = "INSERT INTO ".$tabname[$id]." ("; + // List of fields + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) + $sql.= $tabrowid[$id].","; + $sql.= $tabfieldinsert[$id]; + $sql.=",active)"; + $sql.= " VALUES("; + + // List of values + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) + $sql.= $newid.","; + $i=0; + foreach ($listfieldinsert as $f => $value) + { + if ($value == 'entity') { + $_POST[$listfieldvalue[$i]] = $conf->entity; + } + if ($i) $sql.=","; + if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $i++; + } + $sql.=",1)"; + + dol_syslog("actionadd", LOG_DEBUG); + $result = $db->query($sql); + if ($result) // Add is ok + { + setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); + $_POST=array('id'=>$id); // Clean $_POST array, we keep only + } + else + { + if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); + } + else { + dol_print_error($db); + } + } + } + + // Si verif ok et action modify, on modifie la ligne + if ($ok && GETPOST('actionmodify')) + { + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + // Modify entry + $sql = "UPDATE ".$tabname[$id]." SET "; + // Modifie valeur des champs + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldmodify)) + { + $sql.= $tabrowid[$id]."="; + $sql.= "'".$db->escape($rowid)."', "; + } + $i = 0; + foreach ($listfieldmodify as $field) + { + if ($field == 'price' || preg_match('/^amount/i',$field) || $field == 'taux') { + $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]],'MU'); + } + else if ($field == 'entity') { + $_POST[$listfieldvalue[$i]] = $conf->entity; + } + if ($i) $sql.=","; + $sql.= $field."="; + if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $i++; + } + $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; + + dol_syslog("actionmodify", LOG_DEBUG); + //print $sql; + $resql = $db->query($sql); + if (! $resql) + { + setEventMessages($db->error(), null, 'errors'); + } + } + //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } if (GETPOST('actioncancel')) { - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition + //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } if ($action == 'confirm_delete' && $confirm == 'yes') // delete { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."='".$rowid."'"; - - dol_syslog("delete", LOG_DEBUG); - $result = $db->query($sql); - if (! $result) - { - if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') - { - setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); - } - else - { - dol_print_error($db); - } - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."='".$rowid."'"; + + dol_syslog("delete", LOG_DEBUG); + $result = $db->query($sql); + if (! $result) + { + if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') + { + setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); + } + else + { + dol_print_error($db); + } + } } // activate if ($action == $acts[0]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$rowid."'"; - } - elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".$code."'"; - } - - $result = $db->query($sql); - if (!$result) - { - dol_print_error($db); - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".$code."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } } // disable if ($action == $acts[1]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$rowid."'"; - } - elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".$code."'"; - } - - $result = $db->query($sql); - if (!$result) - { - dol_print_error($db); - } + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".$code."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } } @@ -368,8 +368,8 @@ $titre=$langs->trans("DictionarySetup"); $linkback=''; if ($id) { - $titre.=' - '.$langs->trans($tablib[$id]); - $titlepicto='title_accountancy'; + $titre.=' - '.$langs->trans($tablib[$id]); + $titlepicto='title_accountancy'; } print load_fiche_titre($titre,$linkback,$titlepicto); @@ -378,7 +378,7 @@ print load_fiche_titre($titre,$linkback,$titlepicto); // Confirmation de la suppression de la ligne if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete','',0,1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete','',0,1); } //var_dump($elementList); @@ -387,315 +387,315 @@ if ($action == 'delete') */ if ($id) { - // Complete requete recherche valeurs avec critere de tri - $sql=$tabsql[$id]; - - if ($search_country_id > 0) - { - if (preg_match('/ WHERE /',$sql)) $sql.= " AND "; - else $sql.=" WHERE "; - $sql.= " c.rowid = ".$search_country_id; - } - - if ($sortfield) - { - // If sort order is "country", we use country_code instead - if ($sortfield == 'country') $sortfield='country_code'; - $sql.= " ORDER BY ".$sortfield; - if ($sortorder) - { - $sql.=" ".strtoupper($sortorder); - } - $sql.=", "; - // Clear the required sort criteria for the tabsqlsort to be able to force it with selected value - $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.' '.$sortorder.',/i','',$tabsqlsort[$id]); - $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.',/i','',$tabsqlsort[$id]); - } - else { - $sql.=" ORDER BY "; - } - $sql.=$tabsqlsort[$id]; - $sql.=$db->plimit($listlimit+1,$offset); - //print $sql; - - $fieldlist=explode(',',$tabfield[$id]); - - print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="from" value="'.dol_escape_htmltag(GETPOST('from','alpha')).'">'; - - print '<div class="div-table-responsive">'; - print '<table class="noborder" width="100%">'; - - // Form to add a new line - if ($tabname[$id]) - { - $alabelisused=0; - $var=false; - - $fieldlist=explode(',',$tabfield[$id]); - - // Line for title - print '<tr class="liste_titre">'; - foreach ($fieldlist as $field => $value) - { - // Determine le nom du champ par rapport aux noms possibles - // dans les dictionnaires de donnees - $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut - $valuetoshow=$langs->trans($valuetoshow); // try to translate - $align="left"; - if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') - { - $valuetoshow=$langs->trans("Label"); - } - if ($fieldlist[$field]=='nature') { $valuetoshow=$langs->trans("Nature"); } - - if ($valuetoshow != '') - { - print '<td align="'.$align.'">'; - if (! empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i',$tabhelp[$id][$value])) print '<a href="'.$tabhelp[$id][$value].'" target="_blank">'.$valuetoshow.' '.img_help(1,$valuetoshow).'</a>'; - else if (! empty($tabhelp[$id][$value])) print $form->textwithpicto($valuetoshow,$tabhelp[$id][$value]); - else print $valuetoshow; - print '</td>'; - } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $alabelisused=1; - } - - print '<td>'; - print '<input type="hidden" name="id" value="'.$id.'">'; - print '</td>'; - print '<td style="min-width: 26px;"></td>'; - print '<td style="min-width: 26px;"></td>'; - print '<td style="min-width: 26px;"></td>'; - print '</tr>'; - - // Line to enter new values - print '<tr class="oddeven nodrag nodrap nohover">'; - - $obj = new stdClass(); - // If data was already input, we define them in obj to populate input fields. - if (GETPOST('actionadd')) - { - foreach ($fieldlist as $key=>$val) - { - if (GETPOST($val) != '') - $obj->$val=GETPOST($val); - } - } - - $tmpaction = 'create'; - $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('createDictionaryFieldlist',$parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; - - if (empty($reshook)) - { - fieldListJournal($fieldlist,$obj,$tabname[$id],'add'); - } - - print '<td colspan="4" align="right">'; - print '<input type="submit" class="button" name="actionadd" value="'.$langs->trans("Add").'">'; - print '</td>'; - print "</tr>"; - - print '<tr><td colspan="7"> </td></tr>'; // Keep to have a line with enough height - } - - - - // List of available record in database - dol_syslog("htdocs/admin/dict", LOG_DEBUG); - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - $var=true; - - $param = '&id='.$id; - if ($search_country_id > 0) $param.= '&search_country_id='.$search_country_id; - $paramwithsearch = $param; - if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder; - if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield; - if (GETPOST('from')) $paramwithsearch.= '&from='.GETPOST('from','alpha'); - - // There is several pages - if ($num > $listlimit) - { - print '<tr class="none"><td align="right" colspan="'.(3+count($fieldlist)).'">'; - print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), '<li class="pagination"><span>'.$langs->trans("Page").' '.($page+1).'</span></li>'); - print '</td></tr>'; - } - - // Title line with search boxes - print '<tr class="liste_titre_filter liste_titre_add">'; - print '<td class="liste_titre"></td>'; - print '<td class="liste_titre"></td>'; - print '<td class="liste_titre"></td>'; - print '<td class="liste_titre"></td>'; - print '<td class="liste_titre"></td>'; - print '<td class="liste_titre"></td>'; - print '<td class="liste_titre" align="center">'; - if ($filterfound) - { - $searchpicto=$form->showFilterAndCheckAddButtons(0); - print $searchpicto; - } - print '</td>'; - print '</tr>'; - - // Title of lines - print '<tr class="liste_titre">'; - foreach ($fieldlist as $field => $value) - { - // Determine le nom du champ par rapport aux noms possibles - // dans les dictionnaires de donnees - $showfield=1; // By defaut - $align="left"; - $sortable=1; - $valuetoshow=''; - /* + // Complete requete recherche valeurs avec critere de tri + $sql=$tabsql[$id]; + + if ($search_country_id > 0) + { + if (preg_match('/ WHERE /',$sql)) $sql.= " AND "; + else $sql.=" WHERE "; + $sql.= " c.rowid = ".$search_country_id; + } + + if ($sortfield) + { + // If sort order is "country", we use country_code instead + if ($sortfield == 'country') $sortfield='country_code'; + $sql.= " ORDER BY ".$sortfield; + if ($sortorder) + { + $sql.=" ".strtoupper($sortorder); + } + $sql.=", "; + // Clear the required sort criteria for the tabsqlsort to be able to force it with selected value + $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.' '.$sortorder.',/i','',$tabsqlsort[$id]); + $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.',/i','',$tabsqlsort[$id]); + } + else { + $sql.=" ORDER BY "; + } + $sql.=$tabsqlsort[$id]; + $sql.=$db->plimit($listlimit+1,$offset); + //print $sql; + + $fieldlist=explode(',',$tabfield[$id]); + + print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="from" value="'.dol_escape_htmltag(GETPOST('from','alpha')).'">'; + + print '<div class="div-table-responsive">'; + print '<table class="noborder" width="100%">'; + + // Form to add a new line + if ($tabname[$id]) + { + $alabelisused=0; + $var=false; + + $fieldlist=explode(',',$tabfield[$id]); + + // Line for title + print '<tr class="liste_titre">'; + foreach ($fieldlist as $field => $value) + { + // Determine le nom du champ par rapport aux noms possibles + // dans les dictionnaires de donnees + $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut + $valuetoshow=$langs->trans($valuetoshow); // try to translate + $align="left"; + if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') + { + $valuetoshow=$langs->trans("Label"); + } + if ($fieldlist[$field]=='nature') { $valuetoshow=$langs->trans("Nature"); } + + if ($valuetoshow != '') + { + print '<td align="'.$align.'">'; + if (! empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i',$tabhelp[$id][$value])) print '<a href="'.$tabhelp[$id][$value].'" target="_blank">'.$valuetoshow.' '.img_help(1,$valuetoshow).'</a>'; + else if (! empty($tabhelp[$id][$value])) print $form->textwithpicto($valuetoshow,$tabhelp[$id][$value]); + else print $valuetoshow; + print '</td>'; + } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $alabelisused=1; + } + + print '<td>'; + print '<input type="hidden" name="id" value="'.$id.'">'; + print '</td>'; + print '<td style="min-width: 26px;"></td>'; + print '<td style="min-width: 26px;"></td>'; + print '<td style="min-width: 26px;"></td>'; + print '</tr>'; + + // Line to enter new values + print '<tr class="oddeven nodrag nodrap nohover">'; + + $obj = new stdClass(); + // If data was already input, we define them in obj to populate input fields. + if (GETPOST('actionadd')) + { + foreach ($fieldlist as $key=>$val) + { + if (GETPOST($val) != '') + $obj->$val=GETPOST($val); + } + } + + $tmpaction = 'create'; + $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('createDictionaryFieldlist',$parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error=$hookmanager->error; $errors=$hookmanager->errors; + + if (empty($reshook)) + { + fieldListJournal($fieldlist,$obj,$tabname[$id],'add'); + } + + print '<td colspan="4" align="right">'; + print '<input type="submit" class="button" name="actionadd" value="'.$langs->trans("Add").'">'; + print '</td>'; + print "</tr>"; + + print '<tr><td colspan="7"> </td></tr>'; // Keep to have a line with enough height + } + + + + // List of available record in database + dol_syslog("htdocs/admin/dict", LOG_DEBUG); + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + $var=true; + + $param = '&id='.$id; + if ($search_country_id > 0) $param.= '&search_country_id='.$search_country_id; + $paramwithsearch = $param; + if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder; + if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield; + if (GETPOST('from')) $paramwithsearch.= '&from='.GETPOST('from','alpha'); + + // There is several pages + if ($num > $listlimit) + { + print '<tr class="none"><td align="right" colspan="'.(3+count($fieldlist)).'">'; + print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), '<li class="pagination"><span>'.$langs->trans("Page").' '.($page+1).'</span></li>'); + print '</td></tr>'; + } + + // Title line with search boxes + print '<tr class="liste_titre_filter liste_titre_add">'; + print '<td class="liste_titre"></td>'; + print '<td class="liste_titre"></td>'; + print '<td class="liste_titre"></td>'; + print '<td class="liste_titre"></td>'; + print '<td class="liste_titre"></td>'; + print '<td class="liste_titre"></td>'; + print '<td class="liste_titre" align="center">'; + if ($filterfound) + { + $searchpicto=$form->showFilterAndCheckAddButtons(0); + print $searchpicto; + } + print '</td>'; + print '</tr>'; + + // Title of lines + print '<tr class="liste_titre">'; + foreach ($fieldlist as $field => $value) + { + // Determine le nom du champ par rapport aux noms possibles + // dans les dictionnaires de donnees + $showfield=1; // By defaut + $align="left"; + $sortable=1; + $valuetoshow=''; + /* $tmparray=getLabelOfField($fieldlist[$field]); $showfield=$tmp['showfield']; $valuetoshow=$tmp['valuetoshow']; $align=$tmp['align']; $sortable=$tmp['sortable']; */ - $valuetoshow=ucfirst($fieldlist[$field]); // By defaut - $valuetoshow=$langs->trans($valuetoshow); // try to translate - if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') { $valuetoshow=$langs->trans("Label"); } - if ($fieldlist[$field]=='nature') { $valuetoshow=$langs->trans("Nature"); } - - // Affiche nom du champ - if ($showfield) - { - print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder); - } - } + $valuetoshow=ucfirst($fieldlist[$field]); // By defaut + $valuetoshow=$langs->trans($valuetoshow); // try to translate + if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') { $valuetoshow=$langs->trans("Label"); } + if ($fieldlist[$field]=='nature') { $valuetoshow=$langs->trans("Nature"); } + + // Affiche nom du champ + if ($showfield) + { + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder); + } + } print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page?'page='.$page.'&':''), $param, 'align="center"', $sortfield, $sortorder); - print getTitleFieldOfList(''); - print getTitleFieldOfList(''); - print getTitleFieldOfList(''); - print '</tr>'; - - if ($num) - { - // Lines with values - while ($i < $num) - { - $obj = $db->fetch_object($resql); - //print_r($obj); - print '<tr class="oddeven" id="rowid-'.$obj->rowid.'">'; - if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) - { - $tmpaction='edit'; - $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('editDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; - - // Show fields - if (empty($reshook)) fieldListJournal($fieldlist,$obj,$tabname[$id],'edit'); - - print '<td align="center" colspan="4">'; - print '<input type="hidden" name="page" value="'.$page.'">'; - print '<input type="hidden" name="rowid" value="'.$rowid.'">'; - print '<input type="submit" class="button" name="actionmodify" value="'.$langs->trans("Modify").'">'; - print '<input type="submit" class="button" name="actioncancel" value="'.$langs->trans("Cancel").'">'; - print '<div name="'.(! empty($obj->rowid)?$obj->rowid:$obj->code).'"></div>'; - print '</td>'; - } - else - { - $tmpaction = 'view'; - $parameters=array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('viewDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - - $error=$hookmanager->error; $errors=$hookmanager->errors; - - if (empty($reshook)) - { - foreach ($fieldlist as $field => $value) - { - - $showfield=1; - $align="left"; - $valuetoshow=$obj->{$fieldlist[$field]}; - if ($valuetoshow=='all') { - $valuetoshow=$langs->trans('All'); - } - else if ($fieldlist[$field]=='nature' && $tabname[$id]==MAIN_DB_PREFIX.'accounting_journal') { - $langs->load("accountancy"); - $key=$langs->trans("AccountingJournalType".strtoupper($obj->nature)); - $valuetoshow=($obj->nature && $key != "AccountingJournalType".strtoupper($obj->nature)?$key:$obj->{$fieldlist[$field]}); - } - - $class='tddict'; + print getTitleFieldOfList(''); + print getTitleFieldOfList(''); + print getTitleFieldOfList(''); + print '</tr>'; + + if ($num) + { + // Lines with values + while ($i < $num) + { + $obj = $db->fetch_object($resql); + //print_r($obj); + print '<tr class="oddeven" id="rowid-'.$obj->rowid.'">'; + if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) + { + $tmpaction='edit'; + $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('editDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error=$hookmanager->error; $errors=$hookmanager->errors; + + // Show fields + if (empty($reshook)) fieldListJournal($fieldlist,$obj,$tabname[$id],'edit'); + + print '<td align="center" colspan="4">'; + print '<input type="hidden" name="page" value="'.$page.'">'; + print '<input type="hidden" name="rowid" value="'.$rowid.'">'; + print '<input type="submit" class="button" name="actionmodify" value="'.$langs->trans("Modify").'">'; + print '<input type="submit" class="button" name="actioncancel" value="'.$langs->trans("Cancel").'">'; + print '<div name="'.(! empty($obj->rowid)?$obj->rowid:$obj->code).'"></div>'; + print '</td>'; + } + else + { + $tmpaction = 'view'; + $parameters=array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('viewDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + + $error=$hookmanager->error; $errors=$hookmanager->errors; + + if (empty($reshook)) + { + foreach ($fieldlist as $field => $value) + { + + $showfield=1; + $align="left"; + $valuetoshow=$obj->{$fieldlist[$field]}; + if ($valuetoshow=='all') { + $valuetoshow=$langs->trans('All'); + } + else if ($fieldlist[$field]=='nature' && $tabname[$id]==MAIN_DB_PREFIX.'accounting_journal') { + $langs->load("accountancy"); + $key=$langs->trans("AccountingJournalType".strtoupper($obj->nature)); + $valuetoshow=($obj->nature && $key != "AccountingJournalType".strtoupper($obj->nature)?$key:$obj->{$fieldlist[$field]}); + } + + $class='tddict'; // Show value for field if ($showfield) print '<!-- '.$fieldlist[$field].' --><td align="'.$align.'" class="'.$class.'">'.$valuetoshow.'</td>'; - } - } - - // Can an entry be erased or disabled ? - $iserasable=1;$canbedisabled=1;$canbemodified=1; // true by default - if (isset($obj->code) && $id != 10) - { - if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) { $iserasable = 0; $canbedisabled = 0; } - else if ($obj->code == 'RECEP') { $iserasable = 0; $canbedisabled = 0; } - else if ($obj->code == 'EF0') { $iserasable = 0; $canbedisabled = 0; } - } - - $canbemodified=$iserasable; - - $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); - if ($param) $url .= '&'.$param; - $url.='&'; - - // Active - print '<td align="center" class="nowrap">'; - if ($canbedisabled) print '<a href="'.$url.'action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>'; - else - { - if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO'))) print $langs->trans("AlwaysActive"); - else if (isset($obj->type) && in_array($obj->type, array('systemauto')) && empty($obj->active)) print $langs->trans("Deprecated"); - else if (isset($obj->type) && in_array($obj->type, array('system')) && ! empty($obj->active) && $obj->code != 'AC_OTH') print $langs->trans("UsedOnlyWithTypeOption"); - else print $langs->trans("AlwaysActive"); - } - print "</td>"; - - // Modify link - if ($canbemodified) print '<td align="center"><a class="reposition" href="'.$url.'action=edit">'.img_edit().'</a></td>'; - else print '<td> </td>'; - - // Delete link - if ($iserasable) - { - print '<td align="center">'; - if ($user->admin) print '<a href="'.$url.'action=delete">'.img_delete().'</a>'; - //else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin - print '</td>'; - } - else print '<td> </td>'; - - print '<td></td>'; - - print '</td>'; - } - - print "</tr>\n"; - $i++; - } - } - } - else { - dol_print_error($db); - } - - print '</table>'; + } + } + + // Can an entry be erased or disabled ? + $iserasable=1;$canbedisabled=1;$canbemodified=1; // true by default + if (isset($obj->code) && $id != 10) + { + if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) { $iserasable = 0; $canbedisabled = 0; } + else if ($obj->code == 'RECEP') { $iserasable = 0; $canbedisabled = 0; } + else if ($obj->code == 'EF0') { $iserasable = 0; $canbedisabled = 0; } + } + + $canbemodified=$iserasable; + + $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); + if ($param) $url .= '&'.$param; + $url.='&'; + + // Active + print '<td align="center" class="nowrap">'; + if ($canbedisabled) print '<a href="'.$url.'action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>'; + else + { + if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO'))) print $langs->trans("AlwaysActive"); + else if (isset($obj->type) && in_array($obj->type, array('systemauto')) && empty($obj->active)) print $langs->trans("Deprecated"); + else if (isset($obj->type) && in_array($obj->type, array('system')) && ! empty($obj->active) && $obj->code != 'AC_OTH') print $langs->trans("UsedOnlyWithTypeOption"); + else print $langs->trans("AlwaysActive"); + } + print "</td>"; + + // Modify link + if ($canbemodified) print '<td align="center"><a class="reposition" href="'.$url.'action=edit">'.img_edit().'</a></td>'; + else print '<td> </td>'; + + // Delete link + if ($iserasable) + { + print '<td align="center">'; + if ($user->admin) print '<a href="'.$url.'action=delete">'.img_delete().'</a>'; + //else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin + print '</td>'; + } + else print '<td> </td>'; + + print '<td></td>'; + + print '</td>'; + } + + print "</tr>\n"; + $i++; + } + } + } + else { + dol_print_error($db); + } + + print '</table>'; print '</div>'; - print '</form>'; + print '</form>'; } print '<br>'; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index d5fed99701e645fda66a3d561912f0329584bd2f..c197d1a23622db7cc02737723fb9167929e2cec4 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -41,13 +41,13 @@ require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; */ class Adherent extends CommonObject { - public $element='member'; - public $table_element='adherent'; - protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + public $element='member'; + public $table_element='adherent'; + protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - var $mesgs; + var $mesgs; - var $login; + var $login; //! Clear password in memory var $pass; @@ -57,128 +57,128 @@ class Adherent extends CommonObject var $pass_indatabase_crypted; var $societe; - var $company; - var $address; - var $zip; - var $town; - - var $state_id; // Id of department - var $state_code; // Code of department - var $state; // Label of department - - var $email; - var $skype; - var $phone; - var $phone_perso; - var $phone_mobile; - - var $morphy; - var $public; - var $statut; // -1:brouillon, 0:resilie, >=1:valide,paye - var $photo; - - var $datec; - var $datem; - var $datefin; - var $datevalid; - var $birth; - - var $note_public; - var $note_private; - - var $typeid; // Id type adherent - var $type; // Libelle type adherent - var $need_subscription; - - var $user_id; - var $user_login; - - var $fk_soc; - - // Fields loaded by fetch_subscriptions() - var $first_subscription_date; - var $first_subscription_amount; - var $last_subscription_date; - var $last_subscription_date_start; - var $last_subscription_date_end; - var $last_subscription_amount; - var $subscriptions=array(); - - var $oldcopy; // To contains a clone of this when we need to save old properties of object - - public $entity; - - /** + var $company; + var $address; + var $zip; + var $town; + + var $state_id; // Id of department + var $state_code; // Code of department + var $state; // Label of department + + var $email; + var $skype; + var $phone; + var $phone_perso; + var $phone_mobile; + + var $morphy; + var $public; + var $statut; // -1:brouillon, 0:resilie, >=1:valide,paye + var $photo; + + var $datec; + var $datem; + var $datefin; + var $datevalid; + var $birth; + + var $note_public; + var $note_private; + + var $typeid; // Id type adherent + var $type; // Libelle type adherent + var $need_subscription; + + var $user_id; + var $user_login; + + var $fk_soc; + + // Fields loaded by fetch_subscriptions() + var $first_subscription_date; + var $first_subscription_amount; + var $last_subscription_date; + var $last_subscription_date_start; + var $last_subscription_date_end; + var $last_subscription_amount; + var $subscriptions=array(); + + var $oldcopy; // To contains a clone of this when we need to save old properties of object + + public $entity; + + /** * Constructor * * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - $this->statut = -1; - // l'adherent n'est pas public par defaut - $this->public = 0; - // les champs optionnels sont vides - $this->array_options=array(); - } - - - /** - * Function sending an email has the adherent with the text supplied in parameter. - * - * @param string $text Content of message (not html entities encoded) - * @param string $subject Subject of message - * @param array $filename_list Array of attached files - * @param array $mimetype_list Array of mime types of attached files - * @param array $mimefilename_list Array of public names of attached files - * @param string $addr_cc Email cc - * @param string $addr_bcc Email bcc - * @param int $deliveryreceipt Ask a delivery receipt - * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection - * @param string $errors_to erros to - * @return int <0 if KO, >0 if OK - */ - function send_an_email($text, $subject, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=-1, $errors_to='') - { - global $conf,$langs; - - // Detect if message is HTML - if ($msgishtml == -1) - { - $msgishtml = 0; - if (dol_textishtml($text,1)) $msgishtml = 1; - } - - $texttosend=$this->makeSubstitution($text); - $subjecttosend=$this->makeSubstitution($subject); - if ($msgishtml) $texttosend=dol_htmlentitiesbr($texttosend); - - // Envoi mail confirmation - $from=$conf->email_from; - if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM; - - // Send email (substitutionarray must be done just before this) - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml); - if ($mailfile->sendfile()) - { - return 1; - } - else - { - $this->error=$langs->trans("ErrorFailedToSendMail",$from,$this->email).'. '.$mailfile->error; - return -1; - } - } - - - /** - * Make substitution of tags into text with value of current object. - * - * @param string $text Text to make substitution to - * @return string Value of input text string with substitutions done - */ + */ + function __construct($db) + { + $this->db = $db; + $this->statut = -1; + // l'adherent n'est pas public par defaut + $this->public = 0; + // les champs optionnels sont vides + $this->array_options=array(); + } + + + /** + * Function sending an email has the adherent with the text supplied in parameter. + * + * @param string $text Content of message (not html entities encoded) + * @param string $subject Subject of message + * @param array $filename_list Array of attached files + * @param array $mimetype_list Array of mime types of attached files + * @param array $mimefilename_list Array of public names of attached files + * @param string $addr_cc Email cc + * @param string $addr_bcc Email bcc + * @param int $deliveryreceipt Ask a delivery receipt + * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection + * @param string $errors_to erros to + * @return int <0 if KO, >0 if OK + */ + function send_an_email($text, $subject, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=-1, $errors_to='') + { + global $conf,$langs; + + // Detect if message is HTML + if ($msgishtml == -1) + { + $msgishtml = 0; + if (dol_textishtml($text,1)) $msgishtml = 1; + } + + $texttosend=$this->makeSubstitution($text); + $subjecttosend=$this->makeSubstitution($subject); + if ($msgishtml) $texttosend=dol_htmlentitiesbr($texttosend); + + // Envoi mail confirmation + $from=$conf->email_from; + if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM; + + // Send email (substitutionarray must be done just before this) + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml); + if ($mailfile->sendfile()) + { + return 1; + } + else + { + $this->error=$langs->trans("ErrorFailedToSendMail",$from,$this->email).'. '.$mailfile->error; + return -1; + } + } + + + /** + * Make substitution of tags into text with value of current object. + * + * @param string $text Text to make substitution to + * @return string Value of input text string with substitutions done + */ function makeSubstitution($text) { global $conf,$langs; @@ -188,1772 +188,1772 @@ class Adherent extends CommonObject $msgishtml = 0; if (dol_textishtml($text,1)) $msgishtml = 1; - $infos=''; - if ($this->civility_id) $infos.= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n"; - $infos.= $langs->transnoentities("id").": ".$this->id."\n"; - $infos.= $langs->transnoentities("Lastname").": ".$this->lastname."\n"; - $infos.= $langs->transnoentities("Firstname").": ".$this->firstname."\n"; - $infos.= $langs->transnoentities("Company").": ".$this->societe."\n"; - $infos.= $langs->transnoentities("Address").": ".$this->address."\n"; - $infos.= $langs->transnoentities("Zip").": ".$this->zip."\n"; - $infos.= $langs->transnoentities("Town").": ".$this->town."\n"; - $infos.= $langs->transnoentities("Country").": ".$this->country."\n"; - $infos.= $langs->transnoentities("EMail").": ".$this->email."\n"; - $infos.= $langs->transnoentities("PhonePro").": ".$this->phone."\n"; - $infos.= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n"; - $infos.= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n"; - if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) + $infos=''; + if ($this->civility_id) $infos.= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n"; + $infos.= $langs->transnoentities("id").": ".$this->id."\n"; + $infos.= $langs->transnoentities("Lastname").": ".$this->lastname."\n"; + $infos.= $langs->transnoentities("Firstname").": ".$this->firstname."\n"; + $infos.= $langs->transnoentities("Company").": ".$this->societe."\n"; + $infos.= $langs->transnoentities("Address").": ".$this->address."\n"; + $infos.= $langs->transnoentities("Zip").": ".$this->zip."\n"; + $infos.= $langs->transnoentities("Town").": ".$this->town."\n"; + $infos.= $langs->transnoentities("Country").": ".$this->country."\n"; + $infos.= $langs->transnoentities("EMail").": ".$this->email."\n"; + $infos.= $langs->transnoentities("PhonePro").": ".$this->phone."\n"; + $infos.= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n"; + $infos.= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n"; + if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) + { + $infos.= $langs->transnoentities("Login").": ".$this->login."\n"; + $infos.= $langs->transnoentities("Password").": ".$this->pass."\n"; + } + $infos.= $langs->transnoentities("Birthday").": ".$birthday."\n"; + $infos.= $langs->transnoentities("Photo").": ".$this->photo."\n"; + $infos.= $langs->transnoentities("Public").": ".yn($this->public); + + // Substitutions + $substitutionarray=array( + '__CIVILITY__'=>$this->getCivilityLabel(), + '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname, + '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname, + '__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs), + '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe, + '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address, + '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip, + '__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town, + '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country, + '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email, + '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday, + '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo, + '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login, + '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass, + '__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):$this->phone, + '__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):$this->phone_perso, + '__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):$this->phone_mobile, + ); + + complete_substitutions_array($substitutionarray, $langs, $this); + + return make_substitutions($text, $substitutionarray, $langs); + } + + + /** + * Return translated label by the nature of a adherent (physical or moral) + * + * @param string $morphy Nature of the adherent (physical or moral) + * @return string Label + */ + function getmorphylib($morphy='') + { + global $langs; + if (! $morphy) { $morphy=$this->morphy; } + if ($morphy == 'phy') { return $langs->trans("Physical"); } + if ($morphy == 'mor') { return $langs->trans("Moral"); } + return $morphy; + } + + /** + * Create a member into database + * + * @param User $user Objet user qui demande la creation + * @param int $notrigger 1 ne declenche pas les triggers, 0 sinon + * @return int <0 if KO, >0 if OK + */ + function create($user,$notrigger=0) + { + global $conf,$langs; + + $error=0; + + $now=dol_now(); + + // Clean parameters + $this->import_key = trim($this->import_key); + + // Check parameters + if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email)) + { + $langs->load("errors"); + $this->error = $langs->trans("ErrorBadEMail",$this->email); + return -1; + } + if (! $this->datec) $this->datec=$now; + if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) + { + if (empty($this->login)) + { + $this->error = $langs->trans("ErrorWrongValueForParameterX","Login"); + return -1; + } + } + + $this->db->begin(); + + // Insert member + $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent"; + $sql.= " (datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key)"; + $sql.= " VALUES ("; + $sql.= " '".$this->db->idate($this->datec)."'"; + $sql.= ", ".($this->login?"'".$this->db->escape($this->login)."'":"null"); + $sql.= ", ".($user->id>0?$user->id:"null"); // Can be null because member can be created by a guest or a script + $sql.= ", null, null, '".$this->db->escape($this->morphy)."'"; + $sql.= ", ".$this->typeid; + $sql.= ", ".$conf->entity; + $sql.= ", ".(! empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'":"null"); + $sql.= ")"; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent"); + if ($id > 0) + { + $this->id=$id; + $this->ref=(string) $id; + + // Update minor fields + $result=$this->update($user,1,1,0,0,'add'); // nosync is 1 to avoid update data of user + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + + // Add link to user + if ($this->user_id) + { + // Add link to user + $sql = "UPDATE ".MAIN_DB_PREFIX."user SET"; + $sql.= " fk_member = ".$this->id; + $sql.= " WHERE rowid = ".$this->user_id; + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) + { + $this->error='Failed to update user to make link with member'; + $this->db->rollback(); + return -4; + } + } + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (count($this->errors)) + { + dol_syslog(get_class($this)."::create ".implode(',',$this->errors), LOG_ERR); + $this->db->rollback(); + return -3; + } + else + { + $this->db->commit(); + return $this->id; + } + } + else + { + $this->error='Failed to get last insert id'; + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Update a member in database (standard information and password) + * + * @param User $user User making update + * @param int $notrigger 1=disable trigger UPDATE (when called by create) + * @param int $nosyncuser 0=Synchronize linked user (standard info), 1=Do not synchronize linked user + * @param int $nosyncuserpass 0=Synchronize linked user (password), 1=Do not synchronize linked user + * @param int $nosyncthirdparty 0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty + * @param string $action Current action for hookmanager + * @return int <0 if KO, >0 if OK + */ + function update($user,$notrigger=0,$nosyncuser=0,$nosyncuserpass=0,$nosyncthirdparty=0,$action='update') + { + global $conf, $langs, $hookmanager; + + $nbrowsaffected=0; + $error=0; + + dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email); + + // Clean parameters + $this->lastname=trim($this->lastname)?trim($this->lastname):trim($this->lastname); + $this->firstname=trim($this->firstname)?trim($this->firstname):trim($this->firstname); + $this->address=($this->address?$this->address:$this->address); + $this->zip=($this->zip?$this->zip:$this->zip); + $this->town=($this->town?$this->town:$this->town); + $this->country_id=($this->country_id > 0?$this->country_id:$this->country_id); + $this->state_id=($this->state_id > 0?$this->state_id:$this->state_id); + if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname=ucwords(trim($this->lastname)); + if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname)); + $this->note_public=($this->note_public?$this->note_public:$this->note_public); + $this->note_private=($this->note_private?$this->note_private:$this->note_private); + + // Check parameters + if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email)) + { + $langs->load("errors"); + $this->error = $langs->trans("ErrorBadEMail",$this->email); + return -1; + } + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; + $sql.= " civility = ".($this->civility_id?"'".$this->db->escape($this->civility_id)."'":"null"); + $sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null"); + $sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); + $sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null"); + $sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null"); + $sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); + $sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null"); + $sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null"); + $sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null"); + $sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null"); + $sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null"); + $sql.= ", email = '".$this->db->escape($this->email)."'"; + $sql.= ", skype = '".$this->db->escape($this->skype)."'"; + $sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null"); + $sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); + $sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); + $sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null"); + $sql.= ", public = '".$this->db->escape($this->public)."'"; + $sql.= ", statut = ".$this->statut; + $sql.= ", fk_adherent_type = ".$this->typeid; + $sql.= ", morphy = '".$this->db->escape($this->morphy)."'"; + $sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null"); + if ($this->datefin) $sql.= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription + if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member + $sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::update update member", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + unset($this->country_code); + unset($this->country); + unset($this->state_code); + unset($this->state); + + $nbrowsaffected+=$this->db->affected_rows($resql); + + $action='update'; + + // Actions on extra fields (by external module) + // TODO le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('memberdao')); + $parameters=array('id'=>$this->id); + $action=''; + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + // Update password + if (! $error && $this->pass) + { + dol_syslog(get_class($this)."::update update password"); + if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) + { + $isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1; + + // If password to set differs from the one found into database + $result=$this->setPassword($user,$this->pass,$isencrypted,$notrigger,$nosyncuserpass); + if (! $nbrowsaffected) $nbrowsaffected++; + } + } + + // Remove links to user and replace with new one + if (! $error) + { + dol_syslog(get_class($this)."::update update link to user"); + $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id; + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; } + // If there is a user linked to this member + if ($this->user_id > 0) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id." WHERE rowid = ".$this->user_id; + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; } + } + } + + if (! $error && $nbrowsaffected) // If something has change in main data + { + // Update information on linked user if it is an update + if (! $error && $this->user_id > 0 && ! $nosyncuser) + { + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + + dol_syslog(get_class($this)."::update update linked user"); + + $luser=new User($this->db); + $result=$luser->fetch($this->user_id); + + if ($result >= 0) + { + //var_dump($this->user_login);exit; + //var_dump($this->login);exit; + $luser->login=$this->login; + $luser->civility_id=$this->civility_id; + $luser->firstname=$this->firstname; + $luser->lastname=$this->lastname; + $luser->pass=$this->pass; + $luser->societe_id=$this->societe; + + $luser->email=$this->email; + $luser->skype=$this->skype; + $luser->office_phone=$this->phone; + $luser->user_mobile=$this->phone_mobile; + + $luser->fk_member=$this->id; + + $result=$luser->update($user,0,1,1); // Use nosync to 1 to avoid cyclic updates + if ($result < 0) + { + $this->error=$luser->error; + dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR); + $error++; + } + } + else + { + $this->error=$luser->error; + $error++; + } + } + + // Update information on linked thirdparty if it is an update + if (! $error && $this->fk_soc > 0 && ! $nosyncthirdparty) + { + require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + + dol_syslog(get_class($this)."::update update linked thirdparty"); + + // This member is linked with a thirdparty, so we also update thirdparty informations + // if this is an update. + $lthirdparty=new Societe($this->db); + $result=$lthirdparty->fetch($this->fk_soc); + + if ($result >= 0) + { + $lthirdparty->address=$this->address; + $lthirdparty->zip=$this->zip; + $lthirdparty->town=$this->town; + $lthirdparty->email=$this->email; + $lthirdparty->skype=$this->skype; + $lthirdparty->phone=$this->phone; + $lthirdparty->state_id=$this->state_id; + $lthirdparty->country_id=$this->country_id; + $lthirdparty->country_id=$this->country_id; + //$lthirdparty->phone_mobile=$this->phone_mobile; + + $result=$lthirdparty->update($this->fk_soc,$user,0,1,1,'update'); // Use sync to 0 to avoid cyclic updates + if ($result < 0) + { + $this->error=$lthirdparty->error; + dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR); + $error++; + } + } + else + { + $this->error=$lthirdparty->error; + $error++; + } + } + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + if (! $error) + { + $this->db->commit(); + return $nbrowsaffected; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -2; + } + } + + + /** + * Update denormalized last subscription date. + * This function is called when we delete a subscription for example. + * + * @param User $user User making change + * @return int <0 if KO, >0 if OK + */ + function update_end_date($user) + { + $this->db->begin(); + + // Search for last subscription id and end date + $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin"; + $sql.= " FROM ".MAIN_DB_PREFIX."subscription"; + $sql.= " WHERE fk_adherent=".$this->id; + $sql.= " ORDER by dateadh DESC"; // Sort by start subscription date + + dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $obj=$this->db->fetch_object($resql); + $dateop=$this->db->jdate($obj->dateop); + $datedeb=$this->db->jdate($obj->datedeb); + $datefin=$this->db->jdate($obj->datefin); + + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; + $sql.= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null"); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->last_subscription_date=$dateop; + $this->last_subscription_date_start=$datedeb; + $this->last_subscription_date_end=$datefin; + $this->datefin=$datefin; + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + + } + + /** + * Fonction qui supprime l'adherent et les donnees associees + * + * @param int $rowid Id of member to delete + * @param User $user User object + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, 0=nothing to do, >0 if OK + */ + function delete($rowid, $user, $notrigger=0) + { + global $conf, $langs; + + $result = 0; + $error=0; + $errorflag=0; + + // Check parameters + if (empty($rowid)) $rowid=$this->id; + + $this->db->begin(); + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_DELETE',$user); + if ($result < 0) $error++; + // End call triggers + } + + // Remove category + $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-1; + } + + // Remove subscription + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-2; + } + } + + // Remove linked user + if (! $error) + { + $ret=$this->setUserId(0); + if ($ret < 0) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-3; + } + } + + // Removed extrafields + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + $errorflag=-4; + dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); + } + } + } + + // Remove adherent + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-5; + } + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return $errorflag; + } + } + + + /** + * Change password of a user + * + * @param User $user Object user de l'utilisateur qui fait la modification + * @param string $password New password (to generate if empty) + * @param int $isencrypted 0 ou 1 si il faut crypter le mot de passe en base (0 par defaut) + * @param int $notrigger 1=Ne declenche pas les triggers + * @param int $nosyncuser Do not synchronize linked user + * @return string If OK return clear password, 0 if no change, < 0 if error + */ + function setPassword($user, $password='', $isencrypted=0, $notrigger=0, $nosyncuser=0) + { + global $conf, $langs; + + $error=0; + + dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." isencrypted=".$isencrypted); + + // If new password not provided, we generate one + if (! $password) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $password=getRandomPassword(false); + } + + // Crypt password + $password_crypted = dol_hash($password); + + $password_indatabase = ''; + if (! $isencrypted) + { + $password_indatabase = $password; + } + + $this->db->begin(); + + // Mise a jour + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent"; + $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."'"; + //if (! empty($conf->global->DATABASE_PWD_ENCRYPTED)) + if ($isencrypted) + { + $sql.= ", pass = null"; + } + else + { + $sql.= ", pass = '".$this->db->escape($password_indatabase)."'"; + } + $sql.= " WHERE rowid = ".$this->id; + + //dol_syslog("Adherent::Password sql=hidden"); + dol_syslog(get_class($this)."::setPassword", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $nbaffectedrows=$this->db->affected_rows($result); + + if ($nbaffectedrows) + { + $this->pass=$password; + $this->pass_indatabase=$password_indatabase; + $this->pass_indatabase_crypted=$password_crypted; + + if ($this->user_id && ! $nosyncuser) + { + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + + // This member is linked with a user, so we also update users informations + // if this is an update. + $luser=new User($this->db); + $result=$luser->fetch($this->user_id); + + if ($result >= 0) + { + $result=$luser->setPassword($user,$this->pass,0,0,1); + if ($result < 0) + { + $this->error=$luser->error; + dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR); + $error++; + } + } + else + { + $this->error=$luser->error; + $error++; + } + } + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_NEW_PASSWORD',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers + } + + $this->db->commit(); + return $this->pass; + } + else + { + $this->db->rollback(); + return 0; + } + } + else + { + $this->db->rollback(); + dol_print_error($this->db); + return -1; + } + } + + + /** + * Set link to a user + * + * @param int $userid Id of user to link to + * @return int 1=OK, -1=KO + */ + function setUserId($userid) + { + global $conf, $langs; + + $this->db->begin(); + + // If user is linked to this member, remove old link to this member + $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id; + dol_syslog(get_class($this)."::setUserId", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -1; } + + // Set link to user + if ($userid > 0) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id; + $sql.= " WHERE rowid = ".$userid; + dol_syslog(get_class($this)."::setUserId", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -2; } + } + + $this->db->commit(); + + return 1; + } + + + /** + * Set link to a third party + * + * @param int $thirdpartyid Id of user to link to + * @return int 1=OK, -1=KO + */ + function setThirdPartyId($thirdpartyid) + { + global $conf, $langs; + + $this->db->begin(); + + // Remove link to third party onto any other members + if ($thirdpartyid > 0) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null"; + $sql.= " WHERE fk_soc = '".$thirdpartyid."'"; + $sql.= " AND entity = ".$conf->entity; + dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG); + $resql = $this->db->query($sql); + } + + // Add link to third party for current member + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid>0 ? $thirdpartyid : 'null'); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Method to load member from its login + * + * @param string $login login of member + * @return void + */ + function fetch_login($login) + { + global $conf; + + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; + $sql.= " WHERE login='".$this->db->escape($login)."'"; + $sql.= " AND entity = ".$conf->entity; + + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + $this->fetch($obj->rowid); + } + } + else + { + dol_print_error($this->db); + } + } + + /** + * Method to load member from its name + * + * @param string $firstname Firstname + * @param string $lastname Lastname + * @return void + */ + function fetch_name($firstname,$lastname) + { + global $conf; + + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; + $sql.= " WHERE firstname='".$this->db->escape($firstname)."'"; + $sql.= " AND lastname='".$this->db->escape($lastname)."'"; + $sql.= " AND entity = ".$conf->entity; + + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + $this->fetch($obj->rowid); + } + } + else + { + dol_print_error($this->db); + } + } + + /** + * Load member from database + * + * @param int $rowid Id of object to load + * @param string $ref To load member from its ref + * @param int $fk_soc To load member from its link to third party + * @param string $ref_ext External reference + * @return int >0 if OK, 0 if not found, <0 if KO + */ + function fetch($rowid,$ref='',$fk_soc='',$ref_ext='') + { + global $langs; + + $sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,"; + $sql.= " d.note_public,"; + $sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,"; + $sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,"; + $sql.= " d.datec as datec,"; + $sql.= " d.tms as datem,"; + $sql.= " d.datefin as datefin,"; + $sql.= " d.birth as birthday,"; + $sql.= " d.datevalid as datev,"; + $sql.= " d.country,"; + $sql.= " d.state_id,"; + $sql.= " d.model_pdf,"; + $sql.= " c.rowid as country_id, c.code as country_code, c.label as country,"; + $sql.= " dep.nom as state, dep.code_departement as state_code,"; + $sql.= " t.libelle as type, t.subscription as subscription,"; + $sql.= " u.rowid as user_id, u.login as user_login"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member"; + $sql.= " WHERE d.fk_adherent_type = t.rowid"; + if ($rowid) $sql.= " AND d.rowid=".$rowid; + elseif ($ref || $fk_soc) { + $sql.= " AND d.entity IN (".getEntity('adherent').")"; + if ($ref) $sql.= " AND d.rowid='".$this->db->escape($ref)."'"; + elseif ($fk_soc > 0) $sql.= " AND d.fk_soc=".$fk_soc; + } + elseif ($ref_ext) + { + $sql.= " AND d.ref_ext='".$this->db->escape($ref_ext)."'"; + } + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->entity = $obj->entity; + $this->ref = $obj->rowid; + $this->id = $obj->rowid; + $this->ref_ext = $obj->ref_ext; + $this->civility_id = $obj->civility_id; + $this->firstname = $obj->firstname; + $this->lastname = $obj->lastname; + $this->login = $obj->login; + $this->societe = $obj->company; + $this->company = $obj->company; + $this->fk_soc = $obj->fk_soc; + $this->address = $obj->address; + $this->zip = $obj->zip; + $this->town = $obj->town; + + $this->pass = $obj->pass; + $this->pass_indatabase = $obj->pass; + $this->pass_indatabase_crypted = $obj->pass_crypted; + + $this->state_id = $obj->state_id; + $this->state_code = $obj->state_id?$obj->state_code:''; + $this->state = $obj->state_id?$obj->state:''; + + $this->country_id = $obj->country_id; + $this->country_code = $obj->country_code; + if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) + $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code); + else + $this->country=$obj->country; + + $this->phone = $obj->phone; + $this->phone_perso = $obj->phone_perso; + $this->phone_mobile = $obj->phone_mobile; + $this->email = $obj->email; + $this->skype = $obj->skype; + + $this->photo = $obj->photo; + $this->statut = $obj->statut; + $this->public = $obj->public; + + $this->datec = $this->db->jdate($obj->datec); + $this->datem = $this->db->jdate($obj->datem); + $this->datefin = $this->db->jdate($obj->datefin); + $this->datevalid = $this->db->jdate($obj->datev); + $this->birth = $this->db->jdate($obj->birthday); + + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->morphy = $obj->morphy; + + $this->typeid = $obj->fk_adherent_type; + $this->type = $obj->type; + $this->need_subscription = $obj->subscription; + + $this->user_id = $obj->user_id; + $this->user_login = $obj->user_login; + + $this->model_pdf = $obj->model_pdf; + + // Retreive all extrafield for thirdparty + // fetch optionals attributes and labels + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); + + // Load other properties + $result=$this->fetch_subscriptions(); + + return $this->id; + } + else + { + return 0; + } + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + + /** + * Fonction qui recupere pour un adherent les parametres + * first_subscription_date + * first_subscription_amount + * last_subscription_date + * last_subscription_amount + * + * @return int <0 si KO, >0 si OK + */ + function fetch_subscriptions() + { + global $langs; + + require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; + + $sql = "SELECT c.rowid, c.fk_adherent, c.subscription, c.note, c.fk_bank,"; + $sql.= " c.tms as datem,"; + $sql.= " c.datec as datec,"; + $sql.= " c.dateadh as dateh,"; + $sql.= " c.datef as datef"; + $sql.= " FROM ".MAIN_DB_PREFIX."subscription as c"; + $sql.= " WHERE c.fk_adherent = ".$this->id; + $sql.= " ORDER BY c.dateadh"; + dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG); + + $resql=$this->db->query($sql); + if ($resql) + { + $this->subscriptions=array(); + + $i=0; + while ($obj = $this->db->fetch_object($resql)) + { + if ($i==0) + { + $this->first_subscription_date=$obj->dateh; + $this->first_subscription_amount=$obj->subscription; + } + $this->last_subscription_date=$obj->dateh; + $this->last_subscription_amount=$obj->subscription; + + $subscription=new Subscription($this->db); + $subscription->id=$obj->rowid; + $subscription->fk_adherent=$obj->fk_adherent; + $subscription->amount=$obj->subscription; + $subscription->note=$obj->note; + $subscription->fk_bank=$obj->fk_bank; + $subscription->datem=$this->db->jdate($obj->datem); + $subscription->datec=$this->db->jdate($obj->datec); + $subscription->dateh=$this->db->jdate($obj->dateh); + $subscription->datef=$this->db->jdate($obj->datef); + + $this->subscriptions[]=$subscription; + + $i++; + } + return 1; + } + else + { + $this->error=$this->db->error().' sql='.$sql; + return -1; + } + } + + + /** + * Insert subscription into database and eventually add links to banks, mailman, etc... + * + * @param int $date Date of effect of subscription + * @param double $montant Amount of subscription (0 accepted for some members) + * @param int $accountid Id bank account + * @param string $operation Type operation (if Id bank account provided) + * @param string $label Label operation (if Id bank account provided) + * @param string $num_chq Numero cheque (if Id bank account provided) + * @param string $emetteur_nom Name of cheque writer + * @param string $emetteur_banque Name of bank of cheque + * @param int $datesubend Date end subscription + * @return int rowid of record added, <0 if KO + */ + function subscription($date, $montant, $accountid=0, $operation='', $label='', $num_chq='', $emetteur_nom='', $emetteur_banque='', $datesubend=0) + { + global $conf,$langs,$user; + + require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; + + $error=0; + + // Clean parameters + if (! $montant) $montant=0; + + $this->db->begin(); + + if ($datesubend) + { + $datefin=$datesubend; + } + else + { + // If no end date, end date = date + 1 year - 1 day + $datefin = dol_time_plus_duree($date,1,'y'); + $datefin = dol_time_plus_duree($datefin,-1,'d'); + } + + // Create subscription + $subscription=new Subscription($this->db); + $subscription->fk_adherent=$this->id; + $subscription->dateh=$date; // Date of new subscription + $subscription->datef=$datefin; // End data of new subscription + $subscription->amount=$montant; + $subscription->note=$label; + + $rowid=$subscription->create($user); + if ($rowid > 0) + { + // Update denormalized subscription end date (read database subscription to find values) + // This will also update this->datefin + $result=$this->update_end_date($user); + if ($result > 0) + { + // Change properties of object (used by triggers) + $this->last_subscription_date=dol_now(); + $this->last_subscription_amount=$montant; + $this->last_subscription_date_start=$date; + $this->last_subscription_date_end=$datefin; + + // Call trigger + $result=$this->call_trigger('MEMBER_SUBSCRIPTION',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return $rowid; + } + else + { + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$subscription->error; + $this->db->rollback(); + return -1; + } + } + + /** + * Function that validate a member + * + * @param User $user user adherent qui valide + * @return int <0 if KO, 0 if nothing done, >0 if OK + */ + function validate($user) + { + global $langs,$conf; + + $error=0; + $now=dol_now(); + + // Check parameters + if ($this->statut == 1) + { + dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING); + return 0; + } + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; + $sql.= " statut = 1"; + $sql.= ", datevalid = '".$this->db->idate($now)."'"; + $sql.= ", fk_user_valid=".$user->id; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::validate", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $this->statut=1; + + // Call trigger + $result=$this->call_trigger('MEMBER_VALIDATE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Fonction qui resilie un adherent + * + * @param User $user User making change + * @return int <0 if KO, >0 if OK + */ + function resiliate($user) + { + global $langs,$conf; + + $error=0; + + // Check paramaters + if ($this->statut == 0) + { + dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING); + return 0; + } + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; + $sql.= " statut = 0"; + $sql.= ", fk_user_valid=".$user->id; + $sql.= " WHERE rowid = ".$this->id; + + $result = $this->db->query($sql); + if ($result) + { + $this->statut=0; + + // Call trigger + $result=$this->call_trigger('MEMBER_RESILIATE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Function to add member into external tools mailing-list, spip, etc. + * + * @return int <0 if KO, >0 if OK + */ + function add_to_abo() + { + global $conf,$langs; + + include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php'; + $mailmanspip=new MailmanSpip($this->db); + + $err=0; + + // mailman + if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled)) + { + $result=$mailmanspip->add_to_mailman($this); + + if ($result < 0) + { + if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error; + $err+=1; + } + foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) + { + $langs->load("errors"); + $this->errors[]=$langs->trans("ErrorFailedToAddToMailmanList",$tmpemail,$tmplist); + } + foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) + { + $langs->load("mailmanspip"); + $this->mesgs[]=$langs->trans("SuccessToAddToMailmanList",$tmpemail,$tmplist); + } + } + + // spip + if (! empty($conf->global->ADHERENT_USE_SPIP) && ! empty($conf->mailmanspip->enabled)) + { + $result=$mailmanspip->add_to_spip($this); + if ($result < 0) + { + $this->errors[]=$mailmanspip->error; + $err+=1; + } + } + if ($err) + { + return -$err; + } + else + { + return 1; + } + } + + + /** + * Function to delete a member from external tools like mailing-list, spip, etc. + * + * @return int <0 if KO, >0 if OK + */ + function del_to_abo() + { + global $conf,$langs; + + include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php'; + $mailmanspip=new MailmanSpip($this->db); + + $err=0; + + // mailman + if (! empty($conf->global->ADHERENT_USE_MAILMAN)) + { + $result=$mailmanspip->del_to_mailman($this); + if ($result < 0) + { + if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error; + $err+=1; + } + + foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) + { + $langs->load("errors"); + $this->errors[]=$langs->trans("ErrorFailedToRemoveToMailmanList",$tmpemail,$tmplist); + } + foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) + { + $langs->load("mailmanspip"); + $this->mesgs[]=$langs->trans("SuccessToRemoveToMailmanList",$tmpemail,$tmplist); + } + } + + if ($conf->global->ADHERENT_USE_SPIP && ! empty($conf->mailmanspip->enabled)) { - $infos.= $langs->transnoentities("Login").": ".$this->login."\n"; - $infos.= $langs->transnoentities("Password").": ".$this->pass."\n"; + $result=$mailmanspip->del_to_spip($this); + if ($result < 0) + { + $this->errors[]=$mailmanspip->error; + $err+=1; + } } - $infos.= $langs->transnoentities("Birthday").": ".$birthday."\n"; - $infos.= $langs->transnoentities("Photo").": ".$this->photo."\n"; - $infos.= $langs->transnoentities("Public").": ".yn($this->public); + if ($err) + { + // error + return -$err; + } + else + { + return 1; + } + } - // Substitutions - $substitutionarray=array( - '__CIVILITY__'=>$this->getCivilityLabel(), - '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname, - '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname, - '__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs), - '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe, - '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address, - '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip, - '__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town, - '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country, - '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email, - '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday, - '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo, - '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login, - '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass, - '__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):$this->phone, - '__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):$this->phone_perso, - '__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):$this->phone_mobile, - ); - complete_substitutions_array($substitutionarray, $langs, $this); + /** + * Return civility label of a member + * + * @return string Translated name of civility (translated with transnoentitiesnoconv) + */ + function getCivilityLabel() + { + global $langs; + $langs->load("dict"); - return make_substitutions($text, $substitutionarray, $langs); + $code=(empty($this->civility_id)?'':$this->civility_id); + if (empty($code)) return ''; + return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code); } + /** + * Return clicable name (with picto eventually) + * + * @param int $withpictoimg 0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) + * @param int $maxlen length max label + * @param string $option Page for link ('card', 'category', 'subscription', ...) + * @param string $mode ''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string Chaine avec URL + */ + function getNomUrl($withpictoimg=0, $maxlen=0, $option='card', $mode='', $morecss='', $save_lastsearch_value=-1) + { + global $conf, $langs; - /** - * Return translated label by the nature of a adherent (physical or moral) - * - * @param string $morphy Nature of the adherent (physical or moral) - * @return string Label - */ - function getmorphylib($morphy='') - { - global $langs; - if (! $morphy) { $morphy=$this->morphy; } - if ($morphy == 'phy') { return $langs->trans("Physical"); } - if ($morphy == 'mor') { return $langs->trans("Moral"); } - return $morphy; - } - - /** - * Create a member into database - * - * @param User $user Objet user qui demande la creation - * @param int $notrigger 1 ne declenche pas les triggers, 0 sinon - * @return int <0 if KO, >0 if OK - */ - function create($user,$notrigger=0) - { - global $conf,$langs; + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; - $error=0; + $result=''; $label=''; + $link=''; $linkstart=''; $linkend=''; - $now=dol_now(); - - // Clean parameters - $this->import_key = trim($this->import_key); - - // Check parameters - if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email)) - { - $langs->load("errors"); - $this->error = $langs->trans("ErrorBadEMail",$this->email); - return -1; - } - if (! $this->datec) $this->datec=$now; - if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) - { - if (empty($this->login)) - { - $this->error = $langs->trans("ErrorWrongValueForParameterX","Login"); - return -1; - } - } - - $this->db->begin(); - - // Insert member - $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent"; - $sql.= " (datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key)"; - $sql.= " VALUES ("; - $sql.= " '".$this->db->idate($this->datec)."'"; - $sql.= ", ".($this->login?"'".$this->db->escape($this->login)."'":"null"); - $sql.= ", ".($user->id>0?$user->id:"null"); // Can be null because member can be created by a guest or a script - $sql.= ", null, null, '".$this->db->escape($this->morphy)."'"; - $sql.= ", ".$this->typeid; - $sql.= ", ".$conf->entity; - $sql.= ", ".(! empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'":"null"); - $sql.= ")"; - - dol_syslog(get_class($this)."::create", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent"); - if ($id > 0) - { - $this->id=$id; - $this->ref=(string) $id; - - // Update minor fields - $result=$this->update($user,1,1,0,0,'add'); // nosync is 1 to avoid update data of user - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - - // Add link to user - if ($this->user_id) - { - // Add link to user - $sql = "UPDATE ".MAIN_DB_PREFIX."user SET"; - $sql.= " fk_member = ".$this->id; - $sql.= " WHERE rowid = ".$this->user_id; - dol_syslog(get_class($this)."::create", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) - { - $this->error='Failed to update user to make link with member'; - $this->db->rollback(); - return -4; - } - } - - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('MEMBER_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - - if (count($this->errors)) - { - dol_syslog(get_class($this)."::create ".implode(',',$this->errors), LOG_ERR); - $this->db->rollback(); - return -3; - } - else - { - $this->db->commit(); - return $this->id; - } - } - else - { - $this->error='Failed to get last insert id'; - dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } - - - /** - * Update a member in database (standard information and password) - * - * @param User $user User making update - * @param int $notrigger 1=disable trigger UPDATE (when called by create) - * @param int $nosyncuser 0=Synchronize linked user (standard info), 1=Do not synchronize linked user - * @param int $nosyncuserpass 0=Synchronize linked user (password), 1=Do not synchronize linked user - * @param int $nosyncthirdparty 0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty - * @param string $action Current action for hookmanager - * @return int <0 if KO, >0 if OK - */ - function update($user,$notrigger=0,$nosyncuser=0,$nosyncuserpass=0,$nosyncthirdparty=0,$action='update') - { - global $conf, $langs, $hookmanager; - - $nbrowsaffected=0; - $error=0; - - dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email); - - // Clean parameters - $this->lastname=trim($this->lastname)?trim($this->lastname):trim($this->lastname); - $this->firstname=trim($this->firstname)?trim($this->firstname):trim($this->firstname); - $this->address=($this->address?$this->address:$this->address); - $this->zip=($this->zip?$this->zip:$this->zip); - $this->town=($this->town?$this->town:$this->town); - $this->country_id=($this->country_id > 0?$this->country_id:$this->country_id); - $this->state_id=($this->state_id > 0?$this->state_id:$this->state_id); - if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname=ucwords(trim($this->lastname)); - if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname)); - $this->note_public=($this->note_public?$this->note_public:$this->note_public); - $this->note_private=($this->note_private?$this->note_private:$this->note_private); + if (! empty($this->photo)) + { + $label.= '<div class="photointooltip">'; + $label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); + $label.= '</div><div style="clear: both;"></div>'; + } - // Check parameters - if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email)) - { - $langs->load("errors"); - $this->error = $langs->trans("ErrorBadEMail",$this->email); - return -1; - } - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " civility = ".($this->civility_id?"'".$this->db->escape($this->civility_id)."'":"null"); - $sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null"); - $sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); - $sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null"); - $sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null"); - $sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); - $sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null"); - $sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null"); - $sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null"); - $sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null"); - $sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null"); - $sql.= ", email = '".$this->db->escape($this->email)."'"; - $sql.= ", skype = '".$this->db->escape($this->skype)."'"; - $sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null"); - $sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); - $sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); - $sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); - $sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); - $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null"); - $sql.= ", public = '".$this->db->escape($this->public)."'"; - $sql.= ", statut = ".$this->statut; - $sql.= ", fk_adherent_type = ".$this->typeid; - $sql.= ", morphy = '".$this->db->escape($this->morphy)."'"; - $sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null"); - if ($this->datefin) $sql.= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription - if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member - $sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::update update member", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - unset($this->country_code); - unset($this->country); - unset($this->state_code); - unset($this->state); - - $nbrowsaffected+=$this->db->affected_rows($resql); - - $action='update'; - - // Actions on extra fields (by external module) - // TODO le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('memberdao')); - $parameters=array('id'=>$this->id); - $action=''; - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; - - // Update password - if (! $error && $this->pass) - { - dol_syslog(get_class($this)."::update update password"); - if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) - { - $isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1; - - // If password to set differs from the one found into database - $result=$this->setPassword($user,$this->pass,$isencrypted,$notrigger,$nosyncuserpass); - if (! $nbrowsaffected) $nbrowsaffected++; - } - } - - // Remove links to user and replace with new one - if (! $error) - { - dol_syslog(get_class($this)."::update update link to user"); - $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id; - dol_syslog(get_class($this)."::update", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; } - // If there is a user linked to this member - if ($this->user_id > 0) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id." WHERE rowid = ".$this->user_id; - dol_syslog(get_class($this)."::update", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; } - } - } - - if (! $error && $nbrowsaffected) // If something has change in main data - { - // Update information on linked user if it is an update - if (! $error && $this->user_id > 0 && ! $nosyncuser) - { - require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; - - dol_syslog(get_class($this)."::update update linked user"); - - $luser=new User($this->db); - $result=$luser->fetch($this->user_id); - - if ($result >= 0) - { - //var_dump($this->user_login);exit; - //var_dump($this->login);exit; - $luser->login=$this->login; - $luser->civility_id=$this->civility_id; - $luser->firstname=$this->firstname; - $luser->lastname=$this->lastname; - $luser->pass=$this->pass; - $luser->societe_id=$this->societe; - - $luser->email=$this->email; - $luser->skype=$this->skype; - $luser->office_phone=$this->phone; - $luser->user_mobile=$this->phone_mobile; - - $luser->fk_member=$this->id; - - $result=$luser->update($user,0,1,1); // Use nosync to 1 to avoid cyclic updates - if ($result < 0) - { - $this->error=$luser->error; - dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR); - $error++; - } - } - else - { - $this->error=$luser->error; - $error++; - } - } - - // Update information on linked thirdparty if it is an update - if (! $error && $this->fk_soc > 0 && ! $nosyncthirdparty) - { - require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; - - dol_syslog(get_class($this)."::update update linked thirdparty"); - - // This member is linked with a thirdparty, so we also update thirdparty informations - // if this is an update. - $lthirdparty=new Societe($this->db); - $result=$lthirdparty->fetch($this->fk_soc); - - if ($result >= 0) - { - $lthirdparty->address=$this->address; - $lthirdparty->zip=$this->zip; - $lthirdparty->town=$this->town; - $lthirdparty->email=$this->email; - $lthirdparty->skype=$this->skype; - $lthirdparty->phone=$this->phone; - $lthirdparty->state_id=$this->state_id; - $lthirdparty->country_id=$this->country_id; - $lthirdparty->country_id=$this->country_id; - //$lthirdparty->phone_mobile=$this->phone_mobile; - - $result=$lthirdparty->update($this->fk_soc,$user,0,1,1,'update'); // Use sync to 0 to avoid cyclic updates - if ($result < 0) - { - $this->error=$lthirdparty->error; - dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR); - $error++; - } - } - else - { - $this->error=$lthirdparty->error; - $error++; - } - } - - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('MEMBER_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - if (! $error) - { - $this->db->commit(); - return $nbrowsaffected; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -2; - } - } - - - /** - * Update denormalized last subscription date. - * This function is called when we delete a subscription for example. - * - * @param User $user User making change - * @return int <0 if KO, >0 if OK - */ - function update_end_date($user) - { - $this->db->begin(); - - // Search for last subscription id and end date - $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin"; - $sql.= " FROM ".MAIN_DB_PREFIX."subscription"; - $sql.= " WHERE fk_adherent=".$this->id; - $sql.= " ORDER by dateadh DESC"; // Sort by start subscription date - - dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $obj=$this->db->fetch_object($resql); - $dateop=$this->db->jdate($obj->dateop); - $datedeb=$this->db->jdate($obj->datedeb); - $datefin=$this->db->jdate($obj->datefin); - - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null"); - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->last_subscription_date=$dateop; - $this->last_subscription_date_start=$datedeb; - $this->last_subscription_date_end=$datefin; - $this->datefin=$datefin; - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - - } - - /** - * Fonction qui supprime l'adherent et les donnees associees - * - * @param int $rowid Id of member to delete - * @param User $user User object - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, 0=nothing to do, >0 if OK - */ - function delete($rowid, $user, $notrigger=0) - { - global $conf, $langs; + $label.= '<div class="centpercent">'; + $label.= '<u>' . $langs->trans("Member") . '</u>'; + if (! empty($this->ref)) + $label.= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; + if (! empty($this->firstname) || ! empty($this->lastname)) + $label.= '<br><b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs); + $label.='</div>'; - $result = 0; - $error=0; - $errorflag=0; + $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.$this->id; + if ($option == 'subscription') + { + $url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.$this->id; + } - // Check parameters - if (empty($rowid)) $rowid=$this->id; + if ($option != 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; + if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; + } - $this->db->begin(); + $link = '<a href="'.$url.'"'; + $linkclose=""; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $langs->load("users"); + $label=$langs->trans("ShowUser"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('MEMBER_DELETE',$user); - if ($result < 0) $error++; - // End call triggers - } + $link.=$linkclose.'>'; + $linkend='</a>'; - // Remove category - $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) + //if ($withpictoimg == -1) $result.='<div class="nowrap">'; + $result.=$link; + if ($withpictoimg) { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-1; + $paddafterimage=''; + if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"'; + // Only picto + if ($withpictoimg > 0) $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>'; + // Picto must be a photo + else $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>'; + $result.=$picto; + } + if ($withpictoimg > -2 && $withpictoimg != 2) + { + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<div class="inline-block nopadding valignmiddle'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' usertext'.$morecss:'').'">'; + if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen); + elseif ($mode == 'ref') $result.=$this->id; + else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen); + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</div>'; } + $result.=$linkend; + //if ($withpictoimg == -1) $result.='</div>'; - // Remove subscription - if (! $error) + return $result; + } + + /** + * Retourne le libelle du statut d'un adherent (brouillon, valide, resilie) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut,$this->need_subscription,$this->datefin,$mode); + } + + /** + * Renvoi le libelle d'un statut donne + * + * @param int $statut Id statut + * @param int $need_subscription 1 if member type need subscription, 0 otherwise + * @param int $date_end_subscription Date fin adhesion + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label + */ + function LibStatut($statut,$need_subscription,$date_end_subscription,$mode=0) + { + global $langs; + $langs->load("members"); + if ($mode == 0) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) + if ($statut == -1) return $langs->trans("MemberStatusDraft"); + if ($statut >= 1) { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-2; + if (! $date_end_subscription) return $langs->trans("MemberStatusActive"); + elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate"); + else return $langs->trans("MemberStatusPaid"); } + if ($statut == 0) return $langs->trans("MemberStatusResiliated"); } - - // Remove linked user - if (! $error) + if ($mode == 1) { - $ret=$this->setUserId(0); - if ($ret < 0) + if ($statut == -1) return $langs->trans("MemberStatusDraftShort"); + if ($statut >= 1) { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-3; + if (! $date_end_subscription) return $langs->trans("MemberStatusActiveShort"); + elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLateShort"); + else return $langs->trans("MemberStatusPaidShort"); } + if ($statut == 0) return $langs->trans("MemberStatusResiliatedShort"); } - - // Removed extrafields - if (! $error) + if ($mode == 2) { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraftShort"); + if ($statut >= 1) { - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $error++; - $errorflag=-4; - dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); - } + if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActiveShort"); + elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLateShort"); + else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaidShort"); } + if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliatedShort"); } - - // Remove adherent - if (! $error) + if ($mode == 3) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) + if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0'); + if ($statut >= 1) { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-5; + if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1'); + elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3'); + else return img_picto($langs->trans('MemberStatusPaid'),'statut4'); + } + if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5'); + } + if ($mode == 4) + { + if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraft"); + if ($statut >= 1) + { + if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActive"); + elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLate"); + else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaid"); + } + if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliated"); + } + if ($mode == 5) + { + if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0'); + if ($statut >= 1) + { + if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveShort").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1'); + elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLateShort").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3'); + else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaidShort").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4'); + } + if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5'); + } + if ($mode == 6) + { + if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0'); + if ($statut >= 1) + { + if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActive").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1'); + elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLate").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3'); + else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaid").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4'); } + if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5'); } + } - if (! $error) + + /** + * Charge indicateurs this->nb de tableau de bord + * + * @return int <0 if KO, >0 if OK + */ + function load_state_board() + { + global $conf; + + $this->nb=array(); + + $sql = "SELECT count(a.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; + $sql.= " WHERE a.statut > 0"; + $sql.= " AND a.entity IN (".getEntity('adherent').")"; + + $resql=$this->db->query($sql); + if ($resql) { - $this->db->commit(); + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["members"]=$obj->nb; + } + $this->db->free($resql); return 1; } else { - $this->db->rollback(); - return $errorflag; + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; } + } + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Objet user + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK + */ + function load_board($user) + { + global $conf, $langs; + + if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe - /** - * Change password of a user - * - * @param User $user Object user de l'utilisateur qui fait la modification - * @param string $password New password (to generate if empty) - * @param int $isencrypted 0 ou 1 si il faut crypter le mot de passe en base (0 par defaut) - * @param int $notrigger 1=Ne declenche pas les triggers - * @param int $nosyncuser Do not synchronize linked user - * @return string If OK return clear password, 0 if no change, < 0 if error - */ - function setPassword($user, $password='', $isencrypted=0, $notrigger=0, $nosyncuser=0) - { - global $conf, $langs; - - $error=0; - - dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." isencrypted=".$isencrypted); - - // If new password not provided, we generate one - if (! $password) - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; - $password=getRandomPassword(false); - } - - // Crypt password - $password_crypted = dol_hash($password); - - $password_indatabase = ''; - if (! $isencrypted) - { - $password_indatabase = $password; - } - - $this->db->begin(); - - // Mise a jour - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent"; - $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."'"; - //if (! empty($conf->global->DATABASE_PWD_ENCRYPTED)) - if ($isencrypted) - { - $sql.= ", pass = null"; - } - else - { - $sql.= ", pass = '".$this->db->escape($password_indatabase)."'"; - } - $sql.= " WHERE rowid = ".$this->id; - - //dol_syslog("Adherent::Password sql=hidden"); - dol_syslog(get_class($this)."::setPassword", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $nbaffectedrows=$this->db->affected_rows($result); - - if ($nbaffectedrows) - { - $this->pass=$password; - $this->pass_indatabase=$password_indatabase; - $this->pass_indatabase_crypted=$password_crypted; - - if ($this->user_id && ! $nosyncuser) - { - require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; - - // This member is linked with a user, so we also update users informations - // if this is an update. - $luser=new User($this->db); - $result=$luser->fetch($this->user_id); - - if ($result >= 0) - { - $result=$luser->setPassword($user,$this->pass,0,0,1); - if ($result < 0) - { - $this->error=$luser->error; - dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR); - $error++; - } - } - else - { - $this->error=$luser->error; - $error++; - } - } - - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('MEMBER_NEW_PASSWORD',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers - } - - $this->db->commit(); - return $this->pass; - } - else - { - $this->db->rollback(); - return 0; - } - } - else - { - $this->db->rollback(); - dol_print_error($this->db); - return -1; - } - } - - - /** - * Set link to a user - * - * @param int $userid Id of user to link to - * @return int 1=OK, -1=KO - */ - function setUserId($userid) - { - global $conf, $langs; - - $this->db->begin(); - - // If user is linked to this member, remove old link to this member - $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id; - dol_syslog(get_class($this)."::setUserId", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -1; } - - // Set link to user - if ($userid > 0) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id; - $sql.= " WHERE rowid = ".$userid; - dol_syslog(get_class($this)."::setUserId", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -2; } - } - - $this->db->commit(); - - return 1; - } - - - /** - * Set link to a third party - * - * @param int $thirdpartyid Id of user to link to - * @return int 1=OK, -1=KO - */ - function setThirdPartyId($thirdpartyid) - { - global $conf, $langs; - - $this->db->begin(); - - // Remove link to third party onto any other members - if ($thirdpartyid > 0) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null"; - $sql.= " WHERE fk_soc = '".$thirdpartyid."'"; - $sql.= " AND entity = ".$conf->entity; - dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG); - $resql = $this->db->query($sql); - } - - // Add link to third party for current member - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid>0 ? $thirdpartyid : 'null'); - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } - - - /** - * Method to load member from its login - * - * @param string $login login of member - * @return void - */ - function fetch_login($login) - { - global $conf; - - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; - $sql.= " WHERE login='".$this->db->escape($login)."'"; - $sql.= " AND entity = ".$conf->entity; - - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); - $this->fetch($obj->rowid); - } - } - else - { - dol_print_error($this->db); - } - } - - /** - * Method to load member from its name - * - * @param string $firstname Firstname - * @param string $lastname Lastname - * @return void - */ - function fetch_name($firstname,$lastname) - { - global $conf; - - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; - $sql.= " WHERE firstname='".$this->db->escape($firstname)."'"; - $sql.= " AND lastname='".$this->db->escape($lastname)."'"; - $sql.= " AND entity = ".$conf->entity; - - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); - $this->fetch($obj->rowid); - } - } - else - { - dol_print_error($this->db); - } - } - - /** - * Load member from database - * - * @param int $rowid Id of object to load - * @param string $ref To load member from its ref - * @param int $fk_soc To load member from its link to third party - * @param string $ref_ext External reference - * @return int >0 if OK, 0 if not found, <0 if KO - */ - function fetch($rowid,$ref='',$fk_soc='',$ref_ext='') - { - global $langs; - - $sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,"; - $sql.= " d.note_public,"; - $sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,"; - $sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,"; - $sql.= " d.datec as datec,"; - $sql.= " d.tms as datem,"; - $sql.= " d.datefin as datefin,"; - $sql.= " d.birth as birthday,"; - $sql.= " d.datevalid as datev,"; - $sql.= " d.country,"; - $sql.= " d.state_id,"; - $sql.= " d.model_pdf,"; - $sql.= " c.rowid as country_id, c.code as country_code, c.label as country,"; - $sql.= " dep.nom as state, dep.code_departement as state_code,"; - $sql.= " t.libelle as type, t.subscription as subscription,"; - $sql.= " u.rowid as user_id, u.login as user_login"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member"; - $sql.= " WHERE d.fk_adherent_type = t.rowid"; - if ($rowid) $sql.= " AND d.rowid=".$rowid; - elseif ($ref || $fk_soc) { - $sql.= " AND d.entity IN (".getEntity('adherent').")"; - if ($ref) $sql.= " AND d.rowid='".$this->db->escape($ref)."'"; - elseif ($fk_soc > 0) $sql.= " AND d.fk_soc=".$fk_soc; - } - elseif ($ref_ext) - { - $sql.= " AND d.ref_ext='".$this->db->escape($ref_ext)."'"; - } - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); - - $this->entity = $obj->entity; - $this->ref = $obj->rowid; - $this->id = $obj->rowid; - $this->ref_ext = $obj->ref_ext; - $this->civility_id = $obj->civility_id; - $this->firstname = $obj->firstname; - $this->lastname = $obj->lastname; - $this->login = $obj->login; - $this->societe = $obj->company; - $this->company = $obj->company; - $this->fk_soc = $obj->fk_soc; - $this->address = $obj->address; - $this->zip = $obj->zip; - $this->town = $obj->town; - - $this->pass = $obj->pass; - $this->pass_indatabase = $obj->pass; - $this->pass_indatabase_crypted = $obj->pass_crypted; - - $this->state_id = $obj->state_id; - $this->state_code = $obj->state_id?$obj->state_code:''; - $this->state = $obj->state_id?$obj->state:''; - - $this->country_id = $obj->country_id; - $this->country_code = $obj->country_code; - if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) - $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code); - else - $this->country=$obj->country; - - $this->phone = $obj->phone; - $this->phone_perso = $obj->phone_perso; - $this->phone_mobile = $obj->phone_mobile; - $this->email = $obj->email; - $this->skype = $obj->skype; - - $this->photo = $obj->photo; - $this->statut = $obj->statut; - $this->public = $obj->public; - - $this->datec = $this->db->jdate($obj->datec); - $this->datem = $this->db->jdate($obj->datem); - $this->datefin = $this->db->jdate($obj->datefin); - $this->datevalid = $this->db->jdate($obj->datev); - $this->birth = $this->db->jdate($obj->birthday); - - $this->note_private = $obj->note_private; - $this->note_public = $obj->note_public; - $this->morphy = $obj->morphy; - - $this->typeid = $obj->fk_adherent_type; - $this->type = $obj->type; - $this->need_subscription = $obj->subscription; - - $this->user_id = $obj->user_id; - $this->user_login = $obj->user_login; - - $this->model_pdf = $obj->model_pdf; - - // Retreive all extrafield for thirdparty - // fetch optionals attributes and labels - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields=new ExtraFields($this->db); - $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); - $this->fetch_optionals($this->id,$extralabels); - - // Load other properties - $result=$this->fetch_subscriptions(); - - return $this->id; - } - else - { - return 0; - } - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } - - - /** - * Fonction qui recupere pour un adherent les parametres - * first_subscription_date - * first_subscription_amount - * last_subscription_date - * last_subscription_amount - * - * @return int <0 si KO, >0 si OK - */ - function fetch_subscriptions() - { - global $langs; + $now=dol_now(); - require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; + $sql = "SELECT a.rowid, a.datefin, a.statut"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; + $sql.= " WHERE a.statut = 1"; + $sql.= " AND a.entity IN (".getEntity('adherent').")"; + $sql.= " AND (a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."')"; - $sql = "SELECT c.rowid, c.fk_adherent, c.subscription, c.note, c.fk_bank,"; - $sql.= " c.tms as datem,"; - $sql.= " c.datec as datec,"; - $sql.= " c.dateadh as dateh,"; - $sql.= " c.datef as datef"; - $sql.= " FROM ".MAIN_DB_PREFIX."subscription as c"; - $sql.= " WHERE c.fk_adherent = ".$this->id; - $sql.= " ORDER BY c.dateadh"; - dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG); - - $resql=$this->db->query($sql); - if ($resql) - { - $this->subscriptions=array(); - - $i=0; - while ($obj = $this->db->fetch_object($resql)) - { - if ($i==0) - { - $this->first_subscription_date=$obj->dateh; - $this->first_subscription_amount=$obj->subscription; - } - $this->last_subscription_date=$obj->dateh; - $this->last_subscription_amount=$obj->subscription; - - $subscription=new Subscription($this->db); - $subscription->id=$obj->rowid; - $subscription->fk_adherent=$obj->fk_adherent; - $subscription->amount=$obj->subscription; - $subscription->note=$obj->note; - $subscription->fk_bank=$obj->fk_bank; - $subscription->datem=$this->db->jdate($obj->datem); - $subscription->datec=$this->db->jdate($obj->datec); - $subscription->dateh=$this->db->jdate($obj->dateh); - $subscription->datef=$this->db->jdate($obj->datef); - - $this->subscriptions[]=$subscription; - - $i++; - } - return 1; - } - else - { - $this->error=$this->db->error().' sql='.$sql; - return -1; - } - } - - - /** - * Insert subscription into database and eventually add links to banks, mailman, etc... - * - * @param int $date Date of effect of subscription - * @param double $montant Amount of subscription (0 accepted for some members) - * @param int $accountid Id bank account - * @param string $operation Type operation (if Id bank account provided) - * @param string $label Label operation (if Id bank account provided) - * @param string $num_chq Numero cheque (if Id bank account provided) - * @param string $emetteur_nom Name of cheque writer - * @param string $emetteur_banque Name of bank of cheque - * @param int $datesubend Date end subscription - * @return int rowid of record added, <0 if KO - */ - function subscription($date, $montant, $accountid=0, $operation='', $label='', $num_chq='', $emetteur_nom='', $emetteur_banque='', $datesubend=0) - { - global $conf,$langs,$user; + $resql=$this->db->query($sql); + if ($resql) + { + $langs->load("members"); - require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; + $response = new WorkboardResponse(); + $response->warning_delay=$conf->adherent->subscription->warning_delay/60/60/24; + $response->label=$langs->trans("MembersWithSubscriptionToReceive"); + $response->url=DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&statut=1&filter=outofdate'; + $response->img=img_object('',"user"); - $error=0; + $adherentstatic = new Adherent($this->db); - // Clean parameters - if (! $montant) $montant=0; - - $this->db->begin(); - - if ($datesubend) - { - $datefin=$datesubend; - } - else - { - // If no end date, end date = date + 1 year - 1 day - $datefin = dol_time_plus_duree($date,1,'y'); - $datefin = dol_time_plus_duree($datefin,-1,'d'); - } - - // Create subscription - $subscription=new Subscription($this->db); - $subscription->fk_adherent=$this->id; - $subscription->dateh=$date; // Date of new subscription - $subscription->datef=$datefin; // End data of new subscription - $subscription->amount=$montant; - $subscription->note=$label; - - $rowid=$subscription->create($user); - if ($rowid > 0) - { - // Update denormalized subscription end date (read database subscription to find values) - // This will also update this->datefin - $result=$this->update_end_date($user); - if ($result > 0) - { - // Change properties of object (used by triggers) - $this->last_subscription_date=dol_now(); - $this->last_subscription_amount=$montant; - $this->last_subscription_date_start=$date; - $this->last_subscription_date_end=$datefin; - - // Call trigger - $result=$this->call_trigger('MEMBER_SUBSCRIPTION',$user); - if ($result < 0) { $error++; } - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return $rowid; - } - else + while ($obj=$this->db->fetch_object($resql)) { - $this->db->rollback(); - return -2; - } - } - else - { - $this->error=$subscription->error; - $this->db->rollback(); - return -1; - } - } - - /** - * Function that validate a member - * - * @param User $user user adherent qui valide - * @return int <0 if KO, 0 if nothing done, >0 if OK - */ - function validate($user) - { - global $langs,$conf; + $response->nbtodo++; - $error=0; - $now=dol_now(); + $adherentstatic->datefin = $this->db->jdate($obj->datefin); + $adherentstatic->statut = $obj->statut; - // Check parameters - if ($this->statut == 1) - { - dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING); - return 0; - } - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " statut = 1"; - $sql.= ", datevalid = '".$this->db->idate($now)."'"; - $sql.= ", fk_user_valid=".$user->id; - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::validate", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $this->statut=1; - - // Call trigger - $result=$this->call_trigger('MEMBER_VALIDATE',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers - - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } - - - /** - * Fonction qui resilie un adherent - * - * @param User $user User making change - * @return int <0 if KO, >0 if OK - */ - function resiliate($user) - { - global $langs,$conf; + if ($adherentstatic->hasDelay()) { + $response->nbtodolate++; + } + } - $error=0; + return $response; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } - // Check paramaters - if ($this->statut == 0) - { - dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING); - return 0; - } - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " statut = 0"; - $sql.= ", fk_user_valid=".$user->id; - $sql.= " WHERE rowid = ".$this->id; - - $result = $this->db->query($sql); - if ($result) - { - $this->statut=0; - - // Call trigger - $result=$this->call_trigger('MEMBER_RESILIATE',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers - - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } - - - /** - * Function to add member into external tools mailing-list, spip, etc. - * - * @return int <0 if KO, >0 if OK - */ - function add_to_abo() - { - global $conf,$langs; - - include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php'; - $mailmanspip=new MailmanSpip($this->db); - - $err=0; - - // mailman - if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled)) - { - $result=$mailmanspip->add_to_mailman($this); - - if ($result < 0) - { - if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error; - $err+=1; - } - foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) - { - $langs->load("errors"); - $this->errors[]=$langs->trans("ErrorFailedToAddToMailmanList",$tmpemail,$tmplist); - } - foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) - { - $langs->load("mailmanspip"); - $this->mesgs[]=$langs->trans("SuccessToAddToMailmanList",$tmpemail,$tmplist); - } - } - - // spip - if (! empty($conf->global->ADHERENT_USE_SPIP) && ! empty($conf->mailmanspip->enabled)) - { - $result=$mailmanspip->add_to_spip($this); - if ($result < 0) - { - $this->errors[]=$mailmanspip->error; - $err+=1; - } - } - if ($err) - { - return -$err; - } - else - { - return 1; - } - } - - - /** - * Function to delete a member from external tools like mailing-list, spip, etc. - * - * @return int <0 if KO, >0 if OK - */ - function del_to_abo() - { - global $conf,$langs; - - include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php'; - $mailmanspip=new MailmanSpip($this->db); - - $err=0; - - // mailman - if (! empty($conf->global->ADHERENT_USE_MAILMAN)) - { - $result=$mailmanspip->del_to_mailman($this); - if ($result < 0) - { - if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error; - $err+=1; - } - - foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) - { - $langs->load("errors"); - $this->errors[]=$langs->trans("ErrorFailedToRemoveToMailmanList",$tmpemail,$tmplist); - } - foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) - { - $langs->load("mailmanspip"); - $this->mesgs[]=$langs->trans("SuccessToRemoveToMailmanList",$tmpemail,$tmplist); - } - } - - if ($conf->global->ADHERENT_USE_SPIP && ! empty($conf->mailmanspip->enabled)) - { - $result=$mailmanspip->del_to_spip($this); - if ($result < 0) - { - $this->errors[]=$mailmanspip->error; - $err+=1; - } - } - if ($err) - { - // error - return -$err; - } - else - { - return 1; - } - } - - - /** - * Return civility label of a member - * - * @return string Translated name of civility (translated with transnoentitiesnoconv) - */ - function getCivilityLabel() - { - global $langs; - $langs->load("dict"); - - $code=(empty($this->civility_id)?'':$this->civility_id); - if (empty($code)) return ''; - return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code); - } - - /** - * Return clicable name (with picto eventually) - * - * @param int $withpictoimg 0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) - * @param int $maxlen length max label - * @param string $option Page for link ('card', 'category', 'subscription', ...) - * @param string $mode ''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref - * @param string $morecss Add more css on link - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string Chaine avec URL - */ - function getNomUrl($withpictoimg=0, $maxlen=0, $option='card', $mode='', $morecss='', $save_lastsearch_value=-1) - { - global $conf, $langs; - - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; - - $result=''; $label=''; - $link=''; $linkstart=''; $linkend=''; - - if (! empty($this->photo)) - { - $label.= '<div class="photointooltip">'; - $label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); - $label.= '</div><div style="clear: both;"></div>'; - } - - $label.= '<div class="centpercent">'; - $label.= '<u>' . $langs->trans("Member") . '</u>'; - if (! empty($this->ref)) - $label.= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; - if (! empty($this->firstname) || ! empty($this->lastname)) - $label.= '<br><b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs); - $label.='</div>'; - - $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.$this->id; - if ($option == 'subscription') - { - $url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.$this->id; - } - - if ($option != 'nolink') - { - // Add param to save lastsearch_values or not - $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; - if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; - } - - $link = '<a href="'.$url.'"'; - $linkclose=""; - if (empty($notooltip)) - { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $langs->load("users"); - $label=$langs->trans("ShowUser"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; - } - - $link.=$linkclose.'>'; - $linkend='</a>'; - - //if ($withpictoimg == -1) $result.='<div class="nowrap">'; - $result.=$link; - if ($withpictoimg) - { - $paddafterimage=''; - if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"'; - // Only picto - if ($withpictoimg > 0) $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>'; - // Picto must be a photo - else $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>'; - $result.=$picto; - } - if ($withpictoimg > -2 && $withpictoimg != 2) - { - if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<div class="inline-block nopadding valignmiddle'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' usertext'.$morecss:'').'">'; - if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen); - elseif ($mode == 'ref') $result.=$this->id; - else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen); - if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</div>'; - } - $result.=$linkend; - //if ($withpictoimg == -1) $result.='</div>'; - - return $result; - } - - /** - * Retourne le libelle du statut d'un adherent (brouillon, valide, resilie) - * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label - */ - function getLibStatut($mode=0) - { - return $this->LibStatut($this->statut,$this->need_subscription,$this->datefin,$mode); - } - - /** - * Renvoi le libelle d'un statut donne - * - * @param int $statut Id statut - * @param int $need_subscription 1 if member type need subscription, 0 otherwise - * @param int $date_end_subscription Date fin adhesion - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label - */ - function LibStatut($statut,$need_subscription,$date_end_subscription,$mode=0) - { - global $langs; - $langs->load("members"); - if ($mode == 0) - { - if ($statut == -1) return $langs->trans("MemberStatusDraft"); - if ($statut >= 1) - { - if (! $date_end_subscription) return $langs->trans("MemberStatusActive"); - elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate"); - else return $langs->trans("MemberStatusPaid"); - } - if ($statut == 0) return $langs->trans("MemberStatusResiliated"); - } - if ($mode == 1) - { - if ($statut == -1) return $langs->trans("MemberStatusDraftShort"); - if ($statut >= 1) - { - if (! $date_end_subscription) return $langs->trans("MemberStatusActiveShort"); - elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLateShort"); - else return $langs->trans("MemberStatusPaidShort"); - } - if ($statut == 0) return $langs->trans("MemberStatusResiliatedShort"); - } - if ($mode == 2) - { - if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraftShort"); - if ($statut >= 1) - { - if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActiveShort"); - elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLateShort"); - else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaidShort"); - } - if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliatedShort"); - } - if ($mode == 3) - { - if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0'); - if ($statut >= 1) - { - if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1'); - elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3'); - else return img_picto($langs->trans('MemberStatusPaid'),'statut4'); - } - if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5'); - } - if ($mode == 4) - { - if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraft"); - if ($statut >= 1) - { - if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActive"); - elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLate"); - else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaid"); - } - if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliated"); - } - if ($mode == 5) - { - if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0'); - if ($statut >= 1) - { - if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveShort").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1'); - elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLateShort").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3'); - else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaidShort").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4'); - } - if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5'); - } - if ($mode == 6) - { - if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0'); - if ($statut >= 1) - { - if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActive").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1'); - elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLate").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3'); - else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaid").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4'); - } - if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5'); - } - } - - - /** - * Charge indicateurs this->nb de tableau de bord - * - * @return int <0 if KO, >0 if OK - */ - function load_state_board() - { - global $conf; - - $this->nb=array(); - - $sql = "SELECT count(a.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; - $sql.= " WHERE a.statut > 0"; - $sql.= " AND a.entity IN (".getEntity('adherent').")"; - - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nb["members"]=$obj->nb; - } - $this->db->free($resql); - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - - } - - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * - * @param User $user Objet user - * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK - */ - function load_board($user) - { - global $conf, $langs; - - if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe - - $now=dol_now(); - - $sql = "SELECT a.rowid, a.datefin, a.statut"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; - $sql.= " WHERE a.statut = 1"; - $sql.= " AND a.entity IN (".getEntity('adherent').")"; - $sql.= " AND (a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."')"; - - $resql=$this->db->query($sql); - if ($resql) - { - $langs->load("members"); - - $response = new WorkboardResponse(); - $response->warning_delay=$conf->adherent->subscription->warning_delay/60/60/24; - $response->label=$langs->trans("MembersWithSubscriptionToReceive"); - $response->url=DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&statut=1&filter=outofdate'; - $response->img=img_object('',"user"); - - $adherentstatic = new Adherent($this->db); - - while ($obj=$this->db->fetch_object($resql)) - { - $response->nbtodo++; - - $adherentstatic->datefin = $this->db->jdate($obj->datefin); - $adherentstatic->statut = $obj->statut; - - if ($adherentstatic->hasDelay()) { - $response->nbtodolate++; - } - } - - return $response; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } - - - /** - * Create a document onto disk according to template module. - * - * @param string $modele Force template to use ('' to not force) - * @param Translate $outputlangs objet lang a utiliser pour traduction - * @param int $hidedetails Hide details of lines - * @param int $hidedesc Hide description - * @param int $hideref Hide ref - * @return int 0 if KO, 1 if OK - */ - public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) - { - global $conf,$langs; - - $langs->load("orders"); + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) + { + global $conf,$langs; + + $langs->load("orders"); if (! dol_strlen($modele)) { - $modele = 'standard'; - - if ($this->modelpdf) { - $modele = $this->modelpdf; - } elseif (! empty($conf->global->ADHERENT_ADDON_PDF)) { - $modele = $conf->global->ADHERENT_ADDON_PDF; - } - } - - $modelpath = "core/modules/member/doc/"; - - return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - function initAsSpecimen() - { - global $user,$langs; - - // Initialise parametres - $this->id=0; - $this->specimen=1; - $this->civility_id = 0; - $this->lastname = 'DOLIBARR'; - $this->firstname = 'SPECIMEN'; - $this->login='dolibspec'; - $this->pass='dolibspec'; - $this->societe = 'Societe ABC'; - $this->address = '61 jump street'; - $this->zip = '75000'; - $this->town = 'Paris'; - $this->country_id = 1; - $this->country_code = 'FR'; - $this->country = 'France'; - $this->morphy = 1; - $this->email = 'specimen@specimen.com'; - $this->skype = 'tom.hanson'; - $this->phone = '0999999999'; - $this->phone_perso = '0999999998'; - $this->phone_mobile = '0999999997'; - $this->note_private='No comment'; - $this->birth=time(); - $this->photo=''; - $this->public=1; - $this->statut=0; - - $this->datefin=time(); - $this->datevalid=time(); - - $this->typeid=1; // Id type adherent - $this->type='Type adherent'; // Libelle type adherent - $this->need_subscription=0; - - $this->first_subscription_date=time(); - $this->first_subscription_amount=10; - $this->last_subscription_date=time(); - $this->last_subscription_amount=10; - } - - - /** - * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet - * - * @param array $info Info array loaded by _load_ldap_info - * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb) - * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb) - * 2=Return key only (uid=qqq) - * @return string DN - */ - function _load_ldap_dn($info,$mode=0) - { - global $conf; - $dn=''; - if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS].",".$conf->global->LDAP_MEMBER_DN; - if ($mode==1) $dn=$conf->global->LDAP_MEMBER_DN; - if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS]; - return $dn; - } - - - /** - * Initialise tableau info (tableau des attributs LDAP) - * - * @return array Tableau info des attributs - */ + $modele = 'standard'; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (! empty($conf->global->ADHERENT_ADDON_PDF)) { + $modele = $conf->global->ADHERENT_ADDON_PDF; + } + } + + $modelpath = "core/modules/member/doc/"; + + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $user,$langs; + + // Initialise parametres + $this->id=0; + $this->specimen=1; + $this->civility_id = 0; + $this->lastname = 'DOLIBARR'; + $this->firstname = 'SPECIMEN'; + $this->login='dolibspec'; + $this->pass='dolibspec'; + $this->societe = 'Societe ABC'; + $this->address = '61 jump street'; + $this->zip = '75000'; + $this->town = 'Paris'; + $this->country_id = 1; + $this->country_code = 'FR'; + $this->country = 'France'; + $this->morphy = 1; + $this->email = 'specimen@specimen.com'; + $this->skype = 'tom.hanson'; + $this->phone = '0999999999'; + $this->phone_perso = '0999999998'; + $this->phone_mobile = '0999999997'; + $this->note_private='No comment'; + $this->birth=time(); + $this->photo=''; + $this->public=1; + $this->statut=0; + + $this->datefin=time(); + $this->datevalid=time(); + + $this->typeid=1; // Id type adherent + $this->type='Type adherent'; // Libelle type adherent + $this->need_subscription=0; + + $this->first_subscription_date=time(); + $this->first_subscription_amount=10; + $this->last_subscription_date=time(); + $this->last_subscription_amount=10; + } + + + /** + * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet + * + * @param array $info Info array loaded by _load_ldap_info + * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb) + * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb) + * 2=Return key only (uid=qqq) + * @return string DN + */ + function _load_ldap_dn($info,$mode=0) + { + global $conf; + $dn=''; + if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS].",".$conf->global->LDAP_MEMBER_DN; + if ($mode==1) $dn=$conf->global->LDAP_MEMBER_DN; + if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS]; + return $dn; + } + + + /** + * Initialise tableau info (tableau des attributs LDAP) + * + * @return array Tableau info des attributs + */ function _load_ldap_info() { global $conf,$langs; @@ -2052,63 +2052,63 @@ class Adherent extends CommonObject } - /** - * Charge les informations d'ordre info dans l'objet adherent - * - * @param int $id Id of member to load - * @return void - */ - function info($id) - { - $sql = 'SELECT a.rowid, a.datec as datec,'; - $sql.= ' a.datevalid as datev,'; - $sql.= ' a.tms as datem,'; - $sql.= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'adherent as a'; - $sql.= ' WHERE a.rowid = '.$id; - - dol_syslog(get_class($this)."::info", LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - if ($this->db->num_rows($result)) - { - $obj = $this->db->fetch_object($result); - $this->id = $obj->rowid; - if ($obj->fk_user_author) - { - $cuser = new User($this->db); - $cuser->fetch($obj->fk_user_author); - $this->user_creation = $cuser; - } - - if ($obj->fk_user_valid) - { - $vuser = new User($this->db); - $vuser->fetch($obj->fk_user_valid); - $this->user_validation = $vuser; - } - - if ($obj->fk_user_mod) - { - $muser = new User($this->db); - $muser->fetch($obj->fk_user_mod); - $this->user_modification = $muser; - } - - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_validation = $this->db->jdate($obj->datev); - $this->date_modification = $this->db->jdate($obj->datem); - } - - $this->db->free($result); - - } - else - { - dol_print_error($this->db); - } - } + /** + * Charge les informations d'ordre info dans l'objet adherent + * + * @param int $id Id of member to load + * @return void + */ + function info($id) + { + $sql = 'SELECT a.rowid, a.datec as datec,'; + $sql.= ' a.datevalid as datev,'; + $sql.= ' a.tms as datem,'; + $sql.= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'adherent as a'; + $sql.= ' WHERE a.rowid = '.$id; + + dol_syslog(get_class($this)."::info", LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_mod) + { + $muser = new User($this->db); + $muser->fetch($obj->fk_user_mod); + $this->user_modification = $muser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_validation = $this->db->jdate($obj->datev); + $this->date_modification = $this->db->jdate($obj->datem); + } + + $this->db->free($result); + + } + else + { + dol_print_error($this->db); + } + } /** * Sets object to supplied categories. @@ -2177,17 +2177,17 @@ class Adherent extends CommonObject * * @return boolean True if late, False if not late */ - public function hasDelay() - { - global $conf; + public function hasDelay() + { + global $conf; - //Only valid members - if ($this->statut <= 0) return false; - if (! $this->datefin) return false; + //Only valid members + if ($this->statut <= 0) return false; + if (! $this->datefin) return false; - $now = dol_now(); + $now = dol_now(); - return $this->datefin < ($now - $conf->adherent->subscription->warning_delay); - } + return $this->datefin < ($now - $conf->adherent->subscription->warning_delay); + } } diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 70589a516fd92c24bbb501140929215a1cd3921c..9d140d5a370f89068edae3d558dd8e1237667e9e 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -57,19 +57,19 @@ if (! defined("MAIN_MOTD")) define("MAIN_MOTD",""); if (GETPOST('cancel','alpha')) { - $action=''; + $action=''; } if ($action == 'removebackgroundlogin' && ! empty($conf->global->MAIN_LOGIN_BACKGROUND)) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $logofile=$conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND; - dol_delete_file($logofile); - dolibarr_del_const($db, "MAIN_LOGIN_BACKGROUND",$conf->entity); - $mysoc->logo=''; + $logofile=$conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND; + dol_delete_file($logofile); + dolibarr_del_const($db, "MAIN_LOGIN_BACKGROUND",$conf->entity); + $mysoc->logo=''; - /*$logosmallfile=$conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small; + /*$logosmallfile=$conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small; dol_delete_file($logosmallfile); dolibarr_del_const($db, "MAIN_INFO_SOCIETE_LOGO_SMALL",$conf->entity); $mysoc->logo_small=''; @@ -89,7 +89,7 @@ if ($action == 'update') $val=GETPOST('THEME_TOPMENU_DISABLE_IMAGE'); if (! $val) dolibarr_del_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', $conf->entity); - else dolibarr_set_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', GETPOST('THEME_TOPMENU_DISABLE_IMAGE'),'chaine',0,'',$conf->entity); + else dolibarr_set_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', GETPOST('THEME_TOPMENU_DISABLE_IMAGE'),'chaine',0,'',$conf->entity); $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_BACKBODY'),array())))); if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_BACKBODY', $conf->entity); @@ -103,44 +103,44 @@ if ($action == 'update') if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_VERMENU_BACK1', $conf->entity); else dolibarr_set_const($db, 'THEME_ELDY_VERMENU_BACK1', $val,'chaine',0,'',$conf->entity); - $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_BACKTITLE1'),array())))); + $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_BACKTITLE1'),array())))); if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_BACKTITLE1', $conf->entity); - else dolibarr_set_const($db, 'THEME_ELDY_BACKTITLE1', $val,'chaine',0,'',$conf->entity); - - $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEIMPAIR1'),array())))); - if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEIMPAIR1', $conf->entity); - else dolibarr_set_const($db, 'THEME_ELDY_LINEIMPAIR1', $val,'chaine',0,'',$conf->entity); - $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEIMPAIR1'),array())))); - if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEIMPAIR2', $conf->entity); - else dolibarr_set_const($db, 'THEME_ELDY_LINEIMPAIR2', $val,'chaine',0,'',$conf->entity); - - $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEPAIR1'),array())))); - if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEPAIR1', $conf->entity); - else dolibarr_set_const($db, 'THEME_ELDY_LINEPAIR1', $val,'chaine',0,'',$conf->entity); - $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEPAIR1'),array())))); - if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEPAIR2', $conf->entity); - else dolibarr_set_const($db, 'THEME_ELDY_LINEPAIR2', $val,'chaine',0,'',$conf->entity); - - $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_TEXTTITLENOTAB'),array())))); + else dolibarr_set_const($db, 'THEME_ELDY_BACKTITLE1', $val,'chaine',0,'',$conf->entity); + + $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEIMPAIR1'),array())))); + if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEIMPAIR1', $conf->entity); + else dolibarr_set_const($db, 'THEME_ELDY_LINEIMPAIR1', $val,'chaine',0,'',$conf->entity); + $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEIMPAIR1'),array())))); + if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEIMPAIR2', $conf->entity); + else dolibarr_set_const($db, 'THEME_ELDY_LINEIMPAIR2', $val,'chaine',0,'',$conf->entity); + + $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEPAIR1'),array())))); + if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEPAIR1', $conf->entity); + else dolibarr_set_const($db, 'THEME_ELDY_LINEPAIR1', $val,'chaine',0,'',$conf->entity); + $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_LINEPAIR1'),array())))); + if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_LINEPAIR2', $conf->entity); + else dolibarr_set_const($db, 'THEME_ELDY_LINEPAIR2', $val,'chaine',0,'',$conf->entity); + + $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_TEXTTITLENOTAB'),array())))); if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_TEXTTITLENOTAB', $conf->entity); - else dolibarr_set_const($db, 'THEME_ELDY_TEXTTITLENOTAB', $val,'chaine',0,'',$conf->entity); + else dolibarr_set_const($db, 'THEME_ELDY_TEXTTITLENOTAB', $val,'chaine',0,'',$conf->entity); - if (GETPOST('THEME_ELDY_USE_HOVER') == '') dolibarr_set_const($db, "THEME_ELDY_USE_HOVER", '0', 'chaine', 0, '', $conf->entity); // If empty, we set to '0' ('000000' is for black) + if (GETPOST('THEME_ELDY_USE_HOVER') == '') dolibarr_set_const($db, "THEME_ELDY_USE_HOVER", '0', 'chaine', 0, '', $conf->entity); // If empty, we set to '0' ('000000' is for black) else dolibarr_set_const($db, "THEME_ELDY_USE_HOVER", $_POST["THEME_ELDY_USE_HOVER"], 'chaine', 0, '', $conf->entity); $val=(implode(',',(colorStringToArray(GETPOST('THEME_ELDY_TEXTLINK'),array())))); if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_TEXTLINK', $conf->entity); - else dolibarr_set_const($db, 'THEME_ELDY_TEXTLINK', $val,'chaine',0,'',$conf->entity); - - dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT", $_POST["main_size_liste_limit"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT", $_POST["main_size_shortliste_limit"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_DISABLE_JAVASCRIPT", $_POST["main_disable_javascript"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_BUTTON_HIDE_UNAUTHORIZED", $_POST["MAIN_BUTTON_HIDE_UNAUTHORIZED"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_START_WEEK", $_POST["MAIN_START_WEEK"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_DAYS", $_POST["MAIN_DEFAULT_WORKING_DAYS"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_HOURS", $_POST["MAIN_DEFAULT_WORKING_HOURS"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_SHOW_LOGO", $_POST["MAIN_SHOW_LOGO"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_FIRSTNAME_NAME_POSITION", $_POST["MAIN_FIRSTNAME_NAME_POSITION"],'chaine',0,'',$conf->entity); + else dolibarr_set_const($db, 'THEME_ELDY_TEXTLINK', $val,'chaine',0,'',$conf->entity); + + dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT", $_POST["main_size_liste_limit"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT", $_POST["main_size_shortliste_limit"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_DISABLE_JAVASCRIPT", $_POST["main_disable_javascript"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_BUTTON_HIDE_UNAUTHORIZED", $_POST["MAIN_BUTTON_HIDE_UNAUTHORIZED"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_START_WEEK", $_POST["MAIN_START_WEEK"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_DAYS", $_POST["MAIN_DEFAULT_WORKING_DAYS"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_HOURS", $_POST["MAIN_DEFAULT_WORKING_HOURS"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_SHOW_LOGO", $_POST["MAIN_SHOW_LOGO"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_FIRSTNAME_NAME_POSITION", $_POST["MAIN_FIRSTNAME_NAME_POSITION"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_HELPCENTER_DISABLELINK", $_POST["MAIN_HELPCENTER_DISABLELINK"],'chaine',0,'',0); // Param for all entities dolibarr_set_const($db, "MAIN_MOTD", dol_htmlcleanlastbr($_POST["main_motd"]),'chaine',0,'',$conf->entity); @@ -151,43 +151,43 @@ if ($action == 'update') $varforimage='imagebackground'; $dirforimage=$conf->mycompany->dir_output.'/logos/'; if ($_FILES[$varforimage]["tmp_name"]) { - if (preg_match('/([^\\/:]+)$/i',$_FILES[$varforimage]["name"],$reg)) - { - $original_file=$reg[1]; - - $isimage=image_format_supported($original_file); - if ($isimage >= 0) - { - dol_syslog("Move file ".$_FILES[$varforimage]["tmp_name"]." to ".$dirforimage.$original_file); - if (! is_dir($dirforimage)) - { - dol_mkdir($dirforimage); - } - $result=dol_move_uploaded_file($_FILES[$varforimage]["tmp_name"],$dirforimage.$original_file,1,0,$_FILES[$varforimage]['error']); - if ($result > 0) - { - dolibarr_set_const($db, "MAIN_LOGIN_BACKGROUND",$original_file,'chaine',0,'',$conf->entity); - } - else if (preg_match('/^ErrorFileIsInfectedWithAVirus/',$result)) - { - $error++; - $langs->load("errors"); - $tmparray=explode(':',$result); - setEventMessages($langs->trans('ErrorFileIsInfectedWithAVirus',$tmparray[1]), null, 'errors'); - } - else - { - $error++; - setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors'); - } - } - else - { - $error++; - $langs->load("errors"); - setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); - } - } + if (preg_match('/([^\\/:]+)$/i',$_FILES[$varforimage]["name"],$reg)) + { + $original_file=$reg[1]; + + $isimage=image_format_supported($original_file); + if ($isimage >= 0) + { + dol_syslog("Move file ".$_FILES[$varforimage]["tmp_name"]." to ".$dirforimage.$original_file); + if (! is_dir($dirforimage)) + { + dol_mkdir($dirforimage); + } + $result=dol_move_uploaded_file($_FILES[$varforimage]["tmp_name"],$dirforimage.$original_file,1,0,$_FILES[$varforimage]['error']); + if ($result > 0) + { + dolibarr_set_const($db, "MAIN_LOGIN_BACKGROUND",$original_file,'chaine',0,'',$conf->entity); + } + else if (preg_match('/^ErrorFileIsInfectedWithAVirus/',$result)) + { + $error++; + $langs->load("errors"); + $tmparray=explode(':',$result); + setEventMessages($langs->trans('ErrorFileIsInfectedWithAVirus',$tmparray[1]), null, 'errors'); + } + else + { + $error++; + setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors'); + } + } + else + { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); + } + } } @@ -218,59 +218,59 @@ print "<br>\n"; if ($action == 'edit') // Edit { - //WYSIWYG Editor - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + //WYSIWYG Editor + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - print '<form enctype="multipart/form-data" method="POST" action="'.$_SERVER["PHP_SELF"].'">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="update">'; + print '<form enctype="multipart/form-data" method="POST" action="'.$_SERVER["PHP_SELF"].'">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="update">'; - clearstatcache(); + clearstatcache(); - print '<br>'; - print '<table summary="edit" class="noborder" width="100%">'; - print '<tr class="liste_titre"><td>'.$langs->trans("Language").'</td><td></td>'; + print '<br>'; + print '<table summary="edit" class="noborder" width="100%">'; + print '<tr class="liste_titre"><td>'.$langs->trans("Language").'</td><td></td>'; print '<td width="20"> </td>'; print '</tr>'; - // Default language - print '<tr><td class="titlefield">'.$langs->trans("DefaultLanguage").'</td><td>'; - print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, 0, 0, 0, 0, 'minwidth300'); - print '</td>'; + // Default language + print '<tr><td class="titlefield">'.$langs->trans("DefaultLanguage").'</td><td>'; + print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, 0, 0, 0, 0, 'minwidth300'); + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; // Multilingual GUI - print '<tr><td class="titlefield">'.$langs->trans("EnableMultilangInterface").'</td><td>'; - print $form->selectyesno('MAIN_MULTILANGS',$conf->global->MAIN_MULTILANGS,1); - print '</td>'; + print '<tr><td class="titlefield">'.$langs->trans("EnableMultilangInterface").'</td><td>'; + print $form->selectyesno('MAIN_MULTILANGS',$conf->global->MAIN_MULTILANGS,1); + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; print '</table><br>'."\n"; - // Themes and themes options - show_theme(null,1); - print '<br>'; + // Themes and themes options + show_theme(null,1); + print '<br>'; - // Other - print '<table summary="edit" class="noborder" width="100%">'; - print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameters").'</td><td>'.$langs->trans("Value").'</td>'; + // Other + print '<table summary="edit" class="noborder" width="100%">'; + print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameters").'</td><td>'.$langs->trans("Value").'</td>'; print '<td width="20"> </td>'; print '</tr>'; // Max size of lists - print '<tr><td>'.$langs->trans("DefaultMaxSizeList").'</td><td><input class="flat" name="main_size_liste_limit" size="4" value="' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '"></td>'; + print '<tr><td>'.$langs->trans("DefaultMaxSizeList").'</td><td><input class="flat" name="main_size_liste_limit" size="4" value="' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '"></td>'; print '<td width="20"> </td>'; print '</tr>'; // Max size of short lists on customer card - print '<tr><td>'.$langs->trans("DefaultMaxSizeShortList").'</td><td><input class="flat" name="main_size_shortliste_limit" size="4" value="' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '"></td>'; + print '<tr><td>'.$langs->trans("DefaultMaxSizeShortList").'</td><td><input class="flat" name="main_size_shortliste_limit" size="4" value="' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '"></td>'; print '<td width="20"> </td>'; print '</tr>'; - // show input border - /* + // show input border + /* print '<tr><td>'.$langs->trans("showInputBorder").'</td><td>'; print $form->selectyesno('main_showInputBorder',isset($conf->global->THEME_ELDY_SHOW_BORDER_INPUT)?$conf->global->THEME_ELDY_SHOW_BORDER_INPUT:0,1); print '</td>'; @@ -279,38 +279,38 @@ if ($action == 'edit') // Edit */ // Disable javascript and ajax - print '<tr><td>'.$langs->trans("DisableJavascript").'</td><td>'; - print $form->selectyesno('main_disable_javascript',isset($conf->global->MAIN_DISABLE_JAVASCRIPT)?$conf->global->MAIN_DISABLE_JAVASCRIPT:0,1); - print '</td>'; + print '<tr><td>'.$langs->trans("DisableJavascript").'</td><td>'; + print $form->selectyesno('main_disable_javascript',isset($conf->global->MAIN_DISABLE_JAVASCRIPT)?$conf->global->MAIN_DISABLE_JAVASCRIPT:0,1); + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; - // First day for weeks - print '<tr><td class="titlefield">'.$langs->trans("WeekStartOnDay").'</td><td>'; - print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1'),'MAIN_START_WEEK',0); - print '</td>'; + // First day for weeks + print '<tr><td class="titlefield">'.$langs->trans("WeekStartOnDay").'</td><td>'; + print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1'),'MAIN_START_WEEK',0); + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; - // DefaultWorkingDays - print '<tr><td class="titlefield">'.$langs->trans("DefaultWorkingDays").'</td><td>'; - print '<input type="text" name="MAIN_DEFAULT_WORKING_DAYS" size="5" value="'.(isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5').'">'; - print '</td>'; + // DefaultWorkingDays + print '<tr><td class="titlefield">'.$langs->trans("DefaultWorkingDays").'</td><td>'; + print '<input type="text" name="MAIN_DEFAULT_WORKING_DAYS" size="5" value="'.(isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5').'">'; + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; - // DefaultWorkingHours - print '<tr><td class="titlefield">'.$langs->trans("DefaultWorkingHours").'</td><td>'; - print '<input type="text" name="MAIN_DEFAULT_WORKING_HOURS" size="5" value="'.(isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18').'">'; - print '</td>'; + // DefaultWorkingHours + print '<tr><td class="titlefield">'.$langs->trans("DefaultWorkingHours").'</td><td>'; + print '<input type="text" name="MAIN_DEFAULT_WORKING_HOURS" size="5" value="'.(isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18').'">'; + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; // Firstname/Name - print '<tr><td class="titlefield">'.$langs->trans("FirstnameNamePosition").'</td><td>'; + print '<tr><td class="titlefield">'.$langs->trans("FirstnameNamePosition").'</td><td>'; $array=array(0=>$langs->trans("Firstname").' '.$langs->trans("Lastname"),1=>$langs->trans("Lastname").' '.$langs->trans("Firstname")); - print $form->selectarray('MAIN_FIRSTNAME_NAME_POSITION',$array,(isset($conf->global->MAIN_FIRSTNAME_NAME_POSITION)?$conf->global->MAIN_FIRSTNAME_NAME_POSITION:0)); - print '</td>'; + print $form->selectarray('MAIN_FIRSTNAME_NAME_POSITION',$array,(isset($conf->global->MAIN_FIRSTNAME_NAME_POSITION)?$conf->global->MAIN_FIRSTNAME_NAME_POSITION:0)); + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; @@ -346,27 +346,27 @@ if ($action == 'edit') // Edit print '</tr>'; // Hide wiki link on login page - print '<tr><td class="titlefield">'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).'</td><td>'; - print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0,1); - print '</td>'; + print '<tr><td class="titlefield">'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).'</td><td>'; + print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0,1); + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; // Message of the day on home page - $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount')); - complete_substitutions_array($substitutionarray, $langs); + $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount')); + complete_substitutions_array($substitutionarray, $langs); - print '<tr><td class="titlefield">'; - $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'<br>'; - foreach($substitutionarray as $key => $val) - { - $texthelp.=$key.'<br>'; - } - print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessageofday'); + print '<tr><td class="titlefield">'; + $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'<br>'; + foreach($substitutionarray as $key => $val) + { + $texthelp.=$key.'<br>'; + } + print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessageofday'); - print '</td><td colspan="2">'; + print '</td><td colspan="2">'; - $doleditor = new DolEditor('main_motd', (isset($conf->global->MAIN_MOTD)?$conf->global->MAIN_MOTD:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); + $doleditor = new DolEditor('main_motd', (isset($conf->global->MAIN_MOTD)?$conf->global->MAIN_MOTD:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); print '</td></tr>'."\n"; @@ -383,12 +383,12 @@ if ($action == 'edit') // Edit // Message on login page $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount','user')); - complete_substitutions_array($substitutionarray, $langs); - print '<tr><td>'; + complete_substitutions_array($substitutionarray, $langs); + print '<tr><td>'; $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'<br>'; foreach($substitutionarray as $key => $val) { - $texthelp.=$key.'<br>'; + $texthelp.=$key.'<br>'; } print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessagelogin'); print '</td><td colspan="2">'; @@ -405,16 +405,16 @@ if ($action == 'edit') // Edit // Background print '<tr><td><label for="imagebackground">'.$langs->trans("BackgroundImageLogin").' (png,jpg)</label></td><td colspan="2">'; - print '<div class="centpercent inline-block">'; + print '<div class="centpercent inline-block">'; print '<input type="file" class="flat class=minwidth200" name="imagebackground" id="imagebackground">'; if (! empty($conf->global->MAIN_LOGIN_BACKGROUND)) { - print '<a href="'.$_SERVER["PHP_SELF"].'?action=removebackgroundlogin">'.img_delete($langs->trans("Delete")).'</a>'; - if (file_exists($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) { - print ' '; - print '<img class="paddingleft valignmiddle" width="100px" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&file='.urlencode('/'.$conf->global->MAIN_LOGIN_BACKGROUND).'">'; - } + print '<a href="'.$_SERVER["PHP_SELF"].'?action=removebackgroundlogin">'.img_delete($langs->trans("Delete")).'</a>'; + if (file_exists($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) { + print ' '; + print '<img class="paddingleft valignmiddle" width="100px" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&file='.urlencode('/'.$conf->global->MAIN_LOGIN_BACKGROUND).'">'; + } } else { - print '<img class="paddingleft valignmiddle" width="100" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">'; + print '<img class="paddingleft valignmiddle" width="100" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">'; } print '</div>'; print '</td></tr>'; @@ -422,31 +422,31 @@ if ($action == 'edit') // Edit print '</table>'."\n"; - print '<br><div class="center">'; - print '<input class="button" type="submit" name="submit" value="'.$langs->trans("Save").'">'; - print ' '; - print '<input class="button" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">'; - print '</div>'; + print '<br><div class="center">'; + print '<input class="button" type="submit" name="submit" value="'.$langs->trans("Save").'">'; + print ' '; + print '<input class="button" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">'; + print '</div>'; - print '</form>'; + print '</form>'; } else // Show { - // Language - print '<table class="noborder" width="100%">'; - print '<tr class="liste_titre"><td>'.$langs->trans("Language").'</td><td></td><td> </td></tr>'; - - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DefaultLanguage").'</td><td>'; - $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); - print ($s?$s.' ':''); - print ($conf->global->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); - print '</td>'; + // Language + print '<table class="noborder" width="100%">'; + print '<tr class="liste_titre"><td>'.$langs->trans("Language").'</td><td></td><td> </td></tr>'; + + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DefaultLanguage").'</td><td>'; + $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); + print ($s?$s.' ':''); + print ($conf->global->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); + print '</td>'; print '<td width="20">'; - if ($user->admin && $conf->global->MAIN_LANG_DEFAULT!='auto') print info_admin($langs->trans("SubmitTranslation".($conf->global->MAIN_LANG_DEFAULT=='en_US'?'ENUS':''),$conf->global->MAIN_LANG_DEFAULT),1); + if ($user->admin && $conf->global->MAIN_LANG_DEFAULT!='auto') print info_admin($langs->trans("SubmitTranslation".($conf->global->MAIN_LANG_DEFAULT=='en_US'?'ENUS':''),$conf->global->MAIN_LANG_DEFAULT),1); print '</td>'; print "</tr>"; - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("EnableMultilangInterface").'</td><td>' . yn($conf->global->MAIN_MULTILANGS) . '</td>'; + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("EnableMultilangInterface").'</td><td>' . yn($conf->global->MAIN_MULTILANGS) . '</td>'; print '<td width="20"> </td>'; print "</tr>"; @@ -454,19 +454,19 @@ else // Show // Themes - show_theme(null,0); - print '<br>'; + show_theme(null,0); + print '<br>'; - // Other - print '<table class="noborder" width="100%">'; - print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameters").'</td><td colspan="2">'.$langs->trans("Value").'</td></tr>'; + // Other + print '<table class="noborder" width="100%">'; + print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameters").'</td><td colspan="2">'.$langs->trans("Value").'</td></tr>'; - print '<tr class="oddeven"><td>'.$langs->trans("DefaultMaxSizeList").'</td><td>' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '</td>'; + print '<tr class="oddeven"><td>'.$langs->trans("DefaultMaxSizeList").'</td><td>' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '</td>'; print '<td width="20"> </td>'; print "</tr>"; - print '<tr class="oddeven"><td>'.$langs->trans("DefaultMaxSizeShortList").'</td><td>' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '</td>'; + print '<tr class="oddeven"><td>'.$langs->trans("DefaultMaxSizeShortList").'</td><td>' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '</td>'; print '<td width="20"> </td>'; print "</tr>"; @@ -477,38 +477,38 @@ else // Show print "</tr>"; */ - // Disable javascript/ajax - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DisableJavascript").'</td><td>'; - print yn($conf->global->MAIN_DISABLE_JAVASCRIPT)."</td>"; - print '<td width="20"> </td>'; - print "</tr>"; + // Disable javascript/ajax + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DisableJavascript").'</td><td>'; + print yn($conf->global->MAIN_DISABLE_JAVASCRIPT)."</td>"; + print '<td width="20"> </td>'; + print "</tr>"; // First day for weeks - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("WeekStartOnDay").'</td><td>'; - print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); - print '</td>'; + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("WeekStartOnDay").'</td><td>'; + print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; - // DefaultWorkingDays - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DefaultWorkingDays").'</td><td>'; - print isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5'; - print '</td>'; + // DefaultWorkingDays + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DefaultWorkingDays").'</td><td>'; + print isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5'; + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; - // DefaultWorkingHours - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DefaultWorkingHours").'</td><td>'; - print isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18'; - print '</td>'; + // DefaultWorkingHours + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DefaultWorkingHours").'</td><td>'; + print isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18'; + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; // Firstname / Name position - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("FirstnameNamePosition").'</td><td>'; - if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print $langs->trans("Firstname").' '.$langs->trans("Lastname"); } - else { print $langs->trans("Lastname").' '.$langs->trans("Firstname"); } - print '</td>'; + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("FirstnameNamePosition").'</td><td>'; + if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print $langs->trans("Firstname").' '.$langs->trans("Lastname"); } + else { print $langs->trans("Lastname").' '.$langs->trans("Firstname"); } + print '</td>'; print '<td width="20"> </td>'; print '</tr>'; @@ -517,8 +517,8 @@ else // Show print yn((isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0),1); print '</td></tr>'; - // Show logo - print '<tr class="oddeven"><td>'.$langs->trans("EnableShowLogo").'</td><td>' . yn($conf->global->MAIN_SHOW_LOGO) . '</td>'; + // Show logo + print '<tr class="oddeven"><td>'.$langs->trans("EnableShowLogo").'</td><td>' . yn($conf->global->MAIN_SHOW_LOGO) . '</td>'; print '<td width="20"> </td>'; print "</tr>"; @@ -531,62 +531,62 @@ else // Show print '</tr>'; */ - // Show bugtrack link + // Show bugtrack link print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).'</td><td>'; print yn($conf->global->MAIN_BUGTRACK_ENABLELINK)."</td>"; print '<td width="20"> </td>'; print "</tr>"; - // Link to wiki help - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).'</td><td colspan="2">'; - print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); - print '</td></tr>'; + // Link to wiki help + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).'</td><td colspan="2">'; + print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); + print '</td></tr>'; - // Message of the day - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("MessageOfDay").'</td><td colspan="2">'; - if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); - else print ' '; - print '</td></tr>'."\n"; + // Message of the day + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("MessageOfDay").'</td><td colspan="2">'; + if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); + else print ' '; + print '</td></tr>'."\n"; - print '</table>'."\n"; + print '</table>'."\n"; - print '<br>'; + print '<br>'; - // Login page - print '<table class="noborder" width="100%">'; - print '<tr class="liste_titre"><td>'.$langs->trans("LoginPage").'</td><td></td><td> </td></tr>'; + // Login page + print '<table class="noborder" width="100%">'; + print '<tr class="liste_titre"><td>'.$langs->trans("LoginPage").'</td><td></td><td> </td></tr>'; - // Message login - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("MessageLogin").'</td><td colspan="2">'; - if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); - else print ' '; - print '</td></tr>'."\n"; + // Message login + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("MessageLogin").'</td><td colspan="2">'; + if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); + else print ' '; + print '</td></tr>'."\n"; // Link to help center - print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DisableLinkToHelpCenter").'</td><td colspan="2">'; - print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); - print '</td></tr>'; - - // Background login - print '<tr class="oddeven"><td>'.$langs->trans("BackgroundImageLogin").'</td><td colspan="2">'; - print '<div class="centpercent inline-block">'; - print $conf->global->MAIN_LOGIN_BACKGROUND; - if ($conf->global->MAIN_LOGIN_BACKGROUND && is_file($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) - { - print '<img class="img_logo paddingleft valignmiddle" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&file='.urlencode($conf->global->MAIN_LOGIN_BACKGROUND).'">'; - } - else - { - print '<img class="img_logo paddingleft valignmiddle" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">'; - } - print '</div>'; - print '</td></tr>'; - - print '</table>'."\n"; - - print '<div class="tabsAction tabsActionNoBottom">'; - print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>'; - print '</div>'; + print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DisableLinkToHelpCenter").'</td><td colspan="2">'; + print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); + print '</td></tr>'; + + // Background login + print '<tr class="oddeven"><td>'.$langs->trans("BackgroundImageLogin").'</td><td colspan="2">'; + print '<div class="centpercent inline-block">'; + print $conf->global->MAIN_LOGIN_BACKGROUND; + if ($conf->global->MAIN_LOGIN_BACKGROUND && is_file($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) + { + print '<img class="img_logo paddingleft valignmiddle" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&file='.urlencode($conf->global->MAIN_LOGIN_BACKGROUND).'">'; + } + else + { + print '<img class="img_logo paddingleft valignmiddle" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">'; + } + print '</div>'; + print '</td></tr>'; + + print '</table>'."\n"; + + print '<div class="tabsAction tabsActionNoBottom">'; + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>'; + print '</div>'; } diff --git a/htdocs/admin/ldap_members.php b/htdocs/admin/ldap_members.php index da04c852b2fdc800d43be5ca738698f5c9a5a114..0dccb9967fea6f7ab1e03199b53ea25f1ace4420 100644 --- a/htdocs/admin/ldap_members.php +++ b/htdocs/admin/ldap_members.php @@ -66,7 +66,7 @@ if ($action == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_PHONE',GETPOST("fieldphone"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_PHONE_PERSO',GETPOST("fieldphoneperso"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_MOBILE',GETPOST("fieldmobile"),'chaine',0,'',$conf->entity)) $error++; - if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_SKYPE',GETPOST("fieldskype"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_SKYPE',GETPOST("fieldskype"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_FAX',GETPOST("fieldfax"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_COMPANY',GETPOST("fieldcompany"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_FIELD_ADDRESS',GETPOST("fieldaddress"),'chaine',0,'',$conf->entity)) $error++; @@ -85,22 +85,22 @@ if ($action == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE', GETPOST("fieldlastsubscriptiondate"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT', GETPOST("fieldlastsubscriptionamount"),'chaine',0,'',$conf->entity)) $error++; - // This one must be after the others - $valkey=''; - $key=GETPOST("key"); - if ($key) $valkey=$conf->global->$key; - if (! dolibarr_set_const($db, 'LDAP_KEY_MEMBERS',$valkey,'chaine',0,'',$conf->entity)) $error++; - - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - dol_print_error($db); - } + // This one must be after the others + $valkey=''; + $key=GETPOST("key"); + if ($key) $valkey=$conf->global->$key; + if (! dolibarr_set_const($db, 'LDAP_KEY_MEMBERS',$valkey,'chaine',0,'',$conf->entity)) $error++; + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + dol_print_error($db); + } } diff --git a/htdocs/admin/ldap_users.php b/htdocs/admin/ldap_users.php index 30ec8d8153c2532c59357491e3ba3e248214b4e8..8be032677839429960f1063775744db374411191 100644 --- a/htdocs/admin/ldap_users.php +++ b/htdocs/admin/ldap_users.php @@ -63,7 +63,7 @@ if ($action == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_FIELD_MAIL',GETPOST("fieldmail"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_PHONE',GETPOST("fieldphone"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_MOBILE',GETPOST("fieldmobile"),'chaine',0,'',$conf->entity)) $error++; - if (! dolibarr_set_const($db, 'LDAP_FIELD_SKYPE',GETPOST("fieldskype"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_SKYPE',GETPOST("fieldskype"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_FAX',GETPOST("fieldfax"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_COMPANY',GETPOST("fieldcompany"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_ADDRESS',GETPOST("fieldaddress"),'chaine',0,'',$conf->entity)) $error++; @@ -74,22 +74,22 @@ if ($action == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_FIELD_SID',GETPOST("fieldsid"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_TITLE',GETPOST("fieldtitle"),'chaine',0,'',$conf->entity)) $error++; - // This one must be after the others - $valkey=''; - $key=GETPOST("key"); - if ($key) $valkey=$conf->global->$key; - if (! dolibarr_set_const($db, 'LDAP_KEY_USERS',$valkey,'chaine',0,'',$conf->entity)) $error++; - - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - dol_print_error($db); - } + // This one must be after the others + $valkey=''; + $key=GETPOST("key"); + if ($key) $valkey=$conf->global->$key; + if (! dolibarr_set_const($db, 'LDAP_KEY_USERS',$valkey,'chaine',0,'',$conf->entity)) $error++; + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + dol_print_error($db); + } } @@ -430,7 +430,7 @@ if (function_exists("ldap_connect")) { $required_fields = array( $conf->global->LDAP_KEY_USERS, - $conf->global->LDAP_FIELD_FULLNAME, + $conf->global->LDAP_FIELD_FULLNAME, $conf->global->LDAP_FIELD_NAME, $conf->global->LDAP_FIELD_FIRSTNAME, $conf->global->LDAP_FIELD_LOGIN, @@ -439,7 +439,7 @@ if (function_exists("ldap_connect")) $conf->global->LDAP_FIELD_PASSWORD_CRYPTED, $conf->global->LDAP_FIELD_PHONE, $conf->global->LDAP_FIELD_FAX, - $conf->global->LDAP_FIELD_SKYPE, + $conf->global->LDAP_FIELD_SKYPE, $conf->global->LDAP_FIELD_MOBILE, $conf->global->LDAP_FIELD_MAIL, $conf->global->LDAP_FIELD_TITLE, @@ -447,35 +447,35 @@ if (function_exists("ldap_connect")) $conf->global->LDAP_FIELD_SID ); - // Remove from required_fields all entries not configured in LDAP (empty) and duplicated - $required_fields=array_unique(array_values(array_filter($required_fields, "dol_validElement"))); - - // Get from LDAP database an array of results - $ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields, 1); - //$ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, '', 1); - - if (is_array($ldapusers)) - { - $liste=array(); - foreach ($ldapusers as $key => $ldapuser) - { - // Define the label string for this user - $label=''; - foreach ($required_fields as $value) - { - if ($value) - { - $label.=$value."=".$ldapuser[$value]." "; - } - } - $liste[$key] = $label; - } - - } - else - { - setEventMessages($ldap->error, $ldap->errors, 'errors'); - } + // Remove from required_fields all entries not configured in LDAP (empty) and duplicated + $required_fields=array_unique(array_values(array_filter($required_fields, "dol_validElement"))); + + // Get from LDAP database an array of results + $ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields, 1); + //$ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, '', 1); + + if (is_array($ldapusers)) + { + $liste=array(); + foreach ($ldapusers as $key => $ldapuser) + { + // Define the label string for this user + $label=''; + foreach ($required_fields as $value) + { + if ($value) + { + $label.=$value."=".$ldapuser[$value]." "; + } + } + $liste[$key] = $label; + } + + } + else + { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } print "<br>\n"; print "LDAP search for user:<br>\n"; diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 8c170cc78adef0e1ac8a713f39faeb8dacfd216e..9ac5b64347636fd510b187abedea3c416ae66b2f 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -87,94 +87,94 @@ class Documents extends DolibarrApi if (preg_match('/\.\./',$original_file) || preg_match('/[<>|]/',$original_file)) { - throw new RestException(401); + throw new RestException(401); + } + if (!$accessallowed) { + throw new RestException(401); + } + + // --- Generates the document + if ($regeneratedoc) + { + $hidedetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 0 : 1; + $hidedesc = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 0 : 1; + $hideref = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 0 : 1; + + if ($module_part == 'facture' || $module_part == 'invoice') + { + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $this->invoice = new Facture($this->db); + $result = $this->invoice->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file))); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + $result = $this->invoice->generateDocument($this->invoice->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if( $result <= 0 ) { + throw new RestException(500, 'Error generating document'); + } + } } - if (!$accessallowed) { - throw new RestException(401); - } - - // --- Generates the document - if ($regeneratedoc) - { - $hidedetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 0 : 1; - $hidedesc = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 0 : 1; - $hideref = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 0 : 1; - - if ($module_part == 'facture' || $module_part == 'invoice') - { - require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - $this->invoice = new Facture($this->db); - $result = $this->invoice->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file))); - if( ! $result ) { - throw new RestException(404, 'Invoice not found'); - } - $result = $this->invoice->generateDocument($this->invoice->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if( $result <= 0 ) { - throw new RestException(500, 'Error generating document'); - } - } - } $filename = basename($original_file); $original_file_osencoded=dol_osencode($original_file); // New file name encoded in OS encoding charset if (! file_exists($original_file_osencoded)) { - throw new RestException(404, 'File not found'); + throw new RestException(404, 'File not found'); } $file_content=file_get_contents($original_file_osencoded); - return array('filename'=>$filename, 'content'=>base64_encode($file_content), 'encoding'=>'MIME base64 (base64_encode php function, http://php.net/manual/en/function.base64-encode.php)' ); - } - - - /** - * Return a document. - * - * @param int $id ID of document - * @return array Array with data of file - * - * @throws RestException - */ - /* + return array('filename'=>$filename, 'content'=>base64_encode($file_content), 'encoding'=>'MIME base64 (base64_encode php function, http://php.net/manual/en/function.base64-encode.php)' ); + } + + + /** + * Return a document. + * + * @param int $id ID of document + * @return array Array with data of file + * + * @throws RestException + */ + /* public function get($id) { return array('note'=>'xxx'); }*/ - /** - * Push a file. - * Test sample 1: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. - * Test sample 2: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. - * - * @param string $filename Name of file to create ('FA1705-0123') - * @param string $modulepart Name of module or area concerned by file upload ('facture', ...) - * @param string $ref Reference of object (This will define subdir automatically and store submited file into it) - * @param string $subdir Subdirectory (Only if ref not provided) - * @param string $filecontent File content (string with file content. An empty file will be created if this parameter is not provided) - * @param string $fileencoding File encoding (''=no encoding, 'base64'=Base 64) - * @param int $overwriteifexists Overwrite file if exists (1 by default) - * @return bool State of copy - * @throws RestException - */ - public function post($filename, $modulepart, $ref='', $subdir='', $filecontent='', $fileencoding='', $overwriteifexists=0) - { - global $db, $conf; - - /*var_dump($modulepart); + /** + * Push a file. + * Test sample 1: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. + * Test sample 2: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. + * + * @param string $filename Name of file to create ('FA1705-0123') + * @param string $modulepart Name of module or area concerned by file upload ('facture', ...) + * @param string $ref Reference of object (This will define subdir automatically and store submited file into it) + * @param string $subdir Subdirectory (Only if ref not provided) + * @param string $filecontent File content (string with file content. An empty file will be created if this parameter is not provided) + * @param string $fileencoding File encoding (''=no encoding, 'base64'=Base 64) + * @param int $overwriteifexists Overwrite file if exists (1 by default) + * @return bool State of copy + * @throws RestException + */ + public function post($filename, $modulepart, $ref='', $subdir='', $filecontent='', $fileencoding='', $overwriteifexists=0) + { + global $db, $conf; + + /*var_dump($modulepart); var_dump($filename); var_dump($filecontent); exit;*/ - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - if (!DolibarrApiAccess::$user->rights->ecm->upload) { - throw new RestException(401); - } + if (!DolibarrApiAccess::$user->rights->ecm->upload) { + throw new RestException(401); + } - $newfilecontent = ''; - if (empty($fileencoding)) $newfilecontent = $filecontent; - if ($fileencoding == 'base64') $newfilecontent = base64_decode($filecontent); + $newfilecontent = ''; + if (empty($fileencoding)) $newfilecontent = $filecontent; + if ($fileencoding == 'base64') $newfilecontent = base64_decode($filecontent); $original_file = dol_sanitizeFileName($filename); diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index d127b0b0e09eeeae2146f5251cd4d888f6de2c18..bc5beef8be72978a3644d954b2c7ae31c020aaf6 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -231,8 +231,8 @@ if (empty($reshook)) // Validation else if ($action == 'confirm_validate' && $confirm == 'yes' && - ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate))) + ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate))) ) { $result = $object->valid($user); @@ -294,15 +294,15 @@ if (empty($reshook)) $result = $object->set_ref_client($user, GETPOST('ref_client')); if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } // Set incoterm elseif ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) - { - $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); - } + { + $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + } // Create proposal else if ($action == 'add' && $user->rights->propal->creer) @@ -346,11 +346,11 @@ if (empty($reshook)) $object->availability_id = GETPOST('availability_id'); $object->demand_reason_id = GETPOST('demand_reason_id'); $object->fk_delivery_address = GETPOST('fk_address'); - $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); + $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); $object->duree_validite = $duration; $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->fk_account = GETPOST('fk_account', 'int'); + $object->fk_account = GETPOST('fk_account', 'int'); $object->remise_percent = GETPOST('remise_percent'); $object->remise_absolue = GETPOST('remise_absolue'); $object->socid = GETPOST('socid'); @@ -377,11 +377,11 @@ if (empty($reshook)) $object->availability_id = GETPOST('availability_id'); $object->demand_reason_id = GETPOST('demand_reason_id'); $object->fk_delivery_address = GETPOST('fk_address'); - $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); + $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); $object->duree_validite = GETPOST('duree_validite'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->fk_account = GETPOST('fk_account', 'int'); + $object->fk_account = GETPOST('fk_account', 'int'); $object->contactid = GETPOST('contactid'); $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); @@ -527,7 +527,7 @@ if (empty($reshook)) // Hooks $parameters = array('objFrom' => $srcobject); $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook + // modified by hook if ($reshook < 0) $error ++; } else { @@ -561,23 +561,23 @@ if (empty($reshook)) { $db->commit(); - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - - $ret = $object->fetch($id); // Reload to get new records - $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result < 0) dol_print_error($db,$result); - } + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + + $ret = $object->fetch($id); // Reload to get new records + $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); + } header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); exit(); @@ -647,7 +647,7 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to send emails - $actiontypecode='AC_OTH_AUTO'; + $actiontypecode='AC_OTH_AUTO'; $trigger_name='PROPAL_SENTBYMAIL'; $autocopy='MAIN_MAIL_AUTOCOPY_PROPOSAL_TO'; $trackid='pro'.$object->id; @@ -756,7 +756,7 @@ if (empty($reshook)) $db->begin(); - // $tva_tx can be 'x.x (XXX)' + // $tva_tx can be 'x.x (XXX)' // Ecrase $pu par celui du produit // Ecrase $desc par celui du produit @@ -781,7 +781,7 @@ if (empty($reshook)) // On defini prix unitaire if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level) { - $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; + $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; @@ -801,7 +801,7 @@ if (empty($reshook)) $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); if ($result) { - // If there is some prices specific to the customer + // If there is some prices specific to the customer if (count($prodcustprice->lines) > 0) { $pu_ht = price($prodcustprice->lines[0]->price); $pu_ttc = price($prodcustprice->lines[0]->price_ttc); @@ -949,18 +949,18 @@ if (empty($reshook)) unset($_POST['idprod']); unset($_POST['units']); - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); } else { $db->rollback(); @@ -1159,12 +1159,12 @@ if (empty($reshook)) // bank account else if ($action == 'setbankaccount' && $user->rights->propal->creer) { - $result=$object->setBankAccount(GETPOST('fk_account', 'int')); + $result=$object->setBankAccount(GETPOST('fk_account', 'int')); } // shipping method else if ($action == 'setshippingmethod' && $user->rights->propal->creer) { - $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int')); + $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int')); } else if ($action == 'update_extras') { @@ -1225,10 +1225,10 @@ if (empty($reshook)) } } - // Actions to build doc - $upload_dir = $conf->propal->dir_output; - $permissioncreate=$user->rights->propal->creer; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + // Actions to build doc + $upload_dir = $conf->propal->dir_output; + $permissioncreate=$user->rights->propal->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -1252,7 +1252,7 @@ $now = dol_now(); // Add new proposal if ($action == 'create') { - $currency_code = $conf->currency; + $currency_code = $conf->currency; print load_fiche_titre($langs->trans("NewProp")); @@ -1317,14 +1317,14 @@ if ($action == 'create') if (!empty($conf->multicurrency->enabled)) { - if (!empty($objectsrc->multicurrency_code)) $currency_code = $objectsrc->multicurrency_code; - if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx)) $currency_tx = $objectsrc->multicurrency_tx; + if (!empty($objectsrc->multicurrency_code)) $currency_code = $objectsrc->multicurrency_code; + if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx)) $currency_tx = $objectsrc->multicurrency_tx; } } } else { - if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; + if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; } $object = new Propal($db); @@ -1359,9 +1359,9 @@ if ($action == 'create') print $soc->getNomUrl(1); print '<input type="hidden" name="socid" value="' . $soc->id . '">'; print '</td>'; - if (! empty($conf->global->SOCIETE_ASK_FOR_SHIPPING_METHOD) && ! empty($soc->shipping_method_id)) { - $shipping_method_id = $soc->shipping_method_id; - } + if (! empty($conf->global->SOCIETE_ASK_FOR_SHIPPING_METHOD) && ! empty($soc->shipping_method_id)) { + $shipping_method_id = $soc->shipping_method_id; + } } else { print '<td>'; print $form->select_company('', 'socid', '(s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300'); @@ -1427,12 +1427,12 @@ if ($action == 'create') $form->select_types_paiements($soc->mode_reglement_id, 'mode_reglement_id'); print '</td></tr>'; - // Bank Account - if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && ! empty($conf->banque->enabled)) { - print '<tr><td>' . $langs->trans('BankAccount') . '</td><td>'; - $form->select_comptes($fk_account, 'fk_account', 0, '', 1); - print '</td></tr>'; - } + // Bank Account + if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && ! empty($conf->banque->enabled)) { + print '<tr><td>' . $langs->trans('BankAccount') . '</td><td>'; + $form->select_comptes($fk_account, 'fk_account', 0, '', 1); + print '</td></tr>'; + } // What trigger creation print '<tr><td>' . $langs->trans('Source') . '</td><td>'; @@ -1444,12 +1444,12 @@ if ($action == 'create') $form->selectAvailabilityDelay('', 'availability_id', '', 1); print '</td></tr>'; - // Shipping Method - if (! empty($conf->expedition->enabled)) { - print '<tr><td>' . $langs->trans('SendingMethod') . '</td><td>'; - print $form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1); - print '</td></tr>'; - } + // Shipping Method + if (! empty($conf->expedition->enabled)) { + print '<tr><td>' . $langs->trans('SendingMethod') . '</td><td>'; + print $form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1); + print '</td></tr>'; + } // Delivery date (or manufacturing) print '<tr><td>' . $langs->trans("DeliveryDate") . '</td>'; @@ -1485,8 +1485,8 @@ if ($action == 'create') { print '<tr>'; print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $soc->libelle_incoterms, 1).'</label></td>'; - print '<td class="maxwidthonsmartphone">'; - print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms)?$soc->location_incoterms:'')); + print '<td class="maxwidthonsmartphone">'; + print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms)?$soc->location_incoterms:'')); print '</td></tr>'; } @@ -1503,8 +1503,8 @@ if ($action == 'create') { print '<tr>'; print '<td>'.fieldLabel('Currency','multicurrency_code').'</td>'; - print '<td class="maxwidthonsmartphone">'; - print $form->selectMultiCurrency($currency_code, 'multicurrency_code', 0); + print '<td class="maxwidthonsmartphone">'; + print $form->selectMultiCurrency($currency_code, 'multicurrency_code', 0); print '</td></tr>'; } @@ -1522,7 +1522,7 @@ if ($action == 'create') print '<tr>'; print '<td class="tdtop">' . $langs->trans('NotePrivate') . '</td>'; print '<td valign="top">'; - $note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc))?$objectsrc->note_private:null)); + $note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc))?$objectsrc->note_private:null)); $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); // print '<textarea name="note_private" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'.</textarea> @@ -1587,7 +1587,7 @@ if ($action == 'create') if (! empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) { - print '<br><table>'; + print '<br><table>'; // For backward compatibility print '<tr>'; @@ -1690,13 +1690,13 @@ if ($action == 'create') //array('type' => 'other','name' => 'note_private', 'label' => $langs->trans("Note"),'value' => '<textarea cols="30" rows="' . ROWS_3 . '" wrap="soft" name="note_private" id="note_private">'.$object->note_private.'</textarea>')); array('type' => 'text', 'name' => 'note_private', 'label' => $langs->trans("Note"),'value' => $object->note_private)); - if (! empty($conf->notification->enabled)) { - require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php'; - $notify = new Notify($db); - $formquestion = array_merge($formquestion, array( - array('type' => 'onecolumn', 'value' => $notify->confirmMessage('PROPAL_CLOSE_SIGNED', $object->socid, $object)), - )); - } + if (! empty($conf->notification->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php'; + $notify = new Notify($db); + $formquestion = array_merge($formquestion, array( + array('type' => 'onecolumn', 'value' => $notify->confirmMessage('PROPAL_CLOSE_SIGNED', $object->socid, $object)), + )); + } $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('SetAcceptedRefused'), $text, 'setstatut', $formquestion, '', 1, 250); @@ -1765,50 +1765,50 @@ if ($action == 'create') // Ref customer $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->propal->creer, 'string', '', 0, 1); $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->propal->creer, 'string', '', null, null, '', 1); - // Thirdparty - $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); + // Thirdparty + $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) $morehtmlref.=' (<a href="'.DOL_URL_ROOT.'/comm/propal/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherProposals").'</a>)'; - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref.='<br>'.$langs->trans('Project') . ' '; - if ($user->rights->propal->creer) - { - if ($action != 'classify') - $morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">'; - $morehtmlref.='<input type="hidden" name="action" value="classin">'; - $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - $morehtmlref.='</form>'; - } 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.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">'; - $morehtmlref.=$proj->ref; - $morehtmlref.='</a>'; - } else { - $morehtmlref.=''; - } - } - } - $morehtmlref.='</div>'; + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='<br>'.$langs->trans('Project') . ' '; + if ($user->rights->propal->creer) + { + if ($action != 'classify') + $morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">'; + $morehtmlref.='<input type="hidden" name="action" value="classin">'; + $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + $morehtmlref.='</form>'; + } 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.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">'; + $morehtmlref.=$proj->ref; + $morehtmlref.='</a>'; + } else { + $morehtmlref.=''; + } + } + } + $morehtmlref.='</div>'; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - print '<div class="fichecenter">'; - print '<div class="fichehalfleft">'; - print '<div class="underbanner clearboth"></div>'; + print '<div class="fichecenter">'; + print '<div class="fichehalfleft">'; + print '<div class="underbanner clearboth"></div>'; print '<table class="border" width="100%">'; @@ -1941,24 +1941,24 @@ if ($action == 'create') print '</td>'; print '</tr>'; - // Shipping Method - if (! empty($conf->expedition->enabled)) { - print '<tr><td>'; - print '<table width="100%" class="nobordernopadding"><tr><td>'; - print $langs->trans('SendingMethod'); - print '</td>'; - if ($action != 'editshippingmethod' && $user->rights->propal->creer) - print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editshippingmethod&id='.$object->id.'">'.img_edit($langs->trans('SetShippingMode'),1).'</a></td>'; - print '</tr></table>'; - print '</td><td>'; - if ($action == 'editshippingmethod') { - $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1); - } else { - $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none'); - } - print '</td>'; - print '</tr>'; - } + // Shipping Method + if (! empty($conf->expedition->enabled)) { + print '<tr><td>'; + print '<table width="100%" class="nobordernopadding"><tr><td>'; + print $langs->trans('SendingMethod'); + print '</td>'; + if ($action != 'editshippingmethod' && $user->rights->propal->creer) + print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editshippingmethod&id='.$object->id.'">'.img_edit($langs->trans('SetShippingMode'),1).'</a></td>'; + print '</tr></table>'; + print '</td><td>'; + if ($action == 'editshippingmethod') { + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1); + } else { + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none'); + } + print '</td>'; + print '</tr>'; + } // Origin of demand print '<tr><td>'; @@ -2054,36 +2054,36 @@ if ($action == 'create') if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && ! empty($conf->banque->enabled)) { - // Bank Account - print '<tr><td>'; - print '<table width="100%" class="nobordernopadding"><tr><td>'; - print $langs->trans('BankAccount'); - print '</td>'; - if ($action != 'editbankaccount' && $user->rights->propal->creer) - print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>'; - print '</tr></table>'; - print '</td><td>'; - if ($action == 'editbankaccount') { - $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1); - } else { - $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none'); - } - print '</td>'; - print '</tr>'; + // Bank Account + print '<tr><td>'; + print '<table width="100%" class="nobordernopadding"><tr><td>'; + print $langs->trans('BankAccount'); + print '</td>'; + if ($action != 'editbankaccount' && $user->rights->propal->creer) + print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>'; + print '</tr></table>'; + print '</td><td>'; + if ($action == 'editbankaccount') { + $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1); + } else { + $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none'); + } + print '</td>'; + print '</tr>'; } // Incoterms if (!empty($conf->incoterm->enabled)) { print '<tr><td>'; - print '<table width="100%" class="nobordernopadding"><tr><td>'; - print $langs->trans('IncotermLabel'); - print '<td><td align="right">'; - if ($user->rights->propal->creer) print '<a href="'.DOL_URL_ROOT.'/comm/propal/card.php?id='.$object->id.'&action=editincoterm">'.img_edit().'</a>'; - else print ' '; - print '</td></tr></table>'; - print '</td>'; - print '<td>'; + print '<table width="100%" class="nobordernopadding"><tr><td>'; + print $langs->trans('IncotermLabel'); + print '<td><td align="right">'; + if ($user->rights->propal->creer) print '<a href="'.DOL_URL_ROOT.'/comm/propal/card.php?id='.$object->id.'&action=editincoterm">'.img_edit().'</a>'; + else print ' '; + print '</td></tr></table>'; + print '</td>'; + print '<td>'; if ($action != 'editincoterm') { print $form->textwithpicto($object->display_incoterms(), $object->libelle_incoterms, 1); @@ -2092,7 +2092,7 @@ if ($action == 'create') { print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:''), $_SERVER['PHP_SELF'].'?id='.$object->id); } - print '</td></tr>'; + print '</td></tr>'; } // Other attributes @@ -2105,25 +2105,25 @@ if ($action == 'create') print '<div class="ficheaddleft">'; print '<div class="underbanner clearboth"></div>'; - print '<table class="border centpercent">'; + print '<table class="border centpercent">'; - if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) - { - // Multicurrency Amount HT - print '<tr><td class="titlefieldmiddle">' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '</td>'; - print '<td class="nowrap">' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>'; - print '</tr>'; + if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) + { + // Multicurrency Amount HT + print '<tr><td class="titlefieldmiddle">' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '</td>'; + print '<td class="nowrap">' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>'; + print '</tr>'; - // Multicurrency Amount VAT - print '<tr><td>' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '</td>'; - print '<td class="nowrap">' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>'; - print '</tr>'; + // Multicurrency Amount VAT + print '<tr><td>' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '</td>'; + print '<td class="nowrap">' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>'; + print '</tr>'; - // Multicurrency Amount TTC - print '<tr><td>' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '</td>'; - print '<td class="nowrap">' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>'; - print '</tr>'; - } + // Multicurrency Amount TTC + print '<tr><td>' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '</td>'; + print '<td class="nowrap">' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>'; + print '</tr>'; + } // Amount HT print '<tr><td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>'; @@ -2138,15 +2138,15 @@ if ($action == 'create') // Amount Local Taxes if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) // Localtax1 { - print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>'; - print '<td class="nowrap">' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; - print '</tr>'; + print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>'; + print '<td class="nowrap">' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; + print '</tr>'; } if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) // Localtax2 { - print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>'; - print '<td class="nowrap">' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; - print '</tr>'; + print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>'; + print '<td class="nowrap">' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; + print '</tr>'; } // Amount TTC @@ -2162,7 +2162,7 @@ if ($action == 'create') // Margin Infos if (! empty($conf->margin->enabled)) { - $formmargin->displayMarginInfos($object); + $formmargin->displayMarginInfos($object); } print '</div>'; @@ -2201,7 +2201,7 @@ if ($action == 'create') include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; } - print '<div class="div-table-responsive">'; + print '<div class="div-table-responsive">'; print '<table id="tablelines" class="noborder noshadow" width="100%">'; if (! empty($object->lines)) @@ -2223,7 +2223,7 @@ if ($action == 'create') } print '</table>'; - print '</div>'; + print '</div>'; print "</form>\n"; @@ -2237,7 +2237,7 @@ if ($action == 'create') $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook + // modified by hook if (empty($reshook)) { if ($action != 'editline') @@ -2245,12 +2245,12 @@ if ($action == 'create') // Validate if ($object->statut == Propal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) > 0) { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate))) - { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate))) + { print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=validate">' . $langs->trans('Validate') . '</a></div>'; - } - else + } + else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">' . $langs->trans('Validate') . '</a></div>'; } // Create event diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index f719dbf7ea8655e9823dfc1ee1260c3d3c45a16a..7dda7031914fc2f3b9fed39fdab9d5084433e1c1 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -30,225 +30,225 @@ require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; class Proposals extends DolibarrApi { - /** - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - static $FIELDS = array( - 'socid' - ); - - /** - * @var propal $propal {@type propal} - */ - public $propal; - - /** - * Constructor - */ - function __construct() - { + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'socid' + ); + + /** + * @var propal $propal {@type propal} + */ + public $propal; + + /** + * Constructor + */ + function __construct() + { global $db, $conf; $this->db = $db; - $this->propal = new Propal($this->db); - } - - /** - * Get properties of a commercial proposal object - * - * Return an array with commercial proposal informations - * - * @param int $id ID of commercial proposal - * @return array|mixed data without useless information + $this->propal = new Propal($this->db); + } + + /** + * Get properties of a commercial proposal object + * + * Return an array with commercial proposal informations + * + * @param int $id ID of commercial proposal + * @return array|mixed data without useless information * - * @throws RestException - */ - function get($id) - { + * @throws RestException + */ + function get($id) + { if(! DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if( ! $result ) { - throw new RestException(404, 'Commercial Proposal not found'); - } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $this->propal->fetchObjectLinked(); + $this->propal->fetchObjectLinked(); return $this->_cleanObjectDatas($this->propal); - } - - /** - * List commercial proposals - * - * Get a list of commercial proposals - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $thirdparty_ids Thirdparty ids to filter commercial proposal of. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')" - * @return array Array of order objects - */ - function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '', $sqlfilters = '') { - global $db, $conf; - - $obj_ret = array(); - - // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - - // If the internal user must only see his customers, force searching by him - $search_sale = 0; - if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; - - $sql = "SELECT t.rowid"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) - $sql.= " FROM ".MAIN_DB_PREFIX."propal as t"; - - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale - - $sql.= ' WHERE t.entity IN ('.getEntity('propal').')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; - if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; - if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - // Insert sale filter - if ($search_sale > 0) - { - $sql .= " AND sc.fk_user = ".$search_sale; - } - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - $sql.= $db->order($sortfield, $sortorder); - if ($limit) { - if ($page < 0) - { - $page = 0; - } - $offset = $limit * $page; - - $sql.= $db->plimit($limit + 1, $offset); - } - - $result = $db->query($sql); - - if ($result) - { - $num = $db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - while ($i < $min) - { - $obj = $db->fetch_object($result); - $propal_static = new Propal($db); - if($propal_static->fetch($obj->rowid)) { - $obj_ret[] = $this->_cleanObjectDatas($propal_static); - } - $i++; - } - } - else { - throw new RestException(503, 'Error when retrieve propal list : '.$db->lasterror()); - } - if( ! count($obj_ret)) { - throw new RestException(404, 'No order found'); - } + } + + /** + * List commercial proposals + * + * Get a list of commercial proposals + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter commercial proposal of. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')" + * @return array Array of order objects + */ + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '', $sqlfilters = '') { + global $db, $conf; + + $obj_ret = array(); + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; + + // If the internal user must only see his customers, force searching by him + $search_sale = 0; + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT t.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql.= " FROM ".MAIN_DB_PREFIX."propal as t"; + + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + + $sql.= ' WHERE t.entity IN ('.getEntity('propal').')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + + if ($result) + { + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + while ($i < $min) + { + $obj = $db->fetch_object($result); + $propal_static = new Propal($db); + if($propal_static->fetch($obj->rowid)) { + $obj_ret[] = $this->_cleanObjectDatas($propal_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve propal list : '.$db->lasterror()); + } + if( ! count($obj_ret)) { + throw new RestException(404, 'No order found'); + } return $obj_ret; - } - - /** - * Create commercial proposal object - * - * @param array $request_data Request data - * @return int ID of propal - */ - function post($request_data = NULL) - { - if(! DolibarrApiAccess::$user->rights->propal->creer) { + } + + /** + * Create commercial proposal object + * + * @param array $request_data Request data + * @return int ID of propal + */ + function post($request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401, "Insuffisant rights"); } - // Check mandatory fields - $result = $this->_validate($request_data); + // Check mandatory fields + $result = $this->_validate($request_data); - foreach($request_data as $field => $value) { - $this->propal->$field = $value; - } - /*if (isset($request_data["lines"])) { + foreach($request_data as $field => $value) { + $this->propal->$field = $value; + } + /*if (isset($request_data["lines"])) { $lines = array(); foreach ($request_data["lines"] as $line) { array_push($lines, (object) $line); } $this->propal->lines = $lines; }*/ - if ($this->propal->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors)); - } - - return $this->propal->id; - } - - /** - * Get lines of a commercial proposal - * - * @param int $id Id of commercial proposal - * - * @url GET {id}/lines - * - * @return int - */ - function getLines($id) { - if(! DolibarrApiAccess::$user->rights->propal->lire) { + if ($this->propal->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors)); + } + + return $this->propal->id; + } + + /** + * Get lines of a commercial proposal + * + * @param int $id Id of commercial proposal + * + * @url GET {id}/lines + * + * @return int + */ + function getLines($id) { + if(! DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if( ! $result ) { - throw new RestException(404, 'Commercial Proposal not found'); - } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - $this->propal->getLinesArray(); - $result = array(); - foreach ($this->propal->lines as $line) { - array_push($result,$this->_cleanObjectDatas($line)); - } - return $result; - } - - /** - * Add a line to given commercial proposal - * - * @param int $id Id of commercial proposal to update - * @param array $request_data Commercial proposal line data - * - * @url POST {id}/lines - * - * @return int - */ - function postLine($id, $request_data = NULL) - { + } + $this->propal->getLinesArray(); + $result = array(); + foreach ($this->propal->lines as $line) { + array_push($result,$this->_cleanObjectDatas($line)); + } + return $result; + } + + /** + * Add a line to given commercial proposal + * + * @param int $id Id of commercial proposal to update + * @param array $request_data Commercial proposal line data + * + * @url POST {id}/lines + * + * @return int + */ + function postLine($id, $request_data = NULL) + { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if (! $result) { - throw new RestException(404, 'Commercial Proposal not found'); - } + $result = $this->propal->fetch($id); + if (! $result) { + throw new RestException(404, 'Commercial Proposal not found'); + } if (! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { @@ -257,288 +257,288 @@ class Proposals extends DolibarrApi $request_data = (object) $request_data; - $updateRes = $this->propal->addline( - $request_data->desc, - $request_data->subprice, - $request_data->qty, - $request_data->tva_tx, - $request_data->localtax1_tx, - $request_data->localtax2_tx, - $request_data->fk_product, - $request_data->remise_percent, - 'HT', - 0, - $request_data->info_bits, - $request_data->product_type, - $request_data->rang, - $request_data->special_code, - $fk_parent_line, - $request_data->fk_fournprice, - $request_data->pa_ht, - $request_data->label, - $request_data->date_start, - $request_data->date_end, - $request_data->array_options, - $request_data->fk_unit, - $this->element, - $request_data->id, - $request_data->multicurrency_subprice, - $request_data->fk_remise_except - ); - - if ($updateRes > 0) { - return $this->get($id)->line->rowid; - - } - return false; - } - - /** - * Update a line of given commercial proposal - * - * @param int $id Id of commercial proposal to update - * @param int $lineid Id of line to update - * @param array $request_data Commercial proposal line data - * - * @url PUT {id}/lines/{lineid} - * - * @return object - */ - function putLine($id, $lineid, $request_data = NULL) - { - if(! DolibarrApiAccess::$user->rights->propal->creer) { + $updateRes = $this->propal->addline( + $request_data->desc, + $request_data->subprice, + $request_data->qty, + $request_data->tva_tx, + $request_data->localtax1_tx, + $request_data->localtax2_tx, + $request_data->fk_product, + $request_data->remise_percent, + 'HT', + 0, + $request_data->info_bits, + $request_data->product_type, + $request_data->rang, + $request_data->special_code, + $fk_parent_line, + $request_data->fk_fournprice, + $request_data->pa_ht, + $request_data->label, + $request_data->date_start, + $request_data->date_end, + $request_data->array_options, + $request_data->fk_unit, + $this->element, + $request_data->id, + $request_data->multicurrency_subprice, + $request_data->fk_remise_except + ); + + if ($updateRes > 0) { + return $this->get($id)->line->rowid; + + } + return false; + } + + /** + * Update a line of given commercial proposal + * + * @param int $id Id of commercial proposal to update + * @param int $lineid Id of line to update + * @param array $request_data Commercial proposal line data + * + * @url PUT {id}/lines/{lineid} + * + * @return object + */ + function putLine($id, $lineid, $request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if($result <= 0) { - throw new RestException(404, 'Proposal not found'); - } + $result = $this->propal->fetch($id); + if($result <= 0) { + throw new RestException(404, 'Proposal not found'); + } if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $request_data = (object) $request_data; - - $propalline = new PropaleLigne($this->db); - $result = $propalline->fetch($lineid); - if ($result <= 0) { - throw new RestException(404, 'Proposal line not found'); - } - - $updateRes = $this->propal->updateline( - $lineid, - isset($request_data->subprice)?$request_data->subprice:$propalline->subprice, - isset($request_data->qty)?$request_data->qty:$propalline->qty, - isset($request_data->remise_percent)?$request_data->remise_percent:$propalline->remise_percent, - isset($request_data->tva_tx)?$request_data->tva_tx:$propalline->tva_tx, - isset($request_data->localtax1_tx)?$request_data->localtax1_tx:$propalline->localtax1_tx, - isset($request_data->localtax2_tx)?$request_data->localtax2_tx:$propalline->localtax2_tx, - isset($request_data->desc)?$request_data->desc:$propalline->desc, - 'HT', - isset($request_data->info_bits)?$request_data->info_bits:$propalline->info_bits, - isset($request_data->special_code)?$request_data->special_code:$propalline->special_code, - isset($request_data->fk_parent_line)?$request_data->fk_parent_line:$propalline->fk_parent_line, - 0, - isset($request_data->fk_fournprice)?$request_data->fk_fournprice:$propalline->fk_fournprice, - isset($request_data->pa_ht)?$request_data->pa_ht:$propalline->pa_ht, - isset($request_data->label)?$request_data->label:$propalline->label, - isset($request_data->product_type)?$request_data->product_type:$propalline->product_type, - isset($request_data->date_start)?$request_data->date_start:$propalline->date_start, - isset($request_data->date_end)?$request_data->date_end:$propalline->date_end, - isset($request_data->array_options)?$request_data->array_options:$propalline->array_options, - isset($request_data->fk_unit)?$request_data->fk_unit:$propalline->fk_unit, - isset($request_data->multicurrency_subprice)?$request_data->multicurrency_subprice:$propalline->subprice - ); - - if ($updateRes > 0) { - $result = $this->get($id); - unset($result->line); - return $this->_cleanObjectDatas($result); - } - return false; - } - - /** - * Delete a line of given commercial proposal - * - * - * @param int $id Id of commercial proposal to update - * @param int $lineid Id of line to delete - * - * @url DELETE {id}/lines/{lineid} - * - * @return int - */ - function delLine($id, $lineid) { - if(! DolibarrApiAccess::$user->rights->propal->creer) { + } + + $request_data = (object) $request_data; + + $propalline = new PropaleLigne($this->db); + $result = $propalline->fetch($lineid); + if ($result <= 0) { + throw new RestException(404, 'Proposal line not found'); + } + + $updateRes = $this->propal->updateline( + $lineid, + isset($request_data->subprice)?$request_data->subprice:$propalline->subprice, + isset($request_data->qty)?$request_data->qty:$propalline->qty, + isset($request_data->remise_percent)?$request_data->remise_percent:$propalline->remise_percent, + isset($request_data->tva_tx)?$request_data->tva_tx:$propalline->tva_tx, + isset($request_data->localtax1_tx)?$request_data->localtax1_tx:$propalline->localtax1_tx, + isset($request_data->localtax2_tx)?$request_data->localtax2_tx:$propalline->localtax2_tx, + isset($request_data->desc)?$request_data->desc:$propalline->desc, + 'HT', + isset($request_data->info_bits)?$request_data->info_bits:$propalline->info_bits, + isset($request_data->special_code)?$request_data->special_code:$propalline->special_code, + isset($request_data->fk_parent_line)?$request_data->fk_parent_line:$propalline->fk_parent_line, + 0, + isset($request_data->fk_fournprice)?$request_data->fk_fournprice:$propalline->fk_fournprice, + isset($request_data->pa_ht)?$request_data->pa_ht:$propalline->pa_ht, + isset($request_data->label)?$request_data->label:$propalline->label, + isset($request_data->product_type)?$request_data->product_type:$propalline->product_type, + isset($request_data->date_start)?$request_data->date_start:$propalline->date_start, + isset($request_data->date_end)?$request_data->date_end:$propalline->date_end, + isset($request_data->array_options)?$request_data->array_options:$propalline->array_options, + isset($request_data->fk_unit)?$request_data->fk_unit:$propalline->fk_unit, + isset($request_data->multicurrency_subprice)?$request_data->multicurrency_subprice:$propalline->subprice + ); + + if ($updateRes > 0) { + $result = $this->get($id); + unset($result->line); + return $this->_cleanObjectDatas($result); + } + return false; + } + + /** + * Delete a line of given commercial proposal + * + * + * @param int $id Id of commercial proposal to update + * @param int $lineid Id of line to delete + * + * @url DELETE {id}/lines/{lineid} + * + * @return int + */ + function delLine($id, $lineid) { + if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if( ! $result ) { - throw new RestException(404, 'Proposal not found'); - } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Proposal not found'); + } if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } + } $request_data = (object) $request_data; - $updateRes = $this->propal->deleteline($lineid); - if ($updateRes == 1) { - return $this->get($id); - } - return false; - } - - /** - * Update commercial proposal general fields (won't touch lines of commercial proposal) - * - * @param int $id Id of commercial proposal to update - * @param array $request_data Datas - * - * @return int - */ - function put($id, $request_data = NULL) { - if(! DolibarrApiAccess::$user->rights->propal->creer) { + $updateRes = $this->propal->deleteline($lineid); + if ($updateRes == 1) { + return $this->get($id); + } + return false; + } + + /** + * Update commercial proposal general fields (won't touch lines of commercial proposal) + * + * @param int $id Id of commercial proposal to update + * @param array $request_data Datas + * + * @return int + */ + function put($id, $request_data = NULL) { + if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if( ! $result ) { - throw new RestException(404, 'Proposal not found'); - } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Proposal not found'); + } if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - foreach($request_data as $field => $value) { - if ($field == 'id') continue; - $this->propal->$field = $value; - } - - if($this->propal->update($id, DolibarrApiAccess::$user,1,'','','update')) - return $this->get($id); - - return false; - } - - /** - * Delete commercial proposal - * - * @param int $id Commercial proposal ID - * - * @return array - */ - function delete($id) - { - if(! DolibarrApiAccess::$user->rights->propal->supprimer) { + foreach($request_data as $field => $value) { + if ($field == 'id') continue; + $this->propal->$field = $value; + } + + if($this->propal->update($id, DolibarrApiAccess::$user,1,'','','update')) + return $this->get($id); + + return false; + } + + /** + * Delete commercial proposal + * + * @param int $id Commercial proposal ID + * + * @return array + */ + function delete($id) + { + if(! DolibarrApiAccess::$user->rights->propal->supprimer) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if( ! $result ) { - throw new RestException(404, 'Commercial Proposal not found'); - } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - if( ! $this->propal->delete(DolibarrApiAccess::$user)) { - throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Commercial Proposal deleted' - ) - ); - - } - - /** - * Validate a commercial proposal - * - * @param int $id Commercial proposal ID - * @param int $notrigger Use {} - * - * @url POST {id}/validate - * - * @return array - * FIXME An error 403 is returned if the request has an empty body. - * Error message: "Forbidden: Content type `text/plain` is not supported." - * Workaround: send this in the body - * { - * "notrigger": 0 - * } - */ - function validate($id, $notrigger=0) - { - if(! DolibarrApiAccess::$user->rights->propal->creer) { + if( ! $this->propal->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Commercial Proposal deleted' + ) + ); + + } + + /** + * Validate a commercial proposal + * + * @param int $id Commercial proposal ID + * @param int $notrigger Use {} + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "notrigger": 0 + * } + */ + function validate($id, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - $result = $this->propal->fetch($id); - if( ! $result ) { - throw new RestException(404, 'Commercial Proposal not found'); - } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); - if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); - } - if ($result < 0) { - throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Commercial Proposal validated (Ref='.$this->propal->ref.')' - ) - ); - } - - /** - * Validate fields before create or update object - * - * @param array $data Array with data to verify - * @return array - * @throws RestException - */ - function _validate($data) - { - $propal = array(); - foreach (Proposals::$FIELDS as $field) { - if (!isset($data[$field])) - throw new RestException(400, "$field field missing"); - $propal[$field] = $data[$field]; - - } - return $propal; - } - - /** - * Clean sensible object datas - * - * @param object $object Object to clean - * @return array Array of cleaned object properties - */ - function _cleanObjectDatas($object) { - - $object = parent::_cleanObjectDatas($object); - - unset($object->name); - unset($object->lastname); - unset($object->firstname); - unset($object->civility_id); - unset($object->address); - - return $object; - } + $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Commercial Proposal validated (Ref='.$this->propal->ref.')' + ) + ); + } + + /** + * Validate fields before create or update object + * + * @param array $data Array with data to verify + * @return array + * @throws RestException + */ + function _validate($data) + { + $propal = array(); + foreach (Proposals::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $propal[$field] = $data[$field]; + + } + return $propal; + } + + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) { + + $object = parent::_cleanObjectDatas($object); + + unset($object->name); + unset($object->lastname); + unset($object->firstname); + unset($object->civility_id); + unset($object->address); + + return $object; + } } diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 5b9fda29a6d7d66e57bb3fb02f2dc84dcffd4d7a..cd5f81783b7da37a623d94c0b71164446fab0039 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -44,40 +44,40 @@ require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php'; */ class Propal extends CommonObject { - public $element='propal'; - public $table_element='propal'; - public $table_element_line='propaldet'; - public $fk_element='fk_propal'; - protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - public $picto='propal'; + public $element='propal'; + public $table_element='propal'; + public $table_element_line='propaldet'; + public $fk_element='fk_propal'; + protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + public $picto='propal'; - /** - * {@inheritdoc} - */ - protected $table_ref_field = 'ref'; + /** + * {@inheritdoc} + */ + protected $table_ref_field = 'ref'; /** * ID of the client * @var int */ - public $socid; + public $socid; - public $contactid; - public $author; - public $ref_client; + public $contactid; + public $author; + public $ref_client; /** * Status of the quote * @var int * @see Propal::STATUS_DRAFT, Propal::STATUS_VALIDATED, Propal::STATUS_SIGNED, Propal::STATUS_NOTSIGNED, Propal::STATUS_BILLED */ - public $statut; + public $statut; /** * @deprecated * @see date_creation */ - public $datec; + public $datec; /** * Creation date @@ -89,7 +89,7 @@ class Propal extends CommonObject * @deprecated * @see date_validation */ - public $datev; + public $datev; /** * Validation date @@ -101,62 +101,62 @@ class Propal extends CommonObject * Date of the quote * @var */ - public $date; + public $date; /** * @deprecated * @see date */ - public $datep; - public $date_livraison; - public $fin_validite; + public $datep; + public $date_livraison; + public $fin_validite; - public $user_author_id; - public $user_valid_id; - public $user_close_id; + public $user_author_id; + public $user_valid_id; + public $user_close_id; /** * @deprecated * @see total_ht */ - public $price; + public $price; /** * @deprecated * @see total_tva */ - public $tva; + public $tva; /** * @deprecated * @see total_ttc */ - public $total; - - public $cond_reglement_code; - public $mode_reglement_code; - public $remise; - public $remise_percent; - public $remise_absolue; - public $fk_address; - public $address_type; - public $address; - public $availability_id; - public $availability_code; - public $demand_reason_id; - public $demand_reason_code; - - public $products=array(); - public $extraparams=array(); + public $total; + + public $cond_reglement_code; + public $mode_reglement_code; + public $remise; + public $remise_percent; + public $remise_absolue; + public $fk_address; + public $address_type; + public $address; + public $availability_id; + public $availability_code; + public $demand_reason_id; + public $demand_reason_code; + + public $products=array(); + public $extraparams=array(); /** * @var PropaleLigne[] */ - public $lines = array(); - public $line; + public $lines = array(); + public $line; - public $labelstatut=array(); - public $labelstatut_short=array(); + public $labelstatut=array(); + public $labelstatut_short=array(); - public $specimen; + public $specimen; // Multicurrency public $fk_multicurrency; @@ -189,256 +189,256 @@ class Propal extends CommonObject */ const STATUS_BILLED = 4; // Todo rename into STATUS_CLOSE ? - /** - * Constructor - * - * @param DoliDB $db Database handler - * @param int $socid Id third party - * @param int $propalid Id proposal - */ - function __construct($db, $socid="", $propalid=0) - { - global $conf,$langs; - - $this->db = $db; - $this->socid = $socid; - $this->id = $propalid; - $this->products = array(); - $this->remise = 0; - $this->remise_percent = 0; - $this->remise_absolue = 0; - - $this->duree_validite=$conf->global->PROPALE_VALIDITY_DURATION; - - $langs->load("propal"); - $this->labelstatut[0]=(! empty($conf->global->PROPAL_STATUS_DRAFT_LABEL) ? $conf->global->PROPAL_STATUS_DRAFT_LABEL : $langs->trans("PropalStatusDraft")); - $this->labelstatut[1]=(! empty($conf->global->PROPAL_STATUS_VALIDATED_LABEL) ? $conf->global->PROPAL_STATUS_VALIDATED_LABEL : $langs->trans("PropalStatusValidated")); - $this->labelstatut[2]=(! empty($conf->global->PROPAL_STATUS_SIGNED_LABEL) ? $conf->global->PROPAL_STATUS_SIGNED_LABEL : $langs->trans("PropalStatusSigned")); - $this->labelstatut[3]=(! empty($conf->global->PROPAL_STATUS_NOTSIGNED_LABEL) ? $conf->global->PROPAL_STATUS_NOTSIGNED_LABEL : $langs->trans("PropalStatusNotSigned")); - $this->labelstatut[4]=(! empty($conf->global->PROPAL_STATUS_BILLED_LABEL) ? $conf->global->PROPAL_STATUS_BILLED_LABEL : $langs->trans("PropalStatusBilled")); - $this->labelstatut_short[0]=(! empty($conf->global->PROPAL_STATUS_DRAFTSHORT_LABEL) ? $conf->global->PROPAL_STATUS_DRAFTSHORT_LABEL : $langs->trans("PropalStatusDraftShort")); - $this->labelstatut_short[1]=(! empty($conf->global->PROPAL_STATUS_VALIDATEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_VALIDATEDSHORT_LABEL : $langs->trans("Opened")); - $this->labelstatut_short[2]=(! empty($conf->global->PROPAL_STATUS_SIGNEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_SIGNEDSHORT_LABEL : $langs->trans("PropalStatusSignedShort")); - $this->labelstatut_short[3]=(! empty($conf->global->PROPAL_STATUS_NOTSIGNEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_NOTSIGNEDSHORT_LABEL : $langs->trans("PropalStatusNotSignedShort")); - $this->labelstatut_short[4]=(! empty($conf->global->PROPAL_STATUS_BILLEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_BILLEDSHORT_LABEL : $langs->trans("PropalStatusBilledShort")); - } - - - /** - * Add line into array products - * $this->thirdparty should be loaded - * - * @param int $idproduct Product Id to add - * @param int $qty Quantity - * @param int $remise_percent Discount effected on Product - * @return int <0 if KO, >0 if OK - * - * TODO Replace calls to this function by generation objet Ligne - * inserted into table $this->products - */ - function add_product($idproduct, $qty, $remise_percent=0) - { - global $conf, $mysoc; - - if (! $qty) $qty = 1; - - dol_syslog(get_class($this)."::add_product $idproduct, $qty, $remise_percent"); - if ($idproduct > 0) - { - $prod=new Product($this->db); - $prod->fetch($idproduct); - - $productdesc = $prod->description; - - $tva_tx = get_default_tva($mysoc,$this->thirdparty,$prod->id); - $tva_npr = get_default_npr($mysoc,$this->thirdparty,$prod->id); - if (empty($tva_tx)) $tva_npr=0; - $vat_src_code = ''; // May be defined into tva_tx - - $localtax1_tx = get_localtax($tva_tx,1,$mysoc,$this->thirdparty,$tva_npr); - $localtax2_tx = get_localtax($tva_tx,2,$mysoc,$this->thirdparty,$tva_npr); - - // multiprices - if($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) - { - $price = $prod->multiprices[$this->thirdparty->price_level]; - } - else - { - $price = $prod->price; - } - - $line = new PropaleLigne($this->db); - - $line->fk_product=$idproduct; - $line->desc=$productdesc; - $line->qty=$qty; - $line->subprice=$price; - $line->remise_percent=$remise_percent; - $line->vat_src_code=$vat_src_code; - $line->tva_tx=$tva_tx; - $line->fk_unit=$prod->fk_unit; + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param int $socid Id third party + * @param int $propalid Id proposal + */ + function __construct($db, $socid="", $propalid=0) + { + global $conf,$langs; + + $this->db = $db; + $this->socid = $socid; + $this->id = $propalid; + $this->products = array(); + $this->remise = 0; + $this->remise_percent = 0; + $this->remise_absolue = 0; + + $this->duree_validite=$conf->global->PROPALE_VALIDITY_DURATION; + + $langs->load("propal"); + $this->labelstatut[0]=(! empty($conf->global->PROPAL_STATUS_DRAFT_LABEL) ? $conf->global->PROPAL_STATUS_DRAFT_LABEL : $langs->trans("PropalStatusDraft")); + $this->labelstatut[1]=(! empty($conf->global->PROPAL_STATUS_VALIDATED_LABEL) ? $conf->global->PROPAL_STATUS_VALIDATED_LABEL : $langs->trans("PropalStatusValidated")); + $this->labelstatut[2]=(! empty($conf->global->PROPAL_STATUS_SIGNED_LABEL) ? $conf->global->PROPAL_STATUS_SIGNED_LABEL : $langs->trans("PropalStatusSigned")); + $this->labelstatut[3]=(! empty($conf->global->PROPAL_STATUS_NOTSIGNED_LABEL) ? $conf->global->PROPAL_STATUS_NOTSIGNED_LABEL : $langs->trans("PropalStatusNotSigned")); + $this->labelstatut[4]=(! empty($conf->global->PROPAL_STATUS_BILLED_LABEL) ? $conf->global->PROPAL_STATUS_BILLED_LABEL : $langs->trans("PropalStatusBilled")); + $this->labelstatut_short[0]=(! empty($conf->global->PROPAL_STATUS_DRAFTSHORT_LABEL) ? $conf->global->PROPAL_STATUS_DRAFTSHORT_LABEL : $langs->trans("PropalStatusDraftShort")); + $this->labelstatut_short[1]=(! empty($conf->global->PROPAL_STATUS_VALIDATEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_VALIDATEDSHORT_LABEL : $langs->trans("Opened")); + $this->labelstatut_short[2]=(! empty($conf->global->PROPAL_STATUS_SIGNEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_SIGNEDSHORT_LABEL : $langs->trans("PropalStatusSignedShort")); + $this->labelstatut_short[3]=(! empty($conf->global->PROPAL_STATUS_NOTSIGNEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_NOTSIGNEDSHORT_LABEL : $langs->trans("PropalStatusNotSignedShort")); + $this->labelstatut_short[4]=(! empty($conf->global->PROPAL_STATUS_BILLEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_BILLEDSHORT_LABEL : $langs->trans("PropalStatusBilledShort")); + } + + + /** + * Add line into array products + * $this->thirdparty should be loaded + * + * @param int $idproduct Product Id to add + * @param int $qty Quantity + * @param int $remise_percent Discount effected on Product + * @return int <0 if KO, >0 if OK + * + * TODO Replace calls to this function by generation objet Ligne + * inserted into table $this->products + */ + function add_product($idproduct, $qty, $remise_percent=0) + { + global $conf, $mysoc; + + if (! $qty) $qty = 1; + + dol_syslog(get_class($this)."::add_product $idproduct, $qty, $remise_percent"); + if ($idproduct > 0) + { + $prod=new Product($this->db); + $prod->fetch($idproduct); + + $productdesc = $prod->description; + + $tva_tx = get_default_tva($mysoc,$this->thirdparty,$prod->id); + $tva_npr = get_default_npr($mysoc,$this->thirdparty,$prod->id); + if (empty($tva_tx)) $tva_npr=0; + $vat_src_code = ''; // May be defined into tva_tx + + $localtax1_tx = get_localtax($tva_tx,1,$mysoc,$this->thirdparty,$tva_npr); + $localtax2_tx = get_localtax($tva_tx,2,$mysoc,$this->thirdparty,$tva_npr); + + // multiprices + if($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) + { + $price = $prod->multiprices[$this->thirdparty->price_level]; + } + else + { + $price = $prod->price; + } + + $line = new PropaleLigne($this->db); + + $line->fk_product=$idproduct; + $line->desc=$productdesc; + $line->qty=$qty; + $line->subprice=$price; + $line->remise_percent=$remise_percent; + $line->vat_src_code=$vat_src_code; + $line->tva_tx=$tva_tx; + $line->fk_unit=$prod->fk_unit; if ($tva_npr) $line->info_bits = 1; - $this->lines[]=$line; - } - } - - /** - * Adding line of fixed discount in the proposal in DB - * - * @param int $idremise Id of fixed discount - * @return int >0 if OK, <0 if KO - */ - function insert_discount($idremise) - { - global $langs; - - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - - $this->db->begin(); - - $remise=new DiscountAbsolute($this->db); - $result=$remise->fetch($idremise); - - if ($result > 0) - { - if ($remise->fk_facture) // Protection against multiple submission - { - $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); - $this->db->rollback(); - return -5; - } - - $line=new PropaleLigne($this->db); - - $this->line->context = $this->context; - - $line->fk_propal=$this->id; - $line->fk_remise_except=$remise->id; - $line->desc=$remise->description; // Description ligne - $line->vat_src_code=$remise->vat_src_code; - $line->tva_tx=$remise->tva_tx; - $line->subprice=-$remise->amount_ht; - $line->fk_product=0; // Id produit predefined - $line->qty=1; - $line->remise=0; - $line->remise_percent=0; - $line->rang=-1; - $line->info_bits=2; - - // TODO deprecated - $line->price=-$remise->amount_ht; - - $line->total_ht = -$remise->amount_ht; - $line->total_tva = -$remise->amount_tva; - $line->total_ttc = -$remise->amount_ttc; - - $result=$line->insert(); - if ($result > 0) - { - $result=$this->update_price(1); - if ($result > 0) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$line->error; - $this->db->rollback(); - return -2; - } - } - else - { - $this->db->rollback(); - return -2; - } - } - - /** - * Add a proposal line into database (linked to product/service or not) - * The parameters are already supposed to be appropriate and with final values to the call - * of this method. Also, for the VAT rate, it must have already been defined - * by whose calling the method get_default_tva (societe_vendeuse, societe_acheteuse, '' product) - * and desc must already have the right value (it's up to the caller to manage multilanguage) - * - * @param string $desc Description de la ligne - * @param float $pu_ht Prix unitaire - * @param float $qty Quantite - * @param float $txtva Taux de tva - * @param float $txlocaltax1 Local tax 1 rate - * @param float $txlocaltax2 Local tax 2 rate - * @param int $fk_product Id du produit/service predefini - * @param float $remise_percent Pourcentage de remise de la ligne - * @param string $price_base_type HT or TTC - * @param float $pu_ttc Prix unitaire TTC - * @param int $info_bits Bits de type de lignes - * @param int $type Type of line (0=product, 1=service). Not used if fk_product is defined, the type of product is used. - * @param int $rang Position of line - * @param int $special_code Special code (also used by externals modules!) - * @param int $fk_parent_line Id of parent line - * @param int $fk_fournprice Id supplier price - * @param int $pa_ht Buying price without tax - * @param string $label ??? - * @param int $date_start Start date of the line - * @param int $date_end End date of the line - * @param array $array_options extrafields array - * @param string $fk_unit Code of the unit to use. Null to use the default one - * @param string $origin 'order', ... - * @param int $origin_id Id of origin object - * @param double $pu_ht_devise Unit price in currency - * @param int $fk_remise_except Id discount if line is from a discount - * @return int >0 if OK, <0 if KO - * @see add_product - */ + $this->lines[]=$line; + } + } + + /** + * Adding line of fixed discount in the proposal in DB + * + * @param int $idremise Id of fixed discount + * @return int >0 if OK, <0 if KO + */ + function insert_discount($idremise) + { + global $langs; + + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + + $this->db->begin(); + + $remise=new DiscountAbsolute($this->db); + $result=$remise->fetch($idremise); + + if ($result > 0) + { + if ($remise->fk_facture) // Protection against multiple submission + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); + $this->db->rollback(); + return -5; + } + + $line=new PropaleLigne($this->db); + + $this->line->context = $this->context; + + $line->fk_propal=$this->id; + $line->fk_remise_except=$remise->id; + $line->desc=$remise->description; // Description ligne + $line->vat_src_code=$remise->vat_src_code; + $line->tva_tx=$remise->tva_tx; + $line->subprice=-$remise->amount_ht; + $line->fk_product=0; // Id produit predefined + $line->qty=1; + $line->remise=0; + $line->remise_percent=0; + $line->rang=-1; + $line->info_bits=2; + + // TODO deprecated + $line->price=-$remise->amount_ht; + + $line->total_ht = -$remise->amount_ht; + $line->total_tva = -$remise->amount_tva; + $line->total_ttc = -$remise->amount_ttc; + + $result=$line->insert(); + if ($result > 0) + { + $result=$this->update_price(1); + if ($result > 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$line->error; + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + return -2; + } + } + + /** + * Add a proposal line into database (linked to product/service or not) + * The parameters are already supposed to be appropriate and with final values to the call + * of this method. Also, for the VAT rate, it must have already been defined + * by whose calling the method get_default_tva (societe_vendeuse, societe_acheteuse, '' product) + * and desc must already have the right value (it's up to the caller to manage multilanguage) + * + * @param string $desc Description de la ligne + * @param float $pu_ht Prix unitaire + * @param float $qty Quantite + * @param float $txtva Taux de tva + * @param float $txlocaltax1 Local tax 1 rate + * @param float $txlocaltax2 Local tax 2 rate + * @param int $fk_product Id du produit/service predefini + * @param float $remise_percent Pourcentage de remise de la ligne + * @param string $price_base_type HT or TTC + * @param float $pu_ttc Prix unitaire TTC + * @param int $info_bits Bits de type de lignes + * @param int $type Type of line (0=product, 1=service). Not used if fk_product is defined, the type of product is used. + * @param int $rang Position of line + * @param int $special_code Special code (also used by externals modules!) + * @param int $fk_parent_line Id of parent line + * @param int $fk_fournprice Id supplier price + * @param int $pa_ht Buying price without tax + * @param string $label ??? + * @param int $date_start Start date of the line + * @param int $date_end End date of the line + * @param array $array_options extrafields array + * @param string $fk_unit Code of the unit to use. Null to use the default one + * @param string $origin 'order', ... + * @param int $origin_id Id of origin object + * @param double $pu_ht_devise Unit price in currency + * @param int $fk_remise_except Id discount if line is from a discount + * @return int >0 if OK, <0 if KO + * @see add_product + */ function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$date_start='', $date_end='',$array_options=0, $fk_unit=null, $origin='', $origin_id=0, $pu_ht_devise=0, $fk_remise_except=0) - { - global $mysoc, $conf, $langs; - - dol_syslog(get_class($this)."::addline propalid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits, type=$type, fk_remise_except=".$fk_remise_except); - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - - // Clean parameters - if (empty($remise_percent)) $remise_percent=0; - if (empty($qty)) $qty=0; - if (empty($info_bits)) $info_bits=0; - if (empty($rang)) $rang=0; - if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; - - $remise_percent=price2num($remise_percent); - $qty=price2num($qty); - $pu_ht=price2num($pu_ht); - $pu_ttc=price2num($pu_ttc); - $txtva=price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' - $txlocaltax1=price2num($txlocaltax1); - $txlocaltax2=price2num($txlocaltax2); - $pa_ht=price2num($pa_ht); - if ($price_base_type=='HT') - { - $pu=$pu_ht; - } - else - { - $pu=$pu_ttc; - } - - // Check parameters - if ($type < 0) return -1; - - if ($this->statut == self::STATUS_DRAFT) - { - $this->db->begin(); - - $product_type=$type; + { + global $mysoc, $conf, $langs; + + dol_syslog(get_class($this)."::addline propalid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits, type=$type, fk_remise_except=".$fk_remise_except); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Clean parameters + if (empty($remise_percent)) $remise_percent=0; + if (empty($qty)) $qty=0; + if (empty($info_bits)) $info_bits=0; + if (empty($rang)) $rang=0; + if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; + + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + $pu_ht=price2num($pu_ht); + $pu_ttc=price2num($pu_ttc); + $txtva=price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + $txlocaltax1=price2num($txlocaltax1); + $txlocaltax2=price2num($txlocaltax2); + $pa_ht=price2num($pa_ht); + if ($price_base_type=='HT') + { + $pu=$pu_ht; + } + else + { + $pu=$pu_ttc; + } + + // Check parameters + if ($type < 0) return -1; + + if ($this->statut == self::STATUS_DRAFT) + { + $this->db->begin(); + + $product_type=$type; if (!empty($fk_product)) { $product=new Product($this->db); @@ -446,390 +446,390 @@ class Propal extends CommonObject $product_type=$product->type; if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL) && $product_type == 0 && $product->stock_reel < $qty) { - $langs->load("errors"); - $this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref); + $langs->load("errors"); + $this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref); $this->db->rollback(); return -3; } } // Calcul du total TTC et de la TVA pour la ligne a partir de - // qty, pu, remise_percent et txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - - $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc); - - // Clean vat code - $vat_src_code=''; - if (preg_match('/\((.*)\)/', $txtva, $reg)) - { - $vat_src_code = $reg[1]; - $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. - } - - $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); - - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc); + + // Clean vat code + $vat_src_code=''; + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { + $vat_src_code = $reg[1]; + $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. + } + + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); + + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; $pu_ht = $tabprice[3]; $pu_tva = $tabprice[4]; $pu_ttc = $tabprice[5]; // MultiCurrency $multicurrency_total_ht = $tabprice[16]; - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; $pu_ht_devise = $tabprice[19]; - // Rang to use - $rangtouse = $rang; - if ($rangtouse == -1) - { - $rangmax = $this->line_max($fk_parent_line); - $rangtouse = $rangmax + 1; - } - - // TODO A virer - // Anciens indicateurs: $price, $remise (a ne plus utiliser) - $price = $pu; - $remise = 0; - if ($remise_percent > 0) - { - $remise = round(($pu * $remise_percent / 100), 2); - $price = $pu - $remise; - } - - // Insert line - $this->line=new PropaleLigne($this->db); - - $this->line->context = $this->context; - - $this->line->fk_propal=$this->id; - $this->line->label=$label; - $this->line->desc=$desc; - $this->line->qty=$qty; + // Rang to use + $rangtouse = $rang; + if ($rangtouse == -1) + { + $rangmax = $this->line_max($fk_parent_line); + $rangtouse = $rangmax + 1; + } + + // TODO A virer + // Anciens indicateurs: $price, $remise (a ne plus utiliser) + $price = $pu; + $remise = 0; + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100), 2); + $price = $pu - $remise; + } + + // Insert line + $this->line=new PropaleLigne($this->db); + + $this->line->context = $this->context; + + $this->line->fk_propal=$this->id; + $this->line->label=$label; + $this->line->desc=$desc; + $this->line->qty=$qty; $this->line->vat_src_code=$vat_src_code; - $this->line->tva_tx=$txtva; - $this->line->localtax1_tx=$txlocaltax1; - $this->line->localtax2_tx=$txlocaltax2; + $this->line->tva_tx=$txtva; + $this->line->localtax1_tx=$txlocaltax1; + $this->line->localtax2_tx=$txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; - $this->line->fk_product=$fk_product; - $this->line->product_type=$type; - $this->line->fk_remise_except=$fk_remise_except; - $this->line->remise_percent=$remise_percent; - $this->line->subprice=$pu_ht; - $this->line->rang=$rangtouse; - $this->line->info_bits=$info_bits; - $this->line->total_ht=$total_ht; - $this->line->total_tva=$total_tva; - $this->line->total_localtax1=$total_localtax1; - $this->line->total_localtax2=$total_localtax2; - $this->line->total_ttc=$total_ttc; - $this->line->special_code=$special_code; - $this->line->fk_parent_line=$fk_parent_line; - $this->line->fk_unit=$fk_unit; - - $this->line->date_start=$date_start; - $this->line->date_end=$date_end; + $this->line->fk_product=$fk_product; + $this->line->product_type=$type; + $this->line->fk_remise_except=$fk_remise_except; + $this->line->remise_percent=$remise_percent; + $this->line->subprice=$pu_ht; + $this->line->rang=$rangtouse; + $this->line->info_bits=$info_bits; + $this->line->total_ht=$total_ht; + $this->line->total_tva=$total_tva; + $this->line->total_localtax1=$total_localtax1; + $this->line->total_localtax2=$total_localtax2; + $this->line->total_ttc=$total_ttc; + $this->line->special_code=$special_code; + $this->line->fk_parent_line=$fk_parent_line; + $this->line->fk_unit=$fk_unit; + + $this->line->date_start=$date_start; + $this->line->date_end=$date_end; $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; - $this->line->origin_id = $origin_id; - $this->line->origin = $origin; + $this->line->origin_id = $origin_id; + $this->line->origin = $origin; // Multicurrency $this->line->fk_multicurrency = $this->fk_multicurrency; $this->line->multicurrency_code = $this->multicurrency_code; $this->line->multicurrency_subprice = $pu_ht_devise; $this->line->multicurrency_total_ht = $multicurrency_total_ht; - $this->line->multicurrency_total_tva = $multicurrency_total_tva; - $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; + $this->line->multicurrency_total_tva = $multicurrency_total_tva; + $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; - // Mise en option de la ligne - if (empty($qty) && empty($special_code)) $this->line->special_code=3; + // Mise en option de la ligne + if (empty($qty) && empty($special_code)) $this->line->special_code=3; - // TODO deprecated - $this->line->price=$price; - $this->line->remise=$remise; + // TODO deprecated + $this->line->price=$price; + $this->line->remise=$remise; - if (is_array($array_options) && count($array_options)>0) { - $this->line->array_options=$array_options; - } + if (is_array($array_options) && count($array_options)>0) { + $this->line->array_options=$array_options; + } - $result=$this->line->insert(); - if ($result > 0) - { - // Reorder if child line - if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); + $result=$this->line->insert(); + if ($result > 0) + { + // Reorder if child line + if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); - // Mise a jour informations denormalisees au niveau de la propale meme - $result=$this->update_price(1,'auto',0,$mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. - if ($result > 0) - { - $this->db->commit(); - return $this->line->rowid; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->line->error; - $this->db->rollback(); - return -2; - } - } - } - - - /** - * Update a proposal line - * - * @param int $rowid Id de la ligne - * @param float $pu Prix unitaire (HT ou TTC selon price_base_type) - * @param float $qty Quantity - * @param float $remise_percent Remise effectuee sur le produit - * @param float $txtva Taux de TVA - * @param float $txlocaltax1 Local tax 1 rate - * @param float $txlocaltax2 Local tax 2 rate - * @param string $desc Description - * @param string $price_base_type HT ou TTC - * @param int $info_bits Miscellaneous informations - * @param int $special_code Special code (also used by externals modules!) - * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). - * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) - * @param int $fk_fournprice Id of origin supplier price - * @param int $pa_ht Price (without tax) of product when it was bought - * @param string $label ??? - * @param int $type 0/1=Product/service - * @param int $date_start Start date of the line - * @param int $date_end End date of the line + // Mise a jour informations denormalisees au niveau de la propale meme + $result=$this->update_price(1,'auto',0,$mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if ($result > 0) + { + $this->db->commit(); + return $this->line->rowid; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->line->error; + $this->db->rollback(); + return -2; + } + } + } + + + /** + * Update a proposal line + * + * @param int $rowid Id de la ligne + * @param float $pu Prix unitaire (HT ou TTC selon price_base_type) + * @param float $qty Quantity + * @param float $remise_percent Remise effectuee sur le produit + * @param float $txtva Taux de TVA + * @param float $txlocaltax1 Local tax 1 rate + * @param float $txlocaltax2 Local tax 2 rate + * @param string $desc Description + * @param string $price_base_type HT ou TTC + * @param int $info_bits Miscellaneous informations + * @param int $special_code Special code (also used by externals modules!) + * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). + * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) + * @param int $fk_fournprice Id of origin supplier price + * @param int $pa_ht Price (without tax) of product when it was bought + * @param string $label ??? + * @param int $type 0/1=Product/service + * @param int $date_start Start date of the line + * @param int $date_end End date of the line * @param array $array_options extrafields array - * @param string $fk_unit Code of the unit to use. Null to use the default one + * @param string $fk_unit Code of the unit to use. Null to use the default one * @param double $pu_ht_devise Unit price in currency * @param int $notrigger disable line update trigger - * @return int 0 if OK, <0 if KO - */ + * @return int 0 if OK, <0 if KO + */ function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $date_start='', $date_end='', $array_options=0, $fk_unit=null, $pu_ht_devise = 0, $notrigger=0) - { - global $mysoc; + { + global $mysoc; - dol_syslog(get_class($this)."::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent, + dol_syslog(get_class($this)."::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent, txtva=$txtva, desc=$desc, price_base_type=$price_base_type, info_bits=$info_bits, special_code=$special_code, fk_parent_line=$fk_parent_line, pa_ht=$pa_ht, type=$type, date_start=$date_start, date_end=$date_end"); - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - - // Clean parameters - $remise_percent=price2num($remise_percent); - $qty=price2num($qty); - $pu = price2num($pu); - $txtva = price2num($txtva); - $txlocaltax1=price2num($txlocaltax1); - $txlocaltax2=price2num($txlocaltax2); - $pa_ht=price2num($pa_ht); - if (empty($qty) && empty($special_code)) $special_code=3; // Set option tag - if (! empty($qty) && $special_code == 3) $special_code=0; // Remove option tag - if (empty($type)) $type=0; - - if ($this->statut == self::STATUS_DRAFT) - { - $this->db->begin(); - - // Calcul du total TTC et de la TVA pour la ligne a partir de - // qty, pu, remise_percent et txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - - $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc); - - // Clean vat code - $vat_src_code=''; - if (preg_match('/\((.*)\)/', $txtva, $reg)) - { - $vat_src_code = $reg[1]; - $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. - } - - $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Clean parameters + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + $pu = price2num($pu); + $txtva = price2num($txtva); + $txlocaltax1=price2num($txlocaltax1); + $txlocaltax2=price2num($txlocaltax2); + $pa_ht=price2num($pa_ht); + if (empty($qty) && empty($special_code)) $special_code=3; // Set option tag + if (! empty($qty) && $special_code == 3) $special_code=0; // Remove option tag + if (empty($type)) $type=0; + + if ($this->statut == self::STATUS_DRAFT) + { + $this->db->begin(); + + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc); + + // Clean vat code + $vat_src_code=''; + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { + $vat_src_code = $reg[1]; + $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. + } + + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; $pu_ht = $tabprice[3]; $pu_tva = $tabprice[4]; $pu_ttc = $tabprice[5]; // MultiCurrency $multicurrency_total_ht = $tabprice[16]; - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; $pu_ht_devise = $tabprice[19]; - // Anciens indicateurs: $price, $remise (a ne plus utiliser) - $price = $pu; - if ($remise_percent > 0) - { - $remise = round(($pu * $remise_percent / 100), 2); - $price = $pu - $remise; - } - - //Fetch current line from the database and then clone the object and set it in $oldline property - $line = new PropaleLigne($this->db); - $line->fetch($rowid); + // Anciens indicateurs: $price, $remise (a ne plus utiliser) + $price = $pu; + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100), 2); + $price = $pu - $remise; + } + + //Fetch current line from the database and then clone the object and set it in $oldline property + $line = new PropaleLigne($this->db); + $line->fetch($rowid); $line->fetch_optionals(); // Fetch extrafields for oldcopy $staticline = clone $line; - $line->oldline = $staticline; - $this->line = $line; - $this->line->context = $this->context; - - // Reorder if fk_parent_line change - if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) - { - $rangmax = $this->line_max($fk_parent_line); - $this->line->rang = $rangmax + 1; - } - - $this->line->rowid = $rowid; - $this->line->label = $label; - $this->line->desc = $desc; - $this->line->qty = $qty; - $this->line->product_type = $type; - $this->line->vat_src_code = $vat_src_code; - $this->line->tva_tx = $txtva; - $this->line->localtax1_tx = $txlocaltax1; - $this->line->localtax2_tx = $txlocaltax2; + $line->oldline = $staticline; + $this->line = $line; + $this->line->context = $this->context; + + // Reorder if fk_parent_line change + if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) + { + $rangmax = $this->line_max($fk_parent_line); + $this->line->rang = $rangmax + 1; + } + + $this->line->rowid = $rowid; + $this->line->label = $label; + $this->line->desc = $desc; + $this->line->qty = $qty; + $this->line->product_type = $type; + $this->line->vat_src_code = $vat_src_code; + $this->line->tva_tx = $txtva; + $this->line->localtax1_tx = $txlocaltax1; + $this->line->localtax2_tx = $txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; - $this->line->remise_percent = $remise_percent; - $this->line->subprice = $pu_ht; - $this->line->info_bits = $info_bits; - - $this->line->total_ht = $total_ht; - $this->line->total_tva = $total_tva; - $this->line->total_localtax1 = $total_localtax1; - $this->line->total_localtax2 = $total_localtax2; - $this->line->total_ttc = $total_ttc; - $this->line->special_code = $special_code; - $this->line->fk_parent_line = $fk_parent_line; - $this->line->skip_update_total = $skip_update_total; - $this->line->fk_unit = $fk_unit; + $this->line->remise_percent = $remise_percent; + $this->line->subprice = $pu_ht; + $this->line->info_bits = $info_bits; + + $this->line->total_ht = $total_ht; + $this->line->total_tva = $total_tva; + $this->line->total_localtax1 = $total_localtax1; + $this->line->total_localtax2 = $total_localtax2; + $this->line->total_ttc = $total_ttc; + $this->line->special_code = $special_code; + $this->line->fk_parent_line = $fk_parent_line; + $this->line->skip_update_total = $skip_update_total; + $this->line->fk_unit = $fk_unit; $this->line->fk_fournprice = $fk_fournprice; - $this->line->pa_ht = $pa_ht; + $this->line->pa_ht = $pa_ht; - $this->line->date_start=$date_start; - $this->line->date_end=$date_end; + $this->line->date_start=$date_start; + $this->line->date_end=$date_end; - // TODO deprecated - $this->line->price=$price; - $this->line->remise=$remise; + // TODO deprecated + $this->line->price=$price; + $this->line->remise=$remise; - if (is_array($array_options) && count($array_options)>0) { - $this->line->array_options=$array_options; - } + if (is_array($array_options) && count($array_options)>0) { + $this->line->array_options=$array_options; + } // Multicurrency $this->line->multicurrency_subprice = $pu_ht_devise; $this->line->multicurrency_total_ht = $multicurrency_total_ht; - $this->line->multicurrency_total_tva = $multicurrency_total_tva; - $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; - - $result=$this->line->update($notrigger); - if ($result > 0) - { - // Reorder if child line - if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); - - $this->update_price(1); - - $this->fk_propal = $this->id; - $this->rowid = $rowid; - - $this->db->commit(); - return $result; - } - else - { - $this->error=$this->line->error; - - $this->db->rollback(); - return -1; - } - } - else - { - dol_syslog(get_class($this)."::updateline Erreur -2 Propal en mode incompatible pour cette action"); - return -2; - } - } - - - /** - * Delete detail line - * - * @param int $lineid Id of line to delete - * @return int >0 if OK, <0 if KO - */ - function deleteline($lineid) - { - if ($this->statut == self::STATUS_DRAFT) - { - $line=new PropaleLigne($this->db); - - // For triggers - $line->fetch($lineid); - - if ($line->delete() > 0) - { - $this->update_price(1); - - return 1; - } - else - { - return -1; - } - } - else - { - return -2; - } - } - - - /** - * Create commercial proposal into database - * this->ref can be set or empty. If empty, we will use "(PROVid)" - * - * @param User $user User that create - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >=0 if OK - */ - function create($user, $notrigger=0) - { - global $conf,$hookmanager; - $error=0; - - $now=dol_now(); - - // Clean parameters - if (empty($this->date)) $this->date=$this->datep; - $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600); - if (empty($this->availability_id)) $this->availability_id=0; - if (empty($this->demand_reason_id)) $this->demand_reason_id=0; + $this->line->multicurrency_total_tva = $multicurrency_total_tva; + $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; + + $result=$this->line->update($notrigger); + if ($result > 0) + { + // Reorder if child line + if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); + + $this->update_price(1); + + $this->fk_propal = $this->id; + $this->rowid = $rowid; + + $this->db->commit(); + return $result; + } + else + { + $this->error=$this->line->error; + + $this->db->rollback(); + return -1; + } + } + else + { + dol_syslog(get_class($this)."::updateline Erreur -2 Propal en mode incompatible pour cette action"); + return -2; + } + } + + + /** + * Delete detail line + * + * @param int $lineid Id of line to delete + * @return int >0 if OK, <0 if KO + */ + function deleteline($lineid) + { + if ($this->statut == self::STATUS_DRAFT) + { + $line=new PropaleLigne($this->db); + + // For triggers + $line->fetch($lineid); + + if ($line->delete() > 0) + { + $this->update_price(1); + + return 1; + } + else + { + return -1; + } + } + else + { + return -2; + } + } + + + /** + * Create commercial proposal into database + * this->ref can be set or empty. If empty, we will use "(PROVid)" + * + * @param User $user User that create + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >=0 if OK + */ + function create($user, $notrigger=0) + { + global $conf,$hookmanager; + $error=0; + + $now=dol_now(); + + // Clean parameters + if (empty($this->date)) $this->date=$this->datep; + $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600); + if (empty($this->availability_id)) $this->availability_id=0; + if (empty($this->demand_reason_id)) $this->demand_reason_id=0; // Multicurrency if (!empty($this->multicurrency_code)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $this->date); @@ -840,18 +840,18 @@ class Propal extends CommonObject $this->multicurrency_tx = 1; } - dol_syslog(get_class($this)."::create"); + dol_syslog(get_class($this)."::create"); - // Check parameters - $result=$this->fetch_thirdparty(); - if ($result < 0) - { - $this->error="Failed to fetch company"; - dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); - return -3; - } + // Check parameters + $result=$this->fetch_thirdparty(); + if ($result < 0) + { + $this->error="Failed to fetch company"; + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + return -3; + } - // Check parameters + // Check parameters if (! empty($this->ref)) // We check that ref is not already used { $result=self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used @@ -864,111 +864,111 @@ class Propal extends CommonObject } } - if (empty($this->date)) - { - $this->error="Date of proposal is required"; - dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); - return -4; - } - - - $this->db->begin(); - - // Insert into database - $sql = "INSERT INTO ".MAIN_DB_PREFIX."propal ("; - $sql.= "fk_soc"; - $sql.= ", price"; - $sql.= ", remise"; - $sql.= ", remise_percent"; - $sql.= ", remise_absolue"; - $sql.= ", tva"; - $sql.= ", total"; - $sql.= ", datep"; - $sql.= ", datec"; - $sql.= ", ref"; - $sql.= ", fk_user_author"; - $sql.= ", note_private"; - $sql.= ", note_public"; - $sql.= ", model_pdf"; - $sql.= ", fin_validite"; - $sql.= ", fk_cond_reglement"; - $sql.= ", fk_mode_reglement"; - $sql.= ", fk_account"; - $sql.= ", ref_client"; - $sql.= ", date_livraison"; - $sql.= ", fk_shipping_method"; - $sql.= ", fk_availability"; - $sql.= ", fk_input_reason"; - $sql.= ", fk_projet"; - $sql.= ", fk_incoterms"; - $sql.= ", location_incoterms"; - $sql.= ", entity"; - $sql.= ", fk_multicurrency"; - $sql.= ", multicurrency_code"; - $sql.= ", multicurrency_tx"; - $sql.= ") "; - $sql.= " VALUES ("; - $sql.= $this->socid; - $sql.= ", 0"; - $sql.= ", ".$this->remise; - $sql.= ", ".($this->remise_percent?$this->db->escape($this->remise_percent):'NULL'); - $sql.= ", ".($this->remise_absolue?$this->db->escape($this->remise_absolue):'NULL'); - $sql.= ", 0"; - $sql.= ", 0"; - $sql.= ", '".$this->db->idate($this->date)."'"; - $sql.= ", '".$this->db->idate($now)."'"; - $sql.= ", '(PROV)'"; - $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"NULL"); - $sql.= ", '".$this->db->escape($this->note_private)."'"; - $sql.= ", '".$this->db->escape($this->note_public)."'"; - $sql.= ", '".$this->db->escape($this->modelpdf)."'"; - $sql.= ", ".($this->fin_validite!=''?"'".$this->db->idate($this->fin_validite)."'":"NULL"); - $sql.= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id : 'NULL'); - $sql.= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id : 'NULL'); - $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); - $sql.= ", '".$this->db->escape($this->ref_client)."'"; - $sql.= ", ".($this->date_livraison!=''?"'".$this->db->idate($this->date_livraison)."'":"NULL"); - $sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:'NULL'); - $sql.= ", ".$this->availability_id; - $sql.= ", ".$this->demand_reason_id; - $sql.= ", ".($this->fk_project?$this->fk_project:"null"); - $sql.= ", ".(int) $this->fk_incoterms; - $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; - $sql.= ", ".$conf->entity; + if (empty($this->date)) + { + $this->error="Date of proposal is required"; + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + return -4; + } + + + $this->db->begin(); + + // Insert into database + $sql = "INSERT INTO ".MAIN_DB_PREFIX."propal ("; + $sql.= "fk_soc"; + $sql.= ", price"; + $sql.= ", remise"; + $sql.= ", remise_percent"; + $sql.= ", remise_absolue"; + $sql.= ", tva"; + $sql.= ", total"; + $sql.= ", datep"; + $sql.= ", datec"; + $sql.= ", ref"; + $sql.= ", fk_user_author"; + $sql.= ", note_private"; + $sql.= ", note_public"; + $sql.= ", model_pdf"; + $sql.= ", fin_validite"; + $sql.= ", fk_cond_reglement"; + $sql.= ", fk_mode_reglement"; + $sql.= ", fk_account"; + $sql.= ", ref_client"; + $sql.= ", date_livraison"; + $sql.= ", fk_shipping_method"; + $sql.= ", fk_availability"; + $sql.= ", fk_input_reason"; + $sql.= ", fk_projet"; + $sql.= ", fk_incoterms"; + $sql.= ", location_incoterms"; + $sql.= ", entity"; + $sql.= ", fk_multicurrency"; + $sql.= ", multicurrency_code"; + $sql.= ", multicurrency_tx"; + $sql.= ") "; + $sql.= " VALUES ("; + $sql.= $this->socid; + $sql.= ", 0"; + $sql.= ", ".$this->remise; + $sql.= ", ".($this->remise_percent?$this->db->escape($this->remise_percent):'NULL'); + $sql.= ", ".($this->remise_absolue?$this->db->escape($this->remise_absolue):'NULL'); + $sql.= ", 0"; + $sql.= ", 0"; + $sql.= ", '".$this->db->idate($this->date)."'"; + $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ", '(PROV)'"; + $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"NULL"); + $sql.= ", '".$this->db->escape($this->note_private)."'"; + $sql.= ", '".$this->db->escape($this->note_public)."'"; + $sql.= ", '".$this->db->escape($this->modelpdf)."'"; + $sql.= ", ".($this->fin_validite!=''?"'".$this->db->idate($this->fin_validite)."'":"NULL"); + $sql.= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id : 'NULL'); + $sql.= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id : 'NULL'); + $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); + $sql.= ", '".$this->db->escape($this->ref_client)."'"; + $sql.= ", ".($this->date_livraison!=''?"'".$this->db->idate($this->date_livraison)."'":"NULL"); + $sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:'NULL'); + $sql.= ", ".$this->availability_id; + $sql.= ", ".$this->demand_reason_id; + $sql.= ", ".($this->fk_project?$this->fk_project:"null"); + $sql.= ", ".(int) $this->fk_incoterms; + $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; + $sql.= ", ".$conf->entity; $sql.= ", ".(int) $this->fk_multicurrency; $sql.= ", '".$this->db->escape($this->multicurrency_code)."'"; $sql.= ", ".(double) $this->multicurrency_tx; - $sql.= ")"; + $sql.= ")"; - dol_syslog(get_class($this)."::create", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."propal"); + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."propal"); - if ($this->id) - { - $this->ref='(PROV'.$this->id.')'; - $sql = 'UPDATE '.MAIN_DB_PREFIX."propal SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".$this->id; + if ($this->id) + { + $this->ref='(PROV'.$this->id.')'; + $sql = 'UPDATE '.MAIN_DB_PREFIX."propal SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".$this->id; - dol_syslog(get_class($this)."::create", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $error++; + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $error++; - /* + /* * Insertion du detail des produits dans la base */ - if (! $error) - { - $fk_parent_line=0; - $num=count($this->lines); + if (! $error) + { + $fk_parent_line=0; + $num=count($this->lines); - for ($i=0;$i<$num;$i++) - { - // Reset fk_parent_line for line that are not child lines or special product - if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) { - $fk_parent_line = 0; - } + for ($i=0;$i<$num;$i++) + { + // Reset fk_parent_line for line that are not child lines or special product + if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } $result = $this->addline( $this->lines[$i]->desc, @@ -989,168 +989,168 @@ class Propal extends CommonObject $this->lines[$i]->fk_fournprice, $this->lines[$i]->pa_ht, $this->lines[$i]->label, - $this->lines[$i]->date_start, + $this->lines[$i]->date_start, $this->lines[$i]->date_end, $this->lines[$i]->array_options, $this->lines[$i]->fk_unit, - $this->element, - $this->lines[$i]->id + $this->element, + $this->lines[$i]->id ); - if ($result < 0) - { - $error++; - $this->error=$this->db->error; - dol_print_error($this->db); - break; - } - // Defined the new fk_parent_line - if ($result > 0 && $this->lines[$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - } - - // Add linked object - if (! $error && $this->origin && $this->origin_id) - { - $ret = $this->add_object_linked(); - if (! $ret) dol_print_error($this->db); - } + if ($result < 0) + { + $error++; + $this->error=$this->db->error; + dol_print_error($this->db); + break; + } + // Defined the new fk_parent_line + if ($result > 0 && $this->lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + } - // Set delivery address - if (! $error && $this->fk_delivery_address) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET fk_delivery_address = ".$this->fk_delivery_address; - $sql.= " WHERE ref = '".$this->db->escape($this->ref)."'"; - $sql.= " AND entity = ".$conf->entity; + // Add linked object + if (! $error && $this->origin && $this->origin_id) + { + $ret = $this->add_object_linked(); + if (! $ret) dol_print_error($this->db); + } + + // Set delivery address + if (! $error && $this->fk_delivery_address) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; + $sql.= " SET fk_delivery_address = ".$this->fk_delivery_address; + $sql.= " WHERE ref = '".$this->db->escape($this->ref)."'"; + $sql.= " AND entity = ".$conf->entity; - $result=$this->db->query($sql); - } + $result=$this->db->query($sql); + } - if (! $error) - { - // Mise a jour infos denormalisees - $resql=$this->update_price(1); - if ($resql) - { - $action='update'; - - // Actions on extra fields (by external module or standard code) - // TODO le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('propaldao')); - $parameters=array('socid'=>$this->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; - - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('PROPAL_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - else + if (! $error) + { + // Mise a jour infos denormalisees + $resql=$this->update_price(1); + if ($resql) { - $this->error=$this->db->lasterror(); - $error++; - } - } - } - else - { - $this->error=$this->db->lasterror(); - $error++; - } - - if (! $error) - { - $this->db->commit(); - dol_syslog(get_class($this)."::create done id=".$this->id); - return $this->id; - } - else - { - $this->db->rollback(); - return -2; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - - /** - * Insert into DB a proposal object completely defined by its data members (ex, results from copy). - * - * @param User $user User that create - * @return int Id of the new object if ok, <0 if ko - * @see create - */ - function create_from($user) - { - // i love this function because $this->products is not used in create function... - $this->products=$this->lines; - - return $this->create($user); - } - - /** - * Load an object from its id and create a new one in database - * - * @param int $socid Id of thirdparty - * @return int New id of clone - */ - function createFromClone($socid=0) - { - global $user,$conf,$hookmanager; + $action='update'; + + // Actions on extra fields (by external module or standard code) + // TODO le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('propaldao')); + $parameters=array('socid'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('PROPAL_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + + if (! $error) + { + $this->db->commit(); + dol_syslog(get_class($this)."::create done id=".$this->id); + return $this->id; + } + else + { + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Insert into DB a proposal object completely defined by its data members (ex, results from copy). + * + * @param User $user User that create + * @return int Id of the new object if ok, <0 if ko + * @see create + */ + function create_from($user) + { + // i love this function because $this->products is not used in create function... + $this->products=$this->lines; + + return $this->create($user); + } + + /** + * Load an object from its id and create a new one in database + * + * @param int $socid Id of thirdparty + * @return int New id of clone + */ + function createFromClone($socid=0) + { + global $user,$conf,$hookmanager; dol_include_once('/projet/class/project.class.php'); - $this->context['createfromclone']='createfromclone'; + $this->context['createfromclone']='createfromclone'; - $error=0; - $now=dol_now(); + $error=0; + $now=dol_now(); - $this->db->begin(); + $this->db->begin(); // get extrafields so they will be clone foreach($this->lines as $line) $line->fetch_optionals($line->rowid); - // Load dest object - $clonedObj = clone $this; + // Load dest object + $clonedObj = clone $this; - $objsoc=new Societe($this->db); + $objsoc=new Societe($this->db); - // Change socid if needed - if (! empty($socid) && $socid != $clonedObj->socid) - { - if ($objsoc->fetch($socid) > 0) - { - $clonedObj->socid = $objsoc->id; - $clonedObj->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); - $clonedObj->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); - $clonedObj->fk_delivery_address = ''; + // Change socid if needed + if (! empty($socid) && $socid != $clonedObj->socid) + { + if ($objsoc->fetch($socid) > 0) + { + $clonedObj->socid = $objsoc->id; + $clonedObj->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $clonedObj->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); + $clonedObj->fk_delivery_address = ''; - /*if (!empty($conf->projet->enabled)) + /*if (!empty($conf->projet->enabled)) { $project = new Project($db); if ($this->fk_project > 0 && $project->fetch($this->fk_project)) { @@ -1160,189 +1160,189 @@ class Propal extends CommonObject $clonedObj->fk_project = ''; } }*/ - $clonedObj->fk_project = ''; // A cloned proposal is set by default to no project. - } - - // reset ref_client - $clonedObj->ref_client = ''; - - // TODO Change product price if multi-prices - } - else - { - $objsoc->fetch($clonedObj->socid); - } - - $clonedObj->id=0; - $clonedObj->ref=''; - $clonedObj->statut=self::STATUS_DRAFT; - - // Clear fields - $clonedObj->user_author = $user->id; - $clonedObj->user_valid = ''; - $clonedObj->date = $now; - $clonedObj->datep = $now; // deprecated - $clonedObj->fin_validite = $clonedObj->date + ($clonedObj->duree_validite * 24 * 3600); - if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) $clonedObj->ref_client = ''; - - // Create clone - - $result=$clonedObj->create($user); - if ($result < 0) $error++; - else - { - // copy internal contacts - if ($clonedObj->copy_linked_contact($this, 'internal') < 0) - $error++; + $clonedObj->fk_project = ''; // A cloned proposal is set by default to no project. + } - // copy external contacts if same company - elseif ($this->socid == $clonedObj->socid) - { - if ($clonedObj->copy_linked_contact($this, 'external') < 0) - $error++; - } - } - - if (! $error) - { - // Hook of thirdparty module - if (is_object($hookmanager)) - { - $parameters=array('objFrom'=>$this,'clonedObj'=>$clonedObj); - $action=''; - $reshook=$hookmanager->executeHooks('createFrom',$parameters,$clonedObj,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) $error++; - } - - // Call trigger - $result=$clonedObj->call_trigger('PROPAL_CLONE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - - unset($this->context['createfromclone']); - - // End - if (! $error) - { - $this->db->commit(); - return $clonedObj->id; - } - else - { - $this->db->rollback(); - return -1; - } - } - - /** - * Load a proposal from database and its ligne array - * - * @param int $rowid id of object to load - * @param string $ref Ref of proposal - * @return int >0 if OK, <0 if KO - */ - function fetch($rowid,$ref='') - { - - $sql = "SELECT p.rowid, p.ref, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc"; - $sql.= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht"; - $sql.= ", p.datec"; - $sql.= ", p.date_valid as datev"; - $sql.= ", p.datep as dp"; - $sql.= ", p.fin_validite as dfv"; - $sql.= ", p.date_livraison as date_livraison"; - $sql.= ", p.model_pdf, p.ref_client, p.extraparams"; - $sql.= ", p.note_private, p.note_public"; - $sql.= ", p.fk_projet, p.fk_statut"; - $sql.= ", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture"; - $sql.= ", p.fk_delivery_address"; - $sql.= ", p.fk_availability"; - $sql.= ", p.fk_input_reason"; - $sql.= ", p.fk_cond_reglement"; - $sql.= ", p.fk_mode_reglement"; - $sql.= ', p.fk_account'; - $sql.= ", p.fk_shipping_method"; - $sql.= ", p.fk_incoterms, p.location_incoterms"; - $sql.= ", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc"; - $sql.= ", i.libelle as libelle_incoterms"; - $sql.= ", c.label as statut_label"; - $sql.= ", ca.code as availability_code, ca.label as availability"; - $sql.= ", dr.code as demand_reason_code, dr.label as demand_reason"; - $sql.= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc"; - $sql.= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."propal as p"; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN (' . getEntity('c_paiement').')'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid AND cr.entity IN (' . getEntity('c_payment_term').')'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_availability as ca ON p.fk_availability = ca.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON p.fk_input_reason = dr.rowid'; + // reset ref_client + $clonedObj->ref_client = ''; + + // TODO Change product price if multi-prices + } + else + { + $objsoc->fetch($clonedObj->socid); + } + + $clonedObj->id=0; + $clonedObj->ref=''; + $clonedObj->statut=self::STATUS_DRAFT; + + // Clear fields + $clonedObj->user_author = $user->id; + $clonedObj->user_valid = ''; + $clonedObj->date = $now; + $clonedObj->datep = $now; // deprecated + $clonedObj->fin_validite = $clonedObj->date + ($clonedObj->duree_validite * 24 * 3600); + if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) $clonedObj->ref_client = ''; + + // Create clone + + $result=$clonedObj->create($user); + if ($result < 0) $error++; + else + { + // copy internal contacts + if ($clonedObj->copy_linked_contact($this, 'internal') < 0) + $error++; + + // copy external contacts if same company + elseif ($this->socid == $clonedObj->socid) + { + if ($clonedObj->copy_linked_contact($this, 'external') < 0) + $error++; + } + } + + if (! $error) + { + // Hook of thirdparty module + if (is_object($hookmanager)) + { + $parameters=array('objFrom'=>$this,'clonedObj'=>$clonedObj); + $action=''; + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$clonedObj,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) $error++; + } + + // Call trigger + $result=$clonedObj->call_trigger('PROPAL_CLONE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + unset($this->context['createfromclone']); + + // End + if (! $error) + { + $this->db->commit(); + return $clonedObj->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Load a proposal from database and its ligne array + * + * @param int $rowid id of object to load + * @param string $ref Ref of proposal + * @return int >0 if OK, <0 if KO + */ + function fetch($rowid,$ref='') + { + + $sql = "SELECT p.rowid, p.ref, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc"; + $sql.= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht"; + $sql.= ", p.datec"; + $sql.= ", p.date_valid as datev"; + $sql.= ", p.datep as dp"; + $sql.= ", p.fin_validite as dfv"; + $sql.= ", p.date_livraison as date_livraison"; + $sql.= ", p.model_pdf, p.ref_client, p.extraparams"; + $sql.= ", p.note_private, p.note_public"; + $sql.= ", p.fk_projet, p.fk_statut"; + $sql.= ", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture"; + $sql.= ", p.fk_delivery_address"; + $sql.= ", p.fk_availability"; + $sql.= ", p.fk_input_reason"; + $sql.= ", p.fk_cond_reglement"; + $sql.= ", p.fk_mode_reglement"; + $sql.= ', p.fk_account'; + $sql.= ", p.fk_shipping_method"; + $sql.= ", p.fk_incoterms, p.location_incoterms"; + $sql.= ", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc"; + $sql.= ", i.libelle as libelle_incoterms"; + $sql.= ", c.label as statut_label"; + $sql.= ", ca.code as availability_code, ca.label as availability"; + $sql.= ", dr.code as demand_reason_code, dr.label as demand_reason"; + $sql.= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc"; + $sql.= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."propal as p"; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN (' . getEntity('c_paiement').')'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid AND cr.entity IN (' . getEntity('c_payment_term').')'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_availability as ca ON p.fk_availability = ca.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON p.fk_input_reason = dr.rowid'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON p.fk_incoterms = i.rowid'; - $sql.= " WHERE p.fk_statut = c.id"; - $sql.= " AND p.entity IN (".getEntity('propal').")"; - if ($ref) $sql.= " AND p.ref='".$ref."'"; - else $sql.= " AND p.rowid=".$rowid; - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; - - $this->ref = $obj->ref; - $this->ref_client = $obj->ref_client; - $this->remise = $obj->remise; - $this->remise_percent = $obj->remise_percent; - $this->remise_absolue = $obj->remise_absolue; - $this->total = $obj->total; // TODO deprecated - $this->total_ht = $obj->total_ht; - $this->total_tva = $obj->tva; - $this->total_localtax1 = $obj->localtax1; - $this->total_localtax2 = $obj->localtax2; - $this->total_ttc = $obj->total; - $this->socid = $obj->fk_soc; - $this->fk_project = $obj->fk_projet; - $this->modelpdf = $obj->model_pdf; - $this->note = $obj->note_private; // TODO deprecated - $this->note_private = $obj->note_private; - $this->note_public = $obj->note_public; - $this->statut = (int) $obj->fk_statut; - $this->statut_libelle = $obj->statut_label; - - $this->datec = $this->db->jdate($obj->datec); // TODO deprecated - $this->datev = $this->db->jdate($obj->datev); // TODO deprecated - $this->date_creation = $this->db->jdate($obj->datec); //Creation date - $this->date_validation = $this->db->jdate($obj->datev); //Validation date - $this->date = $this->db->jdate($obj->dp); // Proposal date - $this->datep = $this->db->jdate($obj->dp); // deprecated - $this->fin_validite = $this->db->jdate($obj->dfv); - $this->date_livraison = $this->db->jdate($obj->date_livraison); - $this->shipping_method_id = ($obj->fk_shipping_method>0)?$obj->fk_shipping_method:null; - $this->availability_id = $obj->fk_availability; - $this->availability_code = $obj->availability_code; - $this->availability = $obj->availability; - $this->demand_reason_id = $obj->fk_input_reason; - $this->demand_reason_code = $obj->demand_reason_code; - $this->demand_reason = $obj->demand_reason; - $this->fk_address = $obj->fk_delivery_address; - - $this->mode_reglement_id = $obj->fk_mode_reglement; - $this->mode_reglement_code = $obj->mode_reglement_code; - $this->mode_reglement = $obj->mode_reglement; - $this->fk_account = ($obj->fk_account>0)?$obj->fk_account:null; - $this->cond_reglement_id = $obj->fk_cond_reglement; - $this->cond_reglement_code = $obj->cond_reglement_code; - $this->cond_reglement = $obj->cond_reglement; - $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; - - $this->extraparams = (array) json_decode($obj->extraparams, true); - - $this->user_author_id = $obj->fk_user_author; - $this->user_valid_id = $obj->fk_user_valid; - $this->user_close_id = $obj->fk_user_cloture; + $sql.= " WHERE p.fk_statut = c.id"; + $sql.= " AND p.entity IN (".getEntity('propal').")"; + if ($ref) $sql.= " AND p.ref='".$ref."'"; + else $sql.= " AND p.rowid=".$rowid; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + + $this->ref = $obj->ref; + $this->ref_client = $obj->ref_client; + $this->remise = $obj->remise; + $this->remise_percent = $obj->remise_percent; + $this->remise_absolue = $obj->remise_absolue; + $this->total = $obj->total; // TODO deprecated + $this->total_ht = $obj->total_ht; + $this->total_tva = $obj->tva; + $this->total_localtax1 = $obj->localtax1; + $this->total_localtax2 = $obj->localtax2; + $this->total_ttc = $obj->total; + $this->socid = $obj->fk_soc; + $this->fk_project = $obj->fk_projet; + $this->modelpdf = $obj->model_pdf; + $this->note = $obj->note_private; // TODO deprecated + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->statut = (int) $obj->fk_statut; + $this->statut_libelle = $obj->statut_label; + + $this->datec = $this->db->jdate($obj->datec); // TODO deprecated + $this->datev = $this->db->jdate($obj->datev); // TODO deprecated + $this->date_creation = $this->db->jdate($obj->datec); //Creation date + $this->date_validation = $this->db->jdate($obj->datev); //Validation date + $this->date = $this->db->jdate($obj->dp); // Proposal date + $this->datep = $this->db->jdate($obj->dp); // deprecated + $this->fin_validite = $this->db->jdate($obj->dfv); + $this->date_livraison = $this->db->jdate($obj->date_livraison); + $this->shipping_method_id = ($obj->fk_shipping_method>0)?$obj->fk_shipping_method:null; + $this->availability_id = $obj->fk_availability; + $this->availability_code = $obj->availability_code; + $this->availability = $obj->availability; + $this->demand_reason_id = $obj->fk_input_reason; + $this->demand_reason_code = $obj->demand_reason_code; + $this->demand_reason = $obj->demand_reason; + $this->fk_address = $obj->fk_delivery_address; + + $this->mode_reglement_id = $obj->fk_mode_reglement; + $this->mode_reglement_code = $obj->mode_reglement_code; + $this->mode_reglement = $obj->mode_reglement; + $this->fk_account = ($obj->fk_account>0)?$obj->fk_account:null; + $this->cond_reglement_id = $obj->fk_cond_reglement; + $this->cond_reglement_code = $obj->cond_reglement_code; + $this->cond_reglement = $obj->cond_reglement; + $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + + $this->extraparams = (array) json_decode($obj->extraparams, true); + + $this->user_author_id = $obj->fk_user_author; + $this->user_valid_id = $obj->fk_user_valid; + $this->user_close_id = $obj->fk_user_cloture; //Incoterms $this->fk_incoterms = $obj->fk_incoterms; @@ -1357,43 +1357,43 @@ class Propal extends CommonObject $this->multicurrency_total_tva = $obj->multicurrency_total_tva; $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc; - if ($obj->fk_statut == self::STATUS_DRAFT) - { - $this->brouillon = 1; - } + if ($obj->fk_statut == self::STATUS_DRAFT) + { + $this->brouillon = 1; + } - // Retreive all extrafield for invoice - // fetch optionals attributes and labels - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields=new ExtraFields($this->db); - $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); - $this->fetch_optionals($this->id,$extralabels); + // Retreive all extrafield for invoice + // fetch optionals attributes and labels + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); - $this->db->free($resql); + $this->db->free($resql); - $this->lines = array(); + $this->lines = array(); - /* + /* * Lines */ - $result=$this->fetch_lines(); - if ($result < 0) - { - return -3; - } + $result=$this->fetch_lines(); + if ($result < 0) + { + return -3; + } - return 1; - } + return 1; + } - $this->error="Record Not Found"; - return 0; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } + $this->error="Record Not Found"; + return 0; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } /** * Load array lines @@ -1494,1947 +1494,1947 @@ class Propal extends CommonObject $i++; } - $this->db->free($result); + $this->db->free($result); + + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -3; + } + } + + /** + * Update value of extrafields on the proposal + * + * @param User $user Object user that modify + * @return int <0 if ko, >0 if ok + */ + function update_extrafields($user) + { + global $conf, $hookmanager; + + $action='update'; + $error = 0; + + // Actions on extra fields (by external module or standard code) + // TODO le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('propaldao')); + $parameters=array('id'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + if (!$error) + { + return 1; + } + else + { + return -1; + } + + } + + /** + * Set status to validated + * + * @param User $user Object user that validate + * @param int $notrigger 1=Does not execute triggers, 0=execute triggers + * @return int <0 if KO, 0=Nothing done, >=0 if OK + */ + function valid($user, $notrigger=0) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + global $conf; + + $error=0; + + // Protection + if ($this->statut == self::STATUS_VALIDATED) + { + dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING); + return 0; + } + + if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate)))) + { + $this->error='ErrorPermissionDenied'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + } + + $now=dol_now(); + + $this->db->begin(); + + // Numbering module definition + $soc = new Societe($this->db); + $soc->fetch($this->socid); + + // Define new ref + if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef($soc); + } + else + { + $num = $this->ref; + } + $this->newref = $num; + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; + $sql.= " SET ref = '".$num."',"; + $sql.= " fk_statut = ".self::STATUS_VALIDATED.", date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; + + dol_syslog(get_class($this)."::valid", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + dol_print_error($this->db); + $error++; + } + + // Trigger calls + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('PROPAL_VALIDATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (! $error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // Rename of propal directory ($this->ref = old ref, $num = new ref) + // to not lose the linked files + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->propal->dir_output.'/'.$oldref; + $dirdest = $conf->propal->dir_output.'/'.$newref; + + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->propal->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + + $this->ref=$num; + $this->brouillon=0; + $this->statut = self::STATUS_VALIDATED; + $this->user_valid_id=$user->id; + $this->datev=$now; + + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + + /** + * Define proposal date + * + * @param User $user Object user that modify + * @param int $date Date + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function set_date($user, $date, $notrigger=0) + { + if (empty($date)) + { + $this->error='ErrorBadParameter'; + dol_syslog(get_class($this)."::set_date ".$this->error, LOG_ERR); + return -1; + } + + if (! empty($user->rights->propal->creer)) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET datep = '".$this->db->idate($date)."'"; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->date = $date; + $this->datep = $date; // deprecated + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + } + + /** + * Define end validity date + * + * @param User $user Object user that modify + * @param int $date_fin_validite End of validity date + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function set_echeance($user, $date_fin_validite, $notrigger=0) + { + if (! empty($user->rights->propal->creer)) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fin_validite = ".($date_fin_validite!=''?"'".$this->db->idate($date_fin_validite)."'":'null'); + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + + if (! $error) + { + $this->oldcopy= clone $this; + $this->fin_validite = $date_fin_validite; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + } + + /** + * Set delivery date + * + * @param User $user Object user that modify + * @param int $date_livraison Delivery date + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if ko, >0 if ok + */ + function set_date_livraison($user, $date_livraison, $notrigger=0) + { + if (! empty($user->rights->propal->creer)) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; + $sql.= " SET date_livraison = ".($date_livraison!=''?"'".$this->db->idate($date_livraison)."'":'null'); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->date_livraison = $date_livraison; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + } + + /** + * Set delivery + * + * @param User $user Object user that modify + * @param int $id Availability id + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function set_availability($user, $id, $notrigger=0) + { + if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; + $sql.= " SET fk_availability = '".$id."'"; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(__METHOD__.' availability('.$availability_id.')', LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->fk_availability = $id; + $this->availability_id = $id; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + else + { + $error_str='Propal status do not meet requirement '.$this->statut; + dol_syslog(__METHOD__.$error_str, LOG_ERR); + $this->error=$error_str; + $this->errors[]= $this->error; + return -2; + } + } + + /** + * Set source of demand + * + * @param User $user Object user that modify + * @param int $id Input reason id + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function set_demand_reason($user, $id, $notrigger=0) + { + if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; + $sql.= " SET fk_input_reason = ".$id; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + + if (! $error) + { + $this->oldcopy= clone $this; + $this->fk_input_reason = $id; + $this->demand_reason_id = $id; + } + + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + else + { + $error_str='Propal status do not meet requirement '.$this->statut; + dol_syslog(__METHOD__.$error_str, LOG_ERR); + $this->error=$error_str; + $this->errors[]= $this->error; + return -2; + } + } + + /** + * Set customer reference number + * + * @param User $user Object user that modify + * @param string $ref_client Customer reference + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if ko, >0 if ok + */ + function set_ref_client($user, $ref_client, $notrigger=0) + { + if (! empty($user->rights->propal->creer)) + { + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal SET ref_client = '.(empty($ref_client) ? 'NULL' : '\''.$this->db->escape($ref_client).'\''); + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->ref_client = $ref_client; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + else + { + return -1; + } + } + + /** + * Set an overall discount on the proposal + * + * @param User $user Object user that modify + * @param double $remise Amount discount + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if ko, >0 if ok + */ + function set_remise_percent($user, $remise, $notrigger=0) + { + $remise=trim($remise)?trim($remise):0; + + if (! empty($user->rights->propal->creer)) + { + $remise = price2num($remise); + + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET remise_percent = ".$remise; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->remise_percent = $remise; + $this->update_price(1); + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + } + + + /** + * Set an absolute overall discount on the proposal + * + * @param User $user Object user that modify + * @param double $remise Amount discount + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if ko, >0 if ok + */ + function set_remise_absolue($user, $remise, $notrigger=0) + { + $remise=trim($remise)?trim($remise):0; + + if (! empty($user->rights->propal->creer)) + { + $remise = price2num($remise); + + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; + $sql.= " SET remise_absolue = ".$remise; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->remise_absolue = $remise; + $this->update_price(1); + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + } + + + + /** + * Reopen the commercial proposal + * + * @param User $user Object user that close + * @param int $statut Statut + * @param string $note Comment + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function reopen($user, $statut, $note='', $notrigger=0) + { + + $this->statut = $statut; + $error=0; + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; + $sql.= " SET fk_statut = ".$this->statut.","; + if (! empty($note)) $sql.= " note_private = '".$this->db->escape($note)."',"; + $sql.= " date_cloture=NULL, fk_user_cloture=NULL"; + $sql.= " WHERE rowid = ".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::reopen", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('PROPAL_REOPEN',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + if (!empty($this->errors)) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Close the commercial proposal + * + * @param User $user Object user that close + * @param int $statut Statut + * @param string $note Comment + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function cloture($user, $statut, $note, $notrigger=0) + { + global $langs,$conf; + + $error=0; + $now=dol_now(); + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; + $sql.= " SET fk_statut = ".$statut.", note_private = '".$this->db->escape($note)."', date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id; + $sql.= " WHERE rowid = ".$this->id; + + $resql=$this->db->query($sql); + if ($resql) + { + $modelpdf=$conf->global->PROPALE_ADDON_PDF_ODT_CLOSED?$conf->global->PROPALE_ADDON_PDF_ODT_CLOSED:$this->modelpdf; + $trigger_name='PROPAL_CLOSE_REFUSED'; + + if ($statut == self::STATUS_SIGNED) + { + $trigger_name='PROPAL_CLOSE_SIGNED'; + $modelpdf=$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL?$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL:$this->modelpdf; + + // The connected company is classified as a client + $soc=new Societe($this->db); + $soc->id = $this->socid; + $result=$soc->set_as_client(); + + if ($result < 0) + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -2; + } + } + if ($statut == self::STATUS_BILLED) + { + $trigger_name='PROPAL_CLASSIFY_BILLED'; + } + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $this->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + //$ret=$object->fetch($id); // Reload to get new records + $this->generateDocument($modelpdf, $outputlangs); + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->statut = $statut; + $this->date_cloture = $now; + $this->note_private = $note; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger($trigger_name,$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if ( ! $error ) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + /** + * Class invoiced the Propal + * + * @param User $user Object user + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 si ko, >0 si ok + */ + function classifyBilled(User $user, $notrigger=0) + { + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal SET fk_statut = '.self::STATUS_BILLED; + $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->statut=self::STATUS_BILLED; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + + /** + * Class invoiced the Propal + * + * @return int <0 si ko, >0 si ok + * @deprecated + * @see classifyBilled() + */ + function classer_facturee() + { + global $user; + dol_syslog(__METHOD__ . " is deprecated", LOG_WARNING); + + return $this->classifyBilled($user); + } + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function set_draft($user, $notrigger=0) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_statut = ".self::STATUS_DRAFT; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->statut = self::STATUS_DRAFT; + $this->brouillon = 1; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + + + /** + * Return list of proposal (eventually filtered on user) into an array + * + * @param int $shortlist 0=Return array[id]=ref, 1=Return array[](id=>id,ref=>ref,name=>name) + * @param int $draft 0=not draft, 1=draft + * @param int $notcurrentuser 0=all user, 1=not current user + * @param int $socid Id third pary + * @param int $limit For pagination + * @param int $offset For pagination + * @param string $sortfield Sort criteria + * @param string $sortorder Sort order + * @return int -1 if KO, array with result if OK + */ + function liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datep', $sortorder='DESC') + { + global $user; + + $ga = array(); + + $sql = "SELECT s.rowid, s.nom as name, s.client,"; + $sql.= " p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, "; + $sql.= " p.datep as dp, p.fin_validite as datelimite"; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p, ".MAIN_DB_PREFIX."c_propalst as c"; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE p.entity IN (".getEntity('propal').")"; + $sql.= " AND p.fk_soc = s.rowid"; + $sql.= " AND p.fk_statut = c.id"; + if (! $user->rights->societe->client->voir && ! $socid) //restriction + { + $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if ($socid) $sql.= " AND s.rowid = ".$socid; + if ($draft) $sql.= " AND p.fk_statut = ".self::STATUS_DRAFT; + if ($notcurrentuser > 0) $sql.= " AND p.fk_user_author <> ".$user->id; + $sql.= $this->db->order($sortfield,$sortorder); + $sql.= $this->db->plimit($limit,$offset); + + $result=$this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + if ($num) + { + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + + if ($shortlist == 1) + { + $ga[$obj->propalid] = $obj->ref; + } + else if ($shortlist == 2) + { + $ga[$obj->propalid] = $obj->ref.' ('.$obj->name.')'; + } + else + { + $ga[$i]['id'] = $obj->propalid; + $ga[$i]['ref'] = $obj->ref; + $ga[$i]['name'] = $obj->name; + } + + $i++; + } + } + return $ga; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Returns an array with the numbers of related invoices + * + * @return array Array of invoices + */ + function getInvoiceArrayList() + { + return $this->InvoiceArrayList($this->id); + } + + /** + * Returns an array with id and ref of related invoices + * + * @param int $id Id propal + * @return array Array of invoices id + */ + function InvoiceArrayList($id) + { + $ga = array(); + $linkedInvoices = array(); + + $this->fetchObjectLinked($id,$this->element); + foreach($this->linkedObjectsIds as $objecttype => $objectid) + { + // Nouveau système du comon object renvoi des rowid et non un id linéaire de 1 à n + // On parcourt donc une liste d'objets en tant qu'objet unique + foreach($objectid as $key => $object) + { + // Cas des factures liees directement + if ($objecttype == 'facture') + { + $linkedInvoices[] = $object; + } + // Cas des factures liees par un autre objet (ex: commande) + else + { + $this->fetchObjectLinked($object,$objecttype); + foreach($this->linkedObjectsIds as $subobjecttype => $subobjectid) + { + foreach($subobjectid as $subkey => $subobject) + { + if ($subobjecttype == 'facture') + { + $linkedInvoices[] = $subobject; + } + } + } + } + } + } + + if (count($linkedInvoices) > 0) + { + $sql= "SELECT rowid as facid, facnumber, total, datef as df, fk_user_author, fk_statut, paye"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture"; + $sql.= " WHERE rowid IN (".implode(',',$linkedInvoices).")"; + + dol_syslog(get_class($this)."::InvoiceArrayList", LOG_DEBUG); + $resql=$this->db->query($sql); + + if ($resql) + { + $tab_sqlobj=array(); + $nump = $this->db->num_rows($resql); + for ($i = 0;$i < $nump;$i++) + { + $sqlobj = $this->db->fetch_object($resql); + $tab_sqlobj[] = $sqlobj; + } + $this->db->free($resql); + + $nump = count($tab_sqlobj); + + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = array_shift($tab_sqlobj); + + $ga[$i] = $obj; + + $i++; + } + } + return $ga; + } + else + { + return -1; + } + } + else return $ga; + } + + /** + * Delete proposal + * + * @param User $user Object user that delete + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int 1 if ok, otherwise if error + */ + function delete($user, $notrigger=0) + { + global $conf; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error=0; + + $this->db->begin(); + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('PROPAL_DELETE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE fk_propal = ".$this->id; + if ($this->db->query($sql)) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."propal WHERE rowid = ".$this->id; + if ($this->db->query($sql)) + { + // Delete linked object + $res = $this->deleteObjectLinked(); + if ($res < 0) $error++; + + // Delete linked contacts + $res = $this->delete_linked_contact(); + if ($res < 0) $error++; + + if (! $error) + { + // We remove directory + $ref = dol_sanitizeFileName($this->ref); + if ($conf->propal->dir_output && !empty($this->ref)) + { + $dir = $conf->propal->dir_output . "/" . $ref ; + $file = $dir . "/" . $ref . ".pdf"; + if (file_exists($file)) + { + dol_delete_preview($this); + + if (! dol_delete_file($file,0,0,0,$this)) // For triggers + { + $this->error='ErrorFailToDeleteFile'; + $this->errors=array('ErrorFailToDeleteFile'); + $this->db->rollback(); + return 0; + } + } + if (file_exists($dir)) + { + $res=@dol_delete_dir_recursive($dir); + if (! $res) + { + $this->error='ErrorFailToDeleteDir'; + $this->errors=array('ErrorFailToDeleteDir'); + $this->db->rollback(); + return 0; + } + } + } + } + + // Removed extrafields + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + $errorflag=-4; + dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); + } + } + } + + if (! $error) + { + dol_syslog(get_class($this)."::delete ".$this->id." by ".$user->id, LOG_DEBUG); + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return 0; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -3; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Change the delivery time + * + * @param int $availability_id Id of new delivery time + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int >0 if OK, <0 if KO + * @deprecated use set_availability + */ + function availability($availability_id, $notrigger=0) + { + global $user; + + if ($this->statut >= self::STATUS_DRAFT) + { + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal'; + $sql .= ' SET fk_availability = '.$availability_id; + $sql .= ' WHERE rowid='.$this->id; + + dol_syslog(__METHOD__.' availability('.$availability_id.')', LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->availability_id = $availability_id; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + else + { + $error_str='Propal status do not meet requirement '.$this->statut; + dol_syslog(__METHOD__.$error_str, LOG_ERR); + $this->error=$error_str; + $this->errors[]= $this->error; + return -2; + } + } + + /** + * Change source demand + * + * @param int $demand_reason_id Id of new source demand + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int >0 si ok, <0 si ko + * @deprecated use set_demand_reason + */ + function demand_reason($demand_reason_id, $notrigger=0) + { + if ($this->statut >= self::STATUS_DRAFT) + { + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal'; + $sql .= ' SET fk_input_reason = '.$demand_reason_id; + $sql .= ' WHERE rowid='.$this->id; + + dol_syslog(__METHOD__.' demand_reason('.$demand_reason_id.')', LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->demand_reason_id = $demand_reason_id; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('PROPAL_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + else + { + $error_str='Propal status do not meet requirement '.$this->statut; + dol_syslog(__METHOD__.$error_str, LOG_ERR); + $this->error=$error_str; + $this->errors[]= $this->error; + return -2; + } + } + + + /** + * Object Proposal Information + * + * @param int $id Proposal id + * @return void + */ + function info($id) + { + $sql = "SELECT c.rowid, "; + $sql.= " c.datec, c.date_valid as datev, c.date_cloture as dateo,"; + $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_cloture"; + $sql.= " FROM ".MAIN_DB_PREFIX."propal as c"; + $sql.= " WHERE c.rowid = ".$id; + + $result = $this->db->query($sql); + + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + + $this->id = $obj->rowid; + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_validation = $this->db->jdate($obj->datev); + $this->date_cloture = $this->db->jdate($obj->dateo); + + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) + { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + + } + $this->db->free($result); + + } + else + { + dol_print_error($this->db); + } + } + + + /** + * Return label of status of proposal (draft, validated, ...) + * + * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto + * @return string Label + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut, $mode); + } + + /** + * Return label of a status (draft, validated, ...) + * + * @param int $statut id statut + * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label + */ + function LibStatut($statut,$mode=1) + { + global $langs; + $langs->load("propal"); + + if ($statut==self::STATUS_DRAFT) $statuttrans='statut0'; + if ($statut==self::STATUS_VALIDATED) $statuttrans='statut1'; + if ($statut==self::STATUS_SIGNED) $statuttrans='statut3'; + if ($statut==self::STATUS_NOTSIGNED) $statuttrans='statut5'; + if ($statut==self::STATUS_BILLED) $statuttrans='statut6'; + + if ($mode == 0) return $this->labelstatut[$statut]; + if ($mode == 1) return $this->labelstatut_short[$statut]; + if ($mode == 2) return img_picto($this->labelstatut_short[$statut], $statuttrans).' '.$this->labelstatut_short[$statut]; + if ($mode == 3) return img_picto($this->labelstatut[$statut], $statuttrans); + if ($mode == 4) return img_picto($this->labelstatut[$statut],$statuttrans).' '.$this->labelstatut[$statut]; + if ($mode == 5) return '<span class="hideonsmartphone">'.$this->labelstatut_short[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans); + if ($mode == 6) return '<span class="hideonsmartphone">'.$this->labelstatut[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans); + } + + + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Object user + * @param int $mode "opened" for proposal to close, "signed" for proposal to invoice + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK + */ + function load_board($user,$mode) + { + global $conf, $langs; + + $clause = " WHERE"; + + $sql = "SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin"; + $sql.= " FROM ".MAIN_DB_PREFIX."propal as p"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = " AND"; + } + $sql.= $clause." p.entity IN (".getEntity('propal').")"; + if ($mode == 'opened') $sql.= " AND p.fk_statut = ".self::STATUS_VALIDATED; + if ($mode == 'signed') $sql.= " AND p.fk_statut = ".self::STATUS_SIGNED; + if ($user->societe_id) $sql.= " AND p.fk_soc = ".$user->societe_id; + + $resql=$this->db->query($sql); + if ($resql) + { + $langs->load("propal"); + $now=dol_now(); + + if ($mode == 'opened') { + $delay_warning=$conf->propal->cloture->warning_delay; + $statut = self::STATUS_VALIDATED; + $label = $langs->trans("PropalsToClose"); + } + if ($mode == 'signed') { + $delay_warning=$conf->propal->facturation->warning_delay; + $statut = self::STATUS_SIGNED; + $label = $langs->trans("PropalsToBill"); // We set here bill but may be billed or ordered + } + + $response = new WorkboardResponse(); + $response->warning_delay = $delay_warning/60/60/24; + $response->label = $label; + $response->url = DOL_URL_ROOT.'/comm/propal/list.php?viewstatut='.$statut.'&mainmenu=commercial&leftmenu=propals'; + $response->url_late = DOL_URL_ROOT.'/comm/propal/list.php?viewstatut='.$statut.'&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc'; + $response->img = img_object('',"propal"); + + // This assignment in condition is not a bug. It allows walking the results. + while ($obj=$this->db->fetch_object($resql)) + { + $response->nbtodo++; + if ($mode == 'opened') + { + $datelimit = $this->db->jdate($obj->datefin); + if ($datelimit < ($now - $delay_warning)) + { + $response->nbtodolate++; + } + } + // TODO Definir regle des propales a facturer en retard + // if ($mode == 'signed' && ! count($this->FactureListeArray($obj->rowid))) $this->nbtodolate++; + } + + return $response; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $langs; + + // Load array of products prodids + $num_prods = 0; + $prodids = array(); + $sql = "SELECT rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE entity IN (".getEntity('product').")"; + $resql = $this->db->query($sql); + if ($resql) + { + $num_prods = $this->db->num_rows($resql); + $i = 0; + while ($i < $num_prods) + { + $i++; + $row = $this->db->fetch_row($resql); + $prodids[$i] = $row[0]; + } + } + + // Initialise parametres + $this->id=0; + $this->ref = 'SPECIMEN'; + $this->ref_client='NEMICEPS'; + $this->specimen=1; + $this->socid = 1; + $this->date = time(); + $this->fin_validite = $this->date+3600*24*30; + $this->cond_reglement_id = 1; + $this->cond_reglement_code = 'RECEP'; + $this->mode_reglement_id = 7; + $this->mode_reglement_code = 'CHQ'; + $this->availability_id = 1; + $this->availability_code = 'AV_NOW'; + $this->demand_reason_id = 1; + $this->demand_reason_code = 'SRC_00'; + $this->note_public='This is a comment (public)'; + $this->note_private='This is a comment (private)'; + // Lines + $nbp = 5; + $xnbp = 0; + while ($xnbp < $nbp) + { + $line=new PropaleLigne($this->db); + $line->desc=$langs->trans("Description")." ".$xnbp; + $line->qty=1; + $line->subprice=100; + $line->price=100; + $line->tva_tx=20; + $line->localtax1_tx=0; + $line->localtax2_tx=0; + if ($xnbp == 2) + { + $line->total_ht=50; + $line->total_ttc=60; + $line->total_tva=10; + $line->remise_percent=50; + } + else + { + $line->total_ht=100; + $line->total_ttc=120; + $line->total_tva=20; + $line->remise_percent=00; + } + + if ($num_prods > 0) + { + $prodid = mt_rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + $line->product_ref='SPECIMEN'; + } + + $this->lines[$xnbp]=$line; + + $this->total_ht += $line->total_ht; + $this->total_tva += $line->total_tva; + $this->total_ttc += $line->total_ttc; + + $xnbp++; + } + } + + /** + * Charge indicateurs this->nb de tableau de bord + * + * @return int <0 if ko, >0 if ok + */ + function load_state_board() + { + global $user; + + $this->nb=array(); + $clause = "WHERE"; + + $sql = "SELECT count(p.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."propal as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = "AND"; + } + $sql.= " ".$clause." p.entity IN (".getEntity('propal').")"; + $resql=$this->db->query($sql); + if ($resql) + { + // This assignment in condition is not a bug. It allows walking the results. + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["proposals"]=$obj->nb; + } + $this->db->free($resql); return 1; } else { - $this->error=$this->db->lasterror(); - return -3; + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; } } - /** - * Update value of extrafields on the proposal - * - * @param User $user Object user that modify - * @return int <0 if ko, >0 if ok - */ - function update_extrafields($user) - { - global $conf, $hookmanager; - - $action='update'; - $error = 0; - - // Actions on extra fields (by external module or standard code) - // TODO le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('propaldao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; - if (!$error) - { - return 1; - } - else - { - return -1; - } - - } - - /** - * Set status to validated - * - * @param User $user Object user that validate - * @param int $notrigger 1=Does not execute triggers, 0=execute triggers - * @return int <0 if KO, 0=Nothing done, >=0 if OK - */ - function valid($user, $notrigger=0) - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - global $conf; - - $error=0; - - // Protection - if ($this->statut == self::STATUS_VALIDATED) - { - dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING); - return 0; - } - - if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate)))) - { - $this->error='ErrorPermissionDenied'; - dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); - return -1; - } - - $now=dol_now(); - - $this->db->begin(); - - // Numbering module definition - $soc = new Societe($this->db); - $soc->fetch($this->socid); - - // Define new ref - if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life - { - $num = $this->getNextNumRef($soc); - } - else - { - $num = $this->ref; - } - $this->newref = $num; - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET ref = '".$num."',"; - $sql.= " fk_statut = ".self::STATUS_VALIDATED.", date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; - - dol_syslog(get_class($this)."::valid", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - dol_print_error($this->db); - $error++; - } + /** + * Returns the reference to the following non used Proposal used depending on the active numbering module + * defined into PROPALE_ADDON + * + * @param Societe $soc Object thirdparty + * @return string Reference libre pour la propale + */ + function getNextNumRef($soc) + { + global $conf,$langs; + $langs->load("propal"); - // Trigger calls - if (! $error && ! $notrigger) + if (! empty($conf->global->PROPALE_ADDON)) { - // Call trigger - $result=$this->call_trigger('PROPAL_VALIDATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - - if (! $error) - { - $this->oldref = $this->ref; - - // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - // Rename of propal directory ($this->ref = old ref, $num = new ref) - // to not lose the linked files - $oldref = dol_sanitizeFileName($this->ref); - $newref = dol_sanitizeFileName($num); - $dirsource = $conf->propal->dir_output.'/'.$oldref; - $dirdest = $conf->propal->dir_output.'/'.$newref; - - if (file_exists($dirsource)) - { - dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); - if (@rename($dirsource, $dirdest)) - { - dol_syslog("Rename ok"); - // Rename docs starting with $oldref with $newref - $listoffiles=dol_dir_list($conf->propal->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); - foreach($listoffiles as $fileentry) - { - $dirsource=$fileentry['name']; - $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); - $dirsource=$fileentry['path'].'/'.$dirsource; - $dirdest=$fileentry['path'].'/'.$dirdest; - @rename($dirsource, $dirdest); - } - } - } - } - - $this->ref=$num; - $this->brouillon=0; - $this->statut = self::STATUS_VALIDATED; - $this->user_valid_id=$user->id; - $this->datev=$now; - - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - - - /** - * Define proposal date - * - * @param User $user Object user that modify - * @param int $date Date - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function set_date($user, $date, $notrigger=0) - { - if (empty($date)) - { - $this->error='ErrorBadParameter'; - dol_syslog(get_class($this)."::set_date ".$this->error, LOG_ERR); - return -1; - } - - if (! empty($user->rights->propal->creer)) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET datep = '".$this->db->idate($date)."'"; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->date = $date; - $this->datep = $date; // deprecated - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - } - - /** - * Define end validity date - * - * @param User $user Object user that modify - * @param int $date_fin_validite End of validity date - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function set_echeance($user, $date_fin_validite, $notrigger=0) - { - if (! empty($user->rights->propal->creer)) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fin_validite = ".($date_fin_validite!=''?"'".$this->db->idate($date_fin_validite)."'":'null'); - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - - if (! $error) - { - $this->oldcopy= clone $this; - $this->fin_validite = $date_fin_validite; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - } - - /** - * Set delivery date - * - * @param User $user Object user that modify - * @param int $date_livraison Delivery date - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if ko, >0 if ok - */ - function set_date_livraison($user, $date_livraison, $notrigger=0) - { - if (! empty($user->rights->propal->creer)) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; - $sql.= " SET date_livraison = ".($date_livraison!=''?"'".$this->db->idate($date_livraison)."'":'null'); - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->date_livraison = $date_livraison; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - } - - /** - * Set delivery - * - * @param User $user Object user that modify - * @param int $id Availability id - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function set_availability($user, $id, $notrigger=0) - { - if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; - $sql.= " SET fk_availability = '".$id."'"; - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(__METHOD__.' availability('.$availability_id.')', LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->fk_availability = $id; - $this->availability_id = $id; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - else - { - $error_str='Propal status do not meet requirement '.$this->statut; - dol_syslog(__METHOD__.$error_str, LOG_ERR); - $this->error=$error_str; - $this->errors[]= $this->error; - return -2; - } - } - - /** - * Set source of demand - * - * @param User $user Object user that modify - * @param int $id Input reason id - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function set_demand_reason($user, $id, $notrigger=0) - { - if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; - $sql.= " SET fk_input_reason = ".$id; - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - - if (! $error) - { - $this->oldcopy= clone $this; - $this->fk_input_reason = $id; - $this->demand_reason_id = $id; - } - - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - else - { - $error_str='Propal status do not meet requirement '.$this->statut; - dol_syslog(__METHOD__.$error_str, LOG_ERR); - $this->error=$error_str; - $this->errors[]= $this->error; - return -2; - } - } - - /** - * Set customer reference number - * - * @param User $user Object user that modify - * @param string $ref_client Customer reference - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if ko, >0 if ok - */ - function set_ref_client($user, $ref_client, $notrigger=0) - { - if (! empty($user->rights->propal->creer)) - { - $error=0; - - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal SET ref_client = '.(empty($ref_client) ? 'NULL' : '\''.$this->db->escape($ref_client).'\''); - $sql.= ' WHERE rowid = '.$this->id; - - dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->ref_client = $ref_client; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - else - { - return -1; - } - } - - /** - * Set an overall discount on the proposal - * - * @param User $user Object user that modify - * @param double $remise Amount discount - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if ko, >0 if ok - */ - function set_remise_percent($user, $remise, $notrigger=0) - { - $remise=trim($remise)?trim($remise):0; - - if (! empty($user->rights->propal->creer)) - { - $remise = price2num($remise); - - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET remise_percent = ".$remise; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->remise_percent = $remise; - $this->update_price(1); - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - } - - - /** - * Set an absolute overall discount on the proposal - * - * @param User $user Object user that modify - * @param double $remise Amount discount - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if ko, >0 if ok - */ - function set_remise_absolue($user, $remise, $notrigger=0) - { - $remise=trim($remise)?trim($remise):0; - - if (! empty($user->rights->propal->creer)) - { - $remise = price2num($remise); - - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; - $sql.= " SET remise_absolue = ".$remise; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->remise_absolue = $remise; - $this->update_price(1); - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - } - - - - /** - * Reopen the commercial proposal - * - * @param User $user Object user that close - * @param int $statut Statut - * @param string $note Comment - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function reopen($user, $statut, $note='', $notrigger=0) - { - - $this->statut = $statut; - $error=0; - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET fk_statut = ".$this->statut.","; - if (! empty($note)) $sql.= " note_private = '".$this->db->escape($note)."',"; - $sql.= " date_cloture=NULL, fk_user_cloture=NULL"; - $sql.= " WHERE rowid = ".$this->id; + $mybool=false; - $this->db->begin(); + $file = $conf->global->PROPALE_ADDON.".php"; + $classname = $conf->global->PROPALE_ADDON; - dol_syslog(get_class($this)."::reopen", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { - $error++; $this->errors[]="Error ".$this->db->lasterror(); - } - if (! $error) - { - if (! $notrigger) + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/propale/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) { - // Call trigger - $result=$this->call_trigger('PROPAL_REOPEN',$user); - if ($result < 0) { $error++; } - // End call triggers + dol_print_error('',"Failed to include file ".$file); + return ''; } - } - // Commit or rollback - if ($error) - { - if (!empty($this->errors)) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - } - $this->db->rollback(); - return -1*$error; + $obj = new $classname(); + $numref = ""; + $numref = $obj->getNextValue($soc,$this); + + if ($numref != "") + { + return $numref; + } + else + { + $this->error=$obj->error; + //dol_print_error($db,"Propale::getNextNumRef ".$obj->error); + return ""; + } } else { - $this->db->commit(); - return 1; + $langs->load("errors"); + print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); + return ""; } - } - - - /** - * Close the commercial proposal - * - * @param User $user Object user that close - * @param int $statut Statut - * @param string $note Comment - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function cloture($user, $statut, $note, $notrigger=0) - { - global $langs,$conf; + } - $error=0; - $now=dol_now(); + /** + * Return clicable link of object (with eventually picto) + * + * @param int $withpicto Add picto into link + * @param string $option Where point the link ('expedition', 'document', ...) + * @param string $get_params Parametres added to url + * @param int $notooltip 1=Disable tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + function getNomUrl($withpicto=0, $option='', $get_params='', $notooltip=0, $save_lastsearch_value=-1) + { + global $langs, $conf, $user; - $this->db->begin(); + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips - $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET fk_statut = ".$statut.", note_private = '".$this->db->escape($note)."', date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id; - $sql.= " WHERE rowid = ".$this->id; + $result=''; + $label=''; + $url=''; - $resql=$this->db->query($sql); - if ($resql) - { - $modelpdf=$conf->global->PROPALE_ADDON_PDF_ODT_CLOSED?$conf->global->PROPALE_ADDON_PDF_ODT_CLOSED:$this->modelpdf; - $trigger_name='PROPAL_CLOSE_REFUSED'; + if ($user->rights->propal->lire) + { + $label = '<u>' . $langs->trans("ShowPropal") . '</u>'; + if (! empty($this->ref)) + $label.= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref; + if (! empty($this->ref_client)) + $label.= '<br><b>'.$langs->trans('RefCustomer').':</b> '.$this->ref_client; + if (! empty($this->total_ht)) + $label.= '<br><b>' . $langs->trans('AmountHT') . ':</b> ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_tva)) + $label.= '<br><b>' . $langs->trans('VAT') . ':</b> ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_ttc)) + $label.= '<br><b>' . $langs->trans('AmountTTC') . ':</b> ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + if ($option == '') { + $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$this->id. $get_params; + } + if ($option == 'compta') { // deprecated + $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$this->id. $get_params; + } + if ($option == 'expedition') { + $url = DOL_URL_ROOT.'/expedition/propal.php?id='.$this->id. $get_params; + } + if ($option == 'document') { + $url = DOL_URL_ROOT.'/comm/propal/document.php?id='.$this->id. $get_params; + } - if ($statut == self::STATUS_SIGNED) - { - $trigger_name='PROPAL_CLOSE_SIGNED'; - $modelpdf=$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL?$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL:$this->modelpdf; + if ($option != 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; + if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; + } + } - // The connected company is classified as a client - $soc=new Societe($this->db); - $soc->id = $this->socid; - $result=$soc->set_as_client(); + $linkclose=''; + if (empty($notooltip) && $user->rights->propal->lire) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowPropal"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; + } - if ($result < 0) - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -2; - } - } - if ($statut == self::STATUS_BILLED) - { - $trigger_name='PROPAL_CLASSIFY_BILLED'; - } - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $this->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - //$ret=$object->fetch($id); // Reload to get new records - $this->generateDocument($modelpdf, $outputlangs); - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->statut = $statut; - $this->date_cloture = $now; - $this->note_private = $note; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger($trigger_name,$user); - if ($result < 0) { $error++; } - // End call triggers - } - - if ( ! $error ) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Class invoiced the Propal - * - * @param User $user Object user - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 si ko, >0 si ok - */ - function classifyBilled(User $user, $notrigger=0) - { - $error=0; - - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal SET fk_statut = '.self::STATUS_BILLED; - $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->statut=self::STATUS_BILLED; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - - /** - * Class invoiced the Propal - * - * @return int <0 si ko, >0 si ok - * @deprecated - * @see classifyBilled() - */ - function classer_facturee() - { - global $user; - dol_syslog(__METHOD__ . " is deprecated", LOG_WARNING); + $linkstart = '<a href="'.$url.'"'; + $linkstart.=$linkclose.'>'; + $linkend='</a>'; - return $this->classifyBilled($user); - } - - /** - * Set draft status - * - * @param User $user Object user that modify - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function set_draft($user, $notrigger=0) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_statut = ".self::STATUS_DRAFT; - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->statut = self::STATUS_DRAFT; - $this->brouillon = 1; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - - - /** - * Return list of proposal (eventually filtered on user) into an array - * - * @param int $shortlist 0=Return array[id]=ref, 1=Return array[](id=>id,ref=>ref,name=>name) - * @param int $draft 0=not draft, 1=draft - * @param int $notcurrentuser 0=all user, 1=not current user - * @param int $socid Id third pary - * @param int $limit For pagination - * @param int $offset For pagination - * @param string $sortfield Sort criteria - * @param string $sortorder Sort order - * @return int -1 if KO, array with result if OK - */ - function liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datep', $sortorder='DESC') - { - global $user; - - $ga = array(); - - $sql = "SELECT s.rowid, s.nom as name, s.client,"; - $sql.= " p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, "; - $sql.= " p.datep as dp, p.fin_validite as datelimite"; - if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p, ".MAIN_DB_PREFIX."c_propalst as c"; - if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE p.entity IN (".getEntity('propal').")"; - $sql.= " AND p.fk_soc = s.rowid"; - $sql.= " AND p.fk_statut = c.id"; - if (! $user->rights->societe->client->voir && ! $socid) //restriction - { - $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - } - if ($socid) $sql.= " AND s.rowid = ".$socid; - if ($draft) $sql.= " AND p.fk_statut = ".self::STATUS_DRAFT; - if ($notcurrentuser > 0) $sql.= " AND p.fk_user_author <> ".$user->id; - $sql.= $this->db->order($sortfield,$sortorder); - $sql.= $this->db->plimit($limit,$offset); - - $result=$this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - if ($num) - { - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($result); - - if ($shortlist == 1) - { - $ga[$obj->propalid] = $obj->ref; - } - else if ($shortlist == 2) - { - $ga[$obj->propalid] = $obj->ref.' ('.$obj->name.')'; - } - else - { - $ga[$i]['id'] = $obj->propalid; - $ga[$i]['ref'] = $obj->ref; - $ga[$i]['name'] = $obj->name; - } - - $i++; - } - } - return $ga; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Returns an array with the numbers of related invoices - * - * @return array Array of invoices - */ - function getInvoiceArrayList() - { - return $this->InvoiceArrayList($this->id); - } - - /** - * Returns an array with id and ref of related invoices - * - * @param int $id Id propal - * @return array Array of invoices id - */ - function InvoiceArrayList($id) - { - $ga = array(); - $linkedInvoices = array(); - - $this->fetchObjectLinked($id,$this->element); - foreach($this->linkedObjectsIds as $objecttype => $objectid) - { - // Nouveau système du comon object renvoi des rowid et non un id linéaire de 1 à n - // On parcourt donc une liste d'objets en tant qu'objet unique - foreach($objectid as $key => $object) - { - // Cas des factures liees directement - if ($objecttype == 'facture') - { - $linkedInvoices[] = $object; - } - // Cas des factures liees par un autre objet (ex: commande) - else - { - $this->fetchObjectLinked($object,$objecttype); - foreach($this->linkedObjectsIds as $subobjecttype => $subobjectid) - { - foreach($subobjectid as $subkey => $subobject) - { - if ($subobjecttype == 'facture') - { - $linkedInvoices[] = $subobject; - } - } - } - } - } - } - - if (count($linkedInvoices) > 0) - { - $sql= "SELECT rowid as facid, facnumber, total, datef as df, fk_user_author, fk_statut, paye"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture"; - $sql.= " WHERE rowid IN (".implode(',',$linkedInvoices).")"; - - dol_syslog(get_class($this)."::InvoiceArrayList", LOG_DEBUG); - $resql=$this->db->query($sql); - - if ($resql) - { - $tab_sqlobj=array(); - $nump = $this->db->num_rows($resql); - for ($i = 0;$i < $nump;$i++) - { - $sqlobj = $this->db->fetch_object($resql); - $tab_sqlobj[] = $sqlobj; - } - $this->db->free($resql); + if ($withpicto) + $result.=($linkstart.img_object(($notooltip?'':$label), $this->picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); + if ($withpicto && $withpicto != 2) + $result.=' '; + $result.=$linkstart.$this->ref.$linkend; + return $result; + } - $nump = count($tab_sqlobj); + /** + * Retrieve an array of propal lines + * + * @return int >0 if OK, <0 if KO + */ + function getLinesArray() + { + // TODO Duplicate with fetch_lines ? Wich one to keep ? - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = array_shift($tab_sqlobj); - - $ga[$i] = $obj; - - $i++; - } - } - return $ga; - } - else - { - return -1; - } - } - else return $ga; - } - - /** - * Delete proposal - * - * @param User $user Object user that delete - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int 1 if ok, otherwise if error - */ - function delete($user, $notrigger=0) - { - global $conf; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $error=0; - - $this->db->begin(); - - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('PROPAL_DELETE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE fk_propal = ".$this->id; - if ($this->db->query($sql)) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."propal WHERE rowid = ".$this->id; - if ($this->db->query($sql)) - { - // Delete linked object - $res = $this->deleteObjectLinked(); - if ($res < 0) $error++; - - // Delete linked contacts - $res = $this->delete_linked_contact(); - if ($res < 0) $error++; - - if (! $error) - { - // We remove directory - $ref = dol_sanitizeFileName($this->ref); - if ($conf->propal->dir_output && !empty($this->ref)) - { - $dir = $conf->propal->dir_output . "/" . $ref ; - $file = $dir . "/" . $ref . ".pdf"; - if (file_exists($file)) - { - dol_delete_preview($this); - - if (! dol_delete_file($file,0,0,0,$this)) // For triggers - { - $this->error='ErrorFailToDeleteFile'; - $this->errors=array('ErrorFailToDeleteFile'); - $this->db->rollback(); - return 0; - } - } - if (file_exists($dir)) - { - $res=@dol_delete_dir_recursive($dir); - if (! $res) - { - $this->error='ErrorFailToDeleteDir'; - $this->errors=array('ErrorFailToDeleteDir'); - $this->db->rollback(); - return 0; - } - } - } - } - - // Removed extrafields - if (! $error) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $error++; - $errorflag=-4; - dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); - } - } - } - - if (! $error) - { - dol_syslog(get_class($this)."::delete ".$this->id." by ".$user->id, LOG_DEBUG); - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return 0; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -3; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -2; - } - } - else - { - $this->db->rollback(); - return -1; - } - } - - /** - * Change the delivery time - * - * @param int $availability_id Id of new delivery time - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int >0 if OK, <0 if KO - * @deprecated use set_availability - */ - function availability($availability_id, $notrigger=0) - { - global $user; - - if ($this->statut >= self::STATUS_DRAFT) - { - $error=0; - - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal'; - $sql .= ' SET fk_availability = '.$availability_id; - $sql .= ' WHERE rowid='.$this->id; - - dol_syslog(__METHOD__.' availability('.$availability_id.')', LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->availability_id = $availability_id; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - else - { - $error_str='Propal status do not meet requirement '.$this->statut; - dol_syslog(__METHOD__.$error_str, LOG_ERR); - $this->error=$error_str; - $this->errors[]= $this->error; - return -2; - } - } - - /** - * Change source demand - * - * @param int $demand_reason_id Id of new source demand - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int >0 si ok, <0 si ko - * @deprecated use set_demand_reason - */ - function demand_reason($demand_reason_id, $notrigger=0) - { - if ($this->statut >= self::STATUS_DRAFT) - { - $error=0; - - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal'; - $sql .= ' SET fk_input_reason = '.$demand_reason_id; - $sql .= ' WHERE rowid='.$this->id; - - dol_syslog(__METHOD__.' demand_reason('.$demand_reason_id.')', LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->demand_reason_id = $demand_reason_id; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('PROPAL_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - else - { - $error_str='Propal status do not meet requirement '.$this->statut; - dol_syslog(__METHOD__.$error_str, LOG_ERR); - $this->error=$error_str; - $this->errors[]= $this->error; - return -2; - } - } - - - /** - * Object Proposal Information - * - * @param int $id Proposal id - * @return void - */ - function info($id) - { - $sql = "SELECT c.rowid, "; - $sql.= " c.datec, c.date_valid as datev, c.date_cloture as dateo,"; - $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_cloture"; - $sql.= " FROM ".MAIN_DB_PREFIX."propal as c"; - $sql.= " WHERE c.rowid = ".$id; - - $result = $this->db->query($sql); - - if ($result) - { - if ($this->db->num_rows($result)) - { - $obj = $this->db->fetch_object($result); - - $this->id = $obj->rowid; - - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_validation = $this->db->jdate($obj->datev); - $this->date_cloture = $this->db->jdate($obj->dateo); - - $cuser = new User($this->db); - $cuser->fetch($obj->fk_user_author); - $this->user_creation = $cuser; - - if ($obj->fk_user_valid) - { - $vuser = new User($this->db); - $vuser->fetch($obj->fk_user_valid); - $this->user_validation = $vuser; - } + $this->lines = array(); - if ($obj->fk_user_cloture) - { - $cluser = new User($this->db); - $cluser->fetch($obj->fk_user_cloture); - $this->user_cloture = $cluser; - } - - - } - $this->db->free($result); - - } - else - { - dol_print_error($this->db); - } - } - - - /** - * Return label of status of proposal (draft, validated, ...) - * - * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto - * @return string Label - */ - function getLibStatut($mode=0) - { - return $this->LibStatut($this->statut, $mode); - } - - /** - * Return label of a status (draft, validated, ...) - * - * @param int $statut id statut - * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto, 6=Long label + Picto - * @return string Label - */ - function LibStatut($statut,$mode=1) - { - global $langs; - $langs->load("propal"); + $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,'; + $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.localtax1_type, pt.localtax2_type, pt.remise_percent, pt.subprice, pt.info_bits,'; + $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,'; + $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; + $sql.= ' pt.fk_unit,'; + $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,'; + $sql.= ' p.entity,'; + $sql.= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as pt'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pt.fk_product=p.rowid'; + $sql.= ' WHERE pt.fk_propal = '.$this->id; + $sql.= ' ORDER BY pt.rang ASC, pt.rowid'; - if ($statut==self::STATUS_DRAFT) $statuttrans='statut0'; - if ($statut==self::STATUS_VALIDATED) $statuttrans='statut1'; - if ($statut==self::STATUS_SIGNED) $statuttrans='statut3'; - if ($statut==self::STATUS_NOTSIGNED) $statuttrans='statut5'; - if ($statut==self::STATUS_BILLED) $statuttrans='statut6'; + dol_syslog(get_class($this).'::getLinesArray', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; - if ($mode == 0) return $this->labelstatut[$statut]; - if ($mode == 1) return $this->labelstatut_short[$statut]; - if ($mode == 2) return img_picto($this->labelstatut_short[$statut], $statuttrans).' '.$this->labelstatut_short[$statut]; - if ($mode == 3) return img_picto($this->labelstatut[$statut], $statuttrans); - if ($mode == 4) return img_picto($this->labelstatut[$statut],$statuttrans).' '.$this->labelstatut[$statut]; - if ($mode == 5) return '<span class="hideonsmartphone">'.$this->labelstatut_short[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans); - if ($mode == 6) return '<span class="hideonsmartphone">'.$this->labelstatut[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans); - } - - - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * - * @param User $user Object user - * @param int $mode "opened" for proposal to close, "signed" for proposal to invoice - * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK - */ - function load_board($user,$mode) - { - global $conf, $langs; - - $clause = " WHERE"; - - $sql = "SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin"; - $sql.= " FROM ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = " AND"; - } - $sql.= $clause." p.entity IN (".getEntity('propal').")"; - if ($mode == 'opened') $sql.= " AND p.fk_statut = ".self::STATUS_VALIDATED; - if ($mode == 'signed') $sql.= " AND p.fk_statut = ".self::STATUS_SIGNED; - if ($user->societe_id) $sql.= " AND p.fk_soc = ".$user->societe_id; - - $resql=$this->db->query($sql); - if ($resql) - { - $langs->load("propal"); - $now=dol_now(); - - if ($mode == 'opened') { - $delay_warning=$conf->propal->cloture->warning_delay; - $statut = self::STATUS_VALIDATED; - $label = $langs->trans("PropalsToClose"); - } - if ($mode == 'signed') { - $delay_warning=$conf->propal->facturation->warning_delay; - $statut = self::STATUS_SIGNED; - $label = $langs->trans("PropalsToBill"); // We set here bill but may be billed or ordered - } - - $response = new WorkboardResponse(); - $response->warning_delay = $delay_warning/60/60/24; - $response->label = $label; - $response->url = DOL_URL_ROOT.'/comm/propal/list.php?viewstatut='.$statut.'&mainmenu=commercial&leftmenu=propals'; - $response->url_late = DOL_URL_ROOT.'/comm/propal/list.php?viewstatut='.$statut.'&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc'; - $response->img = img_object('',"propal"); - - // This assignment in condition is not a bug. It allows walking the results. - while ($obj=$this->db->fetch_object($resql)) - { - $response->nbtodo++; - if ($mode == 'opened') - { - $datelimit = $this->db->jdate($obj->datefin); - if ($datelimit < ($now - $delay_warning)) - { - $response->nbtodolate++; - } - } - // TODO Definir regle des propales a facturer en retard - // if ($mode == 'signed' && ! count($this->FactureListeArray($obj->rowid))) $this->nbtodolate++; - } - - return $response; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } - - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - function initAsSpecimen() - { - global $langs; - - // Load array of products prodids - $num_prods = 0; - $prodids = array(); - $sql = "SELECT rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."product"; - $sql.= " WHERE entity IN (".getEntity('product').")"; - $resql = $this->db->query($sql); - if ($resql) - { - $num_prods = $this->db->num_rows($resql); - $i = 0; - while ($i < $num_prods) - { - $i++; - $row = $this->db->fetch_row($resql); - $prodids[$i] = $row[0]; - } - } - - // Initialise parametres - $this->id=0; - $this->ref = 'SPECIMEN'; - $this->ref_client='NEMICEPS'; - $this->specimen=1; - $this->socid = 1; - $this->date = time(); - $this->fin_validite = $this->date+3600*24*30; - $this->cond_reglement_id = 1; - $this->cond_reglement_code = 'RECEP'; - $this->mode_reglement_id = 7; - $this->mode_reglement_code = 'CHQ'; - $this->availability_id = 1; - $this->availability_code = 'AV_NOW'; - $this->demand_reason_id = 1; - $this->demand_reason_code = 'SRC_00'; - $this->note_public='This is a comment (public)'; - $this->note_private='This is a comment (private)'; - // Lines - $nbp = 5; - $xnbp = 0; - while ($xnbp < $nbp) - { - $line=new PropaleLigne($this->db); - $line->desc=$langs->trans("Description")." ".$xnbp; - $line->qty=1; - $line->subprice=100; - $line->price=100; - $line->tva_tx=20; - $line->localtax1_tx=0; - $line->localtax2_tx=0; - if ($xnbp == 2) - { - $line->total_ht=50; - $line->total_ttc=60; - $line->total_tva=10; - $line->remise_percent=50; - } - else - { - $line->total_ht=100; - $line->total_ttc=120; - $line->total_tva=20; - $line->remise_percent=00; - } - - if ($num_prods > 0) - { - $prodid = mt_rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; - $line->product_ref='SPECIMEN'; - } - - $this->lines[$xnbp]=$line; - - $this->total_ht += $line->total_ht; - $this->total_tva += $line->total_tva; - $this->total_ttc += $line->total_ttc; - - $xnbp++; - } - } - - /** - * Charge indicateurs this->nb de tableau de bord - * - * @return int <0 if ko, >0 if ok - */ - function load_state_board() - { - global $user; - - $this->nb=array(); - $clause = "WHERE"; - - $sql = "SELECT count(p.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."propal as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = "AND"; - } - $sql.= " ".$clause." p.entity IN (".getEntity('propal').")"; - - $resql=$this->db->query($sql); - if ($resql) - { - // This assignment in condition is not a bug. It allows walking the results. - while ($obj=$this->db->fetch_object($resql)) - { - $this->nb["proposals"]=$obj->nb; - } - $this->db->free($resql); - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } - - - /** - * Returns the reference to the following non used Proposal used depending on the active numbering module - * defined into PROPALE_ADDON - * - * @param Societe $soc Object thirdparty - * @return string Reference libre pour la propale - */ - function getNextNumRef($soc) - { - global $conf,$langs; - $langs->load("propal"); - - if (! empty($conf->global->PROPALE_ADDON)) - { - $mybool=false; - - $file = $conf->global->PROPALE_ADDON.".php"; - $classname = $conf->global->PROPALE_ADDON; - - // Include file with class - $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) { - - $dir = dol_buildpath($reldir."core/modules/propale/"); - - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } - - if (! $mybool) - { - dol_print_error('',"Failed to include file ".$file); - return ''; - } - - $obj = new $classname(); - $numref = ""; - $numref = $obj->getNextValue($soc,$this); - - if ($numref != "") - { - return $numref; - } - else - { - $this->error=$obj->error; - //dol_print_error($db,"Propale::getNextNumRef ".$obj->error); - return ""; - } - } - else - { - $langs->load("errors"); - print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); - return ""; - } - } - - /** - * Return clicable link of object (with eventually picto) - * - * @param int $withpicto Add picto into link - * @param string $option Where point the link ('expedition', 'document', ...) - * @param string $get_params Parametres added to url - * @param int $notooltip 1=Disable tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string String with URL - */ - function getNomUrl($withpicto=0, $option='', $get_params='', $notooltip=0, $save_lastsearch_value=-1) - { - global $langs, $conf, $user; - - if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips - - $result=''; - $label=''; - $url=''; - - if ($user->rights->propal->lire) - { - $label = '<u>' . $langs->trans("ShowPropal") . '</u>'; - if (! empty($this->ref)) - $label.= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref; - if (! empty($this->ref_client)) - $label.= '<br><b>'.$langs->trans('RefCustomer').':</b> '.$this->ref_client; - if (! empty($this->total_ht)) - $label.= '<br><b>' . $langs->trans('AmountHT') . ':</b> ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_tva)) - $label.= '<br><b>' . $langs->trans('VAT') . ':</b> ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_ttc)) - $label.= '<br><b>' . $langs->trans('AmountTTC') . ':</b> ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - if ($option == '') { - $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$this->id. $get_params; - } - if ($option == 'compta') { // deprecated - $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$this->id. $get_params; - } - if ($option == 'expedition') { - $url = DOL_URL_ROOT.'/expedition/propal.php?id='.$this->id. $get_params; - } - if ($option == 'document') { - $url = DOL_URL_ROOT.'/comm/propal/document.php?id='.$this->id. $get_params; - } - - if ($option != 'nolink') - { - // Add param to save lastsearch_values or not - $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; - if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; - } - } - - $linkclose=''; - if (empty($notooltip) && $user->rights->propal->lire) - { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label=$langs->trans("ShowPropal"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip"'; - } - - $linkstart = '<a href="'.$url.'"'; - $linkstart.=$linkclose.'>'; - $linkend='</a>'; - - if ($withpicto) - $result.=($linkstart.img_object(($notooltip?'':$label), $this->picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); - if ($withpicto && $withpicto != 2) - $result.=' '; - $result.=$linkstart.$this->ref.$linkend; - return $result; - } - - /** - * Retrieve an array of propal lines - * - * @return int >0 if OK, <0 if KO - */ - function getLinesArray() - { - // TODO Duplicate with fetch_lines ? Wich one to keep ? - - $this->lines = array(); - - $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,'; - $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.localtax1_type, pt.localtax2_type, pt.remise_percent, pt.subprice, pt.info_bits,'; - $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,'; - $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; - $sql.= ' pt.fk_unit,'; - $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,'; - $sql.= ' p.entity,'; - $sql.= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as pt'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pt.fk_product=p.rowid'; - $sql.= ' WHERE pt.fk_propal = '.$this->id; - $sql.= ' ORDER BY pt.rang ASC, pt.rowid'; - - dol_syslog(get_class($this).'::getLinesArray', LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - - $this->lines[$i] = new PropaleLigne($this->db); - $this->lines[$i]->id = $obj->rowid; // for backward compatibility - $this->lines[$i]->rowid = $obj->rowid; - $this->lines[$i]->label = $obj->custom_label; - $this->lines[$i]->desc = $obj->description; - $this->lines[$i]->description = $obj->description; - $this->lines[$i]->fk_product = $obj->fk_product; - $this->lines[$i]->ref = $obj->ref; - $this->lines[$i]->product_ref = $obj->ref; - $this->lines[$i]->entity = $obj->entity; // Product entity - $this->lines[$i]->product_label = $obj->product_label; - $this->lines[$i]->product_desc = $obj->product_desc; - $this->lines[$i]->product_tobatch = $obj->product_tobatch; - $this->lines[$i]->fk_product_type = $obj->fk_product_type; // deprecated - $this->lines[$i]->product_type = $obj->product_type; - $this->lines[$i]->qty = $obj->qty; - $this->lines[$i]->subprice = $obj->subprice; - $this->lines[$i]->fk_remise_except = $obj->fk_remise_except; - $this->lines[$i]->remise_percent = $obj->remise_percent; - - $this->lines[$i]->vat_src_code = $obj->vat_src_code; - $this->lines[$i]->tva_tx = $obj->tva_tx; - $this->lines[$i]->localtax1_tx = $obj->localtax1_tx; - $this->lines[$i]->localtax2_tx = $obj->localtax2_tx; - $this->lines[$i]->localtax1_type = $obj->localtax1_type; - $this->lines[$i]->localtax2_type = $obj->localtax2_type; - $this->lines[$i]->info_bits = $obj->info_bits; - $this->lines[$i]->total_ht = $obj->total_ht; - $this->lines[$i]->total_tva = $obj->total_tva; - $this->lines[$i]->total_ttc = $obj->total_ttc; - $this->lines[$i]->total_localtax1 = $obj->total_localtax1; - $this->lines[$i]->total_localtax2 = $obj->total_localtax2; - $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + $this->lines[$i] = new PropaleLigne($this->db); + $this->lines[$i]->id = $obj->rowid; // for backward compatibility + $this->lines[$i]->rowid = $obj->rowid; + $this->lines[$i]->label = $obj->custom_label; + $this->lines[$i]->desc = $obj->description; + $this->lines[$i]->description = $obj->description; + $this->lines[$i]->fk_product = $obj->fk_product; + $this->lines[$i]->ref = $obj->ref; + $this->lines[$i]->product_ref = $obj->ref; + $this->lines[$i]->entity = $obj->entity; // Product entity + $this->lines[$i]->product_label = $obj->product_label; + $this->lines[$i]->product_desc = $obj->product_desc; + $this->lines[$i]->product_tobatch = $obj->product_tobatch; + $this->lines[$i]->fk_product_type = $obj->fk_product_type; // deprecated + $this->lines[$i]->product_type = $obj->product_type; + $this->lines[$i]->qty = $obj->qty; + $this->lines[$i]->subprice = $obj->subprice; + $this->lines[$i]->fk_remise_except = $obj->fk_remise_except; + $this->lines[$i]->remise_percent = $obj->remise_percent; + + $this->lines[$i]->vat_src_code = $obj->vat_src_code; + $this->lines[$i]->tva_tx = $obj->tva_tx; + $this->lines[$i]->localtax1_tx = $obj->localtax1_tx; + $this->lines[$i]->localtax2_tx = $obj->localtax2_tx; + $this->lines[$i]->localtax1_type = $obj->localtax1_type; + $this->lines[$i]->localtax2_type = $obj->localtax2_type; + $this->lines[$i]->info_bits = $obj->info_bits; + $this->lines[$i]->total_ht = $obj->total_ht; + $this->lines[$i]->total_tva = $obj->total_tva; + $this->lines[$i]->total_ttc = $obj->total_ttc; + $this->lines[$i]->total_localtax1 = $obj->total_localtax1; + $this->lines[$i]->total_localtax2 = $obj->total_localtax2; + $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht); $this->lines[$i]->pa_ht = $marginInfos[0]; $this->lines[$i]->marge_tx = $marginInfos[1]; $this->lines[$i]->marque_tx = $marginInfos[2]; $this->lines[$i]->fk_parent_line = $obj->fk_parent_line; - $this->lines[$i]->special_code = $obj->special_code; - $this->lines[$i]->rang = $obj->rang; - $this->lines[$i]->date_start = $this->db->jdate($obj->date_start); - $this->lines[$i]->date_end = $this->db->jdate($obj->date_end); - $this->lines[$i]->fk_unit = $obj->fk_unit; + $this->lines[$i]->special_code = $obj->special_code; + $this->lines[$i]->rang = $obj->rang; + $this->lines[$i]->date_start = $this->db->jdate($obj->date_start); + $this->lines[$i]->date_end = $this->db->jdate($obj->date_end); + $this->lines[$i]->fk_unit = $obj->fk_unit; // Multicurrency $this->lines[$i]->fk_multicurrency = $obj->fk_multicurrency; @@ -3444,18 +3444,18 @@ class Propal extends CommonObject $this->lines[$i]->multicurrency_total_tva = $obj->multicurrency_total_tva; $this->lines[$i]->multicurrency_total_ttc = $obj->multicurrency_total_ttc; - $i++; - } - $this->db->free($resql); + $i++; + } + $this->db->free($resql); - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } /** * Create a document onto disk according to template module. @@ -3513,16 +3513,16 @@ class Propal extends CommonObject */ class PropaleLigne extends CommonObjectLine { - public $element='propaldet'; - public $table_element='propaldet'; + public $element='propaldet'; + public $table_element='propaldet'; - var $oldline; + var $oldline; - // From llx_propaldet - var $fk_propal; - var $fk_parent_line; - var $desc; // Description ligne - var $fk_product; // Id produit predefini + // From llx_propaldet + var $fk_propal; + var $fk_parent_line; + var $desc; // Description ligne + var $fk_product; // Id produit predefini /** * @deprecated * @see product_type @@ -3533,51 +3533,51 @@ class PropaleLigne extends CommonObjectLine * @var int * @see Product::TYPE_PRODUCT, Product::TYPE_SERVICE */ - var $product_type = Product::TYPE_PRODUCT; + var $product_type = Product::TYPE_PRODUCT; - var $qty; - var $tva_tx; - var $subprice; - var $remise_percent; - var $fk_remise_except; + var $qty; + var $tva_tx; + var $subprice; + var $remise_percent; + var $fk_remise_except; - var $rang = 0; + var $rang = 0; var $fk_fournprice; var $pa_ht; var $marge_tx; var $marque_tx; - var $special_code; // Tag for special lines (exlusive tags) - // 1: frais de port - // 2: ecotaxe - // 3: option line (when qty = 0) + var $special_code; // Tag for special lines (exlusive tags) + // 1: frais de port + // 2: ecotaxe + // 3: option line (when qty = 0) - var $info_bits = 0; // Liste d'options cumulables: - // Bit 0: 0 si TVA normal - 1 si TVA NPR - // Bit 1: 0 ligne normale - 1 si ligne de remise fixe + var $info_bits = 0; // Liste d'options cumulables: + // Bit 0: 0 si TVA normal - 1 si TVA NPR + // Bit 1: 0 ligne normale - 1 si ligne de remise fixe - var $total_ht; // Total HT de la ligne toute quantite et incluant la remise ligne - var $total_tva; // Total TVA de la ligne toute quantite et incluant la remise ligne - var $total_ttc; // Total TTC de la ligne toute quantite et incluant la remise ligne + var $total_ht; // Total HT de la ligne toute quantite et incluant la remise ligne + var $total_tva; // Total TVA de la ligne toute quantite et incluant la remise ligne + var $total_ttc; // Total TTC de la ligne toute quantite et incluant la remise ligne /** * @deprecated * @see $remise_percent, $fk_remise_except */ - var $remise; + var $remise; /** * @deprecated * @see subprice */ - var $price; + var $price; - // From llx_product + // From llx_product /** * @deprecated * @see product_ref */ - var $ref; + var $ref; /** * Product reference * @var string @@ -3587,7 +3587,7 @@ class PropaleLigne extends CommonObjectLine * @deprecated * @see product_label */ - var $libelle; + var $libelle; /** * Product label * @var string @@ -3597,21 +3597,21 @@ class PropaleLigne extends CommonObjectLine * Product description * @var string */ - public $product_desc; + public $product_desc; - var $localtax1_tx; // Local tax 1 - var $localtax2_tx; // Local tax 2 - var $localtax1_type; // Local tax 1 type + var $localtax1_tx; // Local tax 1 + var $localtax2_tx; // Local tax 2 + var $localtax1_type; // Local tax 1 type var $localtax2_type; // Local tax 2 type - var $total_localtax1; // Line total local tax 1 - var $total_localtax2; // Line total local tax 2 + var $total_localtax1; // Line total local tax 1 + var $total_localtax2; // Line total local tax 2 - var $date_start; - var $date_end; + var $date_start; + var $date_end; - var $skip_update_total; // Skip update price total for special lines + var $skip_update_total; // Skip update price total for special lines - // Multicurrency + // Multicurrency var $fk_multicurrency; var $multicurrency_code; var $multicurrency_subprice; @@ -3619,22 +3619,22 @@ class PropaleLigne extends CommonObjectLine var $multicurrency_total_tva; var $multicurrency_total_ttc; - /** - * Class line Contructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db= $db; - } - - /** - * Retrieve the propal line object - * - * @param int $rowid Propal line id - * @return int <0 if KO, >0 if OK - */ + /** + * Class line Contructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db= $db; + } + + /** + * Retrieve the propal line object + * + * @param int $rowid Propal line id + * @return int <0 if KO, >0 if OK + */ function fetch($rowid) { $sql = 'SELECT pd.rowid, pd.fk_propal, pd.fk_parent_line, pd.fk_product, pd.label as custom_label, pd.description, pd.price, pd.qty, pd.vat_src_code, pd.tva_tx,'; @@ -3696,7 +3696,7 @@ class PropaleLigne extends CommonObjectLine $this->fk_unit = $objp->fk_unit; $this->date_start = $this->db->jdate($objp->date_start); - $this->date_end = $this->db->jdate($objp->date_end); + $this->date_end = $this->db->jdate($objp->date_end); // Multicurrency $this->fk_multicurrency = $objp->fk_multicurrency; @@ -3708,7 +3708,7 @@ class PropaleLigne extends CommonObjectLine $this->db->free($result); - return 1; + return 1; } else { @@ -3721,45 +3721,45 @@ class PropaleLigne extends CommonObjectLine } } - /** - * Insert object line propal in database - * - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function insert($notrigger=0) - { - global $conf,$user; + /** + * Insert object line propal in database + * + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function insert($notrigger=0) + { + global $conf,$user; - $error=0; + $error=0; - dol_syslog(get_class($this)."::insert rang=".$this->rang); + dol_syslog(get_class($this)."::insert rang=".$this->rang); - $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'. + $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'. - // Clean parameters - if (empty($this->tva_tx)) $this->tva_tx=0; - if (empty($this->localtax1_tx)) $this->localtax1_tx=0; - if (empty($this->localtax2_tx)) $this->localtax2_tx=0; - if (empty($this->localtax1_type)) $this->localtax1_type=0; + // Clean parameters + if (empty($this->tva_tx)) $this->tva_tx=0; + if (empty($this->localtax1_tx)) $this->localtax1_tx=0; + if (empty($this->localtax2_tx)) $this->localtax2_tx=0; + if (empty($this->localtax1_type)) $this->localtax1_type=0; if (empty($this->localtax2_type)) $this->localtax2_type=0; - if (empty($this->total_localtax1)) $this->total_localtax1=0; - if (empty($this->total_localtax2)) $this->total_localtax2=0; - if (empty($this->rang)) $this->rang=0; - if (empty($this->remise)) $this->remise=0; - if (empty($this->remise_percent) || ! is_numeric($this->remise_percent)) $this->remise_percent=0; - if (empty($this->info_bits)) $this->info_bits=0; - if (empty($this->special_code)) $this->special_code=0; - if (empty($this->fk_parent_line)) $this->fk_parent_line=0; - if (empty($this->fk_fournprice)) $this->fk_fournprice=0; + if (empty($this->total_localtax1)) $this->total_localtax1=0; + if (empty($this->total_localtax2)) $this->total_localtax2=0; + if (empty($this->rang)) $this->rang=0; + if (empty($this->remise)) $this->remise=0; + if (empty($this->remise_percent) || ! is_numeric($this->remise_percent)) $this->remise_percent=0; + if (empty($this->info_bits)) $this->info_bits=0; + if (empty($this->special_code)) $this->special_code=0; + if (empty($this->fk_parent_line)) $this->fk_parent_line=0; + if (empty($this->fk_fournprice)) $this->fk_fournprice=0; if (! is_numeric($this->qty)) $this->qty = 0; - if (empty($this->pa_ht)) $this->pa_ht=0; - if (empty($this->multicurrency_subprice)) $this->multicurrency_subprice=0; - if (empty($this->multicurrency_total_ht)) $this->multicurrency_total_ht=0; - if (empty($this->multicurrency_total_tva)) $this->multicurrency_total_tva=0; - if (empty($this->multicurrency_total_ttc)) $this->multicurrency_total_ttc=0; + if (empty($this->pa_ht)) $this->pa_ht=0; + if (empty($this->multicurrency_subprice)) $this->multicurrency_subprice=0; + if (empty($this->multicurrency_total_ht)) $this->multicurrency_total_ht=0; + if (empty($this->multicurrency_total_tva)) $this->multicurrency_total_tva=0; + if (empty($this->multicurrency_total_ttc)) $this->multicurrency_total_ttc=0; - // if buy price not defined, define buyprice as configured in margin admin + // if buy price not defined, define buyprice as configured in margin admin if ($this->pa_ht == 0 && $pa_ht_isemptystring) { if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) @@ -3772,183 +3772,183 @@ class PropaleLigne extends CommonObjectLine } } - // Check parameters - if ($this->product_type < 0) return -1; + // Check parameters + if ($this->product_type < 0) return -1; - $this->db->begin(); + $this->db->begin(); - // Insert line into database - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'propaldet'; - $sql.= ' (fk_propal, fk_parent_line, label, description, fk_product, product_type,'; + // Insert line into database + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'propaldet'; + $sql.= ' (fk_propal, fk_parent_line, label, description, fk_product, product_type,'; $sql.= ' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,'; - $sql.= ' subprice, remise_percent, '; - $sql.= ' info_bits, '; - $sql.= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,'; - $sql.= ' fk_unit,'; - $sql.= ' date_start, date_end'; + $sql.= ' subprice, remise_percent, '; + $sql.= ' info_bits, '; + $sql.= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,'; + $sql.= ' fk_unit,'; + $sql.= ' date_start, date_end'; $sql.= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)'; - $sql.= " VALUES (".$this->fk_propal.","; - $sql.= " ".($this->fk_parent_line>0?"'".$this->db->escape($this->fk_parent_line)."'":"null").","; - $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; - $sql.= " '".$this->db->escape($this->desc)."',"; - $sql.= " ".($this->fk_product?"'".$this->db->escape($this->fk_product)."'":"null").","; - $sql.= " '".$this->db->escape($this->product_type)."',"; - $sql.= " ".($this->fk_remise_except?"'".$this->db->escape($this->fk_remise_except)."'":"null").","; - $sql.= " ".price2num($this->qty).","; - $sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->db->escape($this->vat_src_code)."'").","; - $sql.= " ".price2num($this->tva_tx).","; - $sql.= " ".price2num($this->localtax1_tx).","; - $sql.= " ".price2num($this->localtax2_tx).","; + $sql.= " VALUES (".$this->fk_propal.","; + $sql.= " ".($this->fk_parent_line>0?"'".$this->db->escape($this->fk_parent_line)."'":"null").","; + $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; + $sql.= " '".$this->db->escape($this->desc)."',"; + $sql.= " ".($this->fk_product?"'".$this->db->escape($this->fk_product)."'":"null").","; + $sql.= " '".$this->db->escape($this->product_type)."',"; + $sql.= " ".($this->fk_remise_except?"'".$this->db->escape($this->fk_remise_except)."'":"null").","; + $sql.= " ".price2num($this->qty).","; + $sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->db->escape($this->vat_src_code)."'").","; + $sql.= " ".price2num($this->tva_tx).","; + $sql.= " ".price2num($this->localtax1_tx).","; + $sql.= " ".price2num($this->localtax2_tx).","; $sql.= " '".$this->db->escape($this->localtax1_type)."',"; $sql.= " '".$this->db->escape($this->localtax2_type)."',"; - $sql.= " ".($this->subprice?price2num($this->subprice):"null").","; - $sql.= " ".price2num($this->remise_percent).","; - $sql.= " ".(isset($this->info_bits)?"'".$this->db->escape($this->info_bits)."'":"null").","; - $sql.= " ".price2num($this->total_ht).","; - $sql.= " ".price2num($this->total_tva).","; - $sql.= " ".price2num($this->total_localtax1).","; - $sql.= " ".price2num($this->total_localtax2).","; - $sql.= " ".price2num($this->total_ttc).","; - $sql.= " ".(!empty($this->fk_fournprice)?"'".$this->db->escape($this->fk_fournprice)."'":"null").","; - $sql.= " ".(isset($this->pa_ht)?"'".price2num($this->pa_ht)."'":"null").","; - $sql.= ' '.$this->special_code.','; - $sql.= ' '.$this->rang.','; - $sql.= ' '.(!$this->fk_unit ? 'NULL' : $this->fk_unit).','; - $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").','; - $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); + $sql.= " ".($this->subprice?price2num($this->subprice):"null").","; + $sql.= " ".price2num($this->remise_percent).","; + $sql.= " ".(isset($this->info_bits)?"'".$this->db->escape($this->info_bits)."'":"null").","; + $sql.= " ".price2num($this->total_ht).","; + $sql.= " ".price2num($this->total_tva).","; + $sql.= " ".price2num($this->total_localtax1).","; + $sql.= " ".price2num($this->total_localtax2).","; + $sql.= " ".price2num($this->total_ttc).","; + $sql.= " ".(!empty($this->fk_fournprice)?"'".$this->db->escape($this->fk_fournprice)."'":"null").","; + $sql.= " ".(isset($this->pa_ht)?"'".price2num($this->pa_ht)."'":"null").","; + $sql.= ' '.$this->special_code.','; + $sql.= ' '.$this->rang.','; + $sql.= ' '.(!$this->fk_unit ? 'NULL' : $this->fk_unit).','; + $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").','; + $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); $sql.= ", ".($this->fk_multicurrency > 0?$this->fk_multicurrency:'null'); $sql.= ", '".$this->db->escape($this->multicurrency_code)."'"; $sql.= ", ".$this->multicurrency_subprice; $sql.= ", ".$this->multicurrency_total_ht; $sql.= ", ".$this->multicurrency_total_tva; $sql.= ", ".$this->multicurrency_total_ttc; - $sql.= ')'; - - dol_syslog(get_class($this).'::insert', LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'propaldet'); - - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $this->id=$this->rowid; - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('LINEPROPAL_INSERT',$user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - // End call triggers - } - - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -1; - } - } - - /** - * Delete line in database - * - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if ko, >0 if ok - */ - function delete($notrigger=0) - { - global $conf,$user; - - $error=0; - $this->db->begin(); - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE rowid = ".$this->rowid; - dol_syslog("PropaleLigne::delete", LOG_DEBUG); - if ($this->db->query($sql) ) - { - - // Remove extrafields - if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used - { - $this->id=$this->rowid; - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $error++; - dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); - } - } - - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('LINEPROPAL_DELETE',$user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - } - // End call triggers - - $this->db->commit(); - - return 1; - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -1; - } - } - - /** - * Update propal line object into DB - * - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if ko, >0 if ok - */ - function update($notrigger=0) - { - global $conf,$user; - - $error=0; - - $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'. - - // Clean parameters - if (empty($this->tva_tx)) $this->tva_tx=0; - if (empty($this->localtax1_tx)) $this->localtax1_tx=0; - if (empty($this->localtax2_tx)) $this->localtax2_tx=0; - if (empty($this->total_localtax1)) $this->total_localtax1=0; - if (empty($this->total_localtax2)) $this->total_localtax2=0; + $sql.= ')'; + + dol_syslog(get_class($this).'::insert', LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'propaldet'); + + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $this->id=$this->rowid; + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINEPROPAL_INSERT',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // End call triggers + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + } + + /** + * Delete line in database + * + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if ko, >0 if ok + */ + function delete($notrigger=0) + { + global $conf,$user; + + $error=0; + $this->db->begin(); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE rowid = ".$this->rowid; + dol_syslog("PropaleLigne::delete", LOG_DEBUG); + if ($this->db->query($sql) ) + { + + // Remove extrafields + if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used + { + $this->id=$this->rowid; + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); + } + } + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINEPROPAL_DELETE',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + } + // End call triggers + + $this->db->commit(); + + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + } + + /** + * Update propal line object into DB + * + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if ko, >0 if ok + */ + function update($notrigger=0) + { + global $conf,$user; + + $error=0; + + $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'. + + // Clean parameters + if (empty($this->tva_tx)) $this->tva_tx=0; + if (empty($this->localtax1_tx)) $this->localtax1_tx=0; + if (empty($this->localtax2_tx)) $this->localtax2_tx=0; + if (empty($this->total_localtax1)) $this->total_localtax1=0; + if (empty($this->total_localtax2)) $this->total_localtax2=0; if (empty($this->localtax1_type)) $this->localtax1_type=0; if (empty($this->localtax2_type)) $this->localtax2_type=0; - if (empty($this->marque_tx)) $this->marque_tx=0; - if (empty($this->marge_tx)) $this->marge_tx=0; - if (empty($this->price)) $this->price=0; // TODO A virer - if (empty($this->remise)) $this->remise=0; // TODO A virer - if (empty($this->remise_percent)) $this->remise_percent=0; - if (empty($this->info_bits)) $this->info_bits=0; - if (empty($this->special_code)) $this->special_code=0; - if (empty($this->fk_parent_line)) $this->fk_parent_line=0; - if (empty($this->fk_fournprice)) $this->fk_fournprice=0; - if (empty($this->subprice)) $this->subprice=0; + if (empty($this->marque_tx)) $this->marque_tx=0; + if (empty($this->marge_tx)) $this->marge_tx=0; + if (empty($this->price)) $this->price=0; // TODO A virer + if (empty($this->remise)) $this->remise=0; // TODO A virer + if (empty($this->remise_percent)) $this->remise_percent=0; + if (empty($this->info_bits)) $this->info_bits=0; + if (empty($this->special_code)) $this->special_code=0; + if (empty($this->fk_parent_line)) $this->fk_parent_line=0; + if (empty($this->fk_fournprice)) $this->fk_fournprice=0; + if (empty($this->subprice)) $this->subprice=0; if (empty($this->pa_ht)) $this->pa_ht=0; // if buy price not defined, define buyprice as configured in margin admin @@ -3964,119 +3964,119 @@ class PropaleLigne extends CommonObjectLine } } - $this->db->begin(); + $this->db->begin(); - // Mise a jour ligne en base - $sql = "UPDATE ".MAIN_DB_PREFIX."propaldet SET"; - $sql.= " description='".$this->db->escape($this->desc)."'"; - $sql.= ", label=".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null"); - $sql.= ", product_type=".$this->product_type; + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."propaldet SET"; + $sql.= " description='".$this->db->escape($this->desc)."'"; + $sql.= ", label=".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null"); + $sql.= ", product_type=".$this->product_type; $sql.= ", vat_src_code = '".(empty($this->vat_src_code)?'':$this->vat_src_code)."'"; - $sql.= ", tva_tx='".price2num($this->tva_tx)."'"; - $sql.= ", localtax1_tx=".price2num($this->localtax1_tx); - $sql.= ", localtax2_tx=".price2num($this->localtax2_tx); + $sql.= ", tva_tx='".price2num($this->tva_tx)."'"; + $sql.= ", localtax1_tx=".price2num($this->localtax1_tx); + $sql.= ", localtax2_tx=".price2num($this->localtax2_tx); $sql.= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'"; $sql.= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'"; - $sql.= ", qty='".price2num($this->qty)."'"; - $sql.= ", subprice=".price2num($this->subprice).""; - $sql.= ", remise_percent=".price2num($this->remise_percent).""; - $sql.= ", price=".price2num($this->price).""; // TODO A virer - $sql.= ", remise=".price2num($this->remise).""; // TODO A virer - $sql.= ", info_bits='".$this->db->escape($this->info_bits)."'"; - if (empty($this->skip_update_total)) - { - $sql.= ", total_ht=".price2num($this->total_ht).""; - $sql.= ", total_tva=".price2num($this->total_tva).""; - $sql.= ", total_ttc=".price2num($this->total_ttc).""; - $sql.= ", total_localtax1=".price2num($this->total_localtax1).""; - $sql.= ", total_localtax2=".price2num($this->total_localtax2).""; - } + $sql.= ", qty='".price2num($this->qty)."'"; + $sql.= ", subprice=".price2num($this->subprice).""; + $sql.= ", remise_percent=".price2num($this->remise_percent).""; + $sql.= ", price=".price2num($this->price).""; // TODO A virer + $sql.= ", remise=".price2num($this->remise).""; // TODO A virer + $sql.= ", info_bits='".$this->db->escape($this->info_bits)."'"; + if (empty($this->skip_update_total)) + { + $sql.= ", total_ht=".price2num($this->total_ht).""; + $sql.= ", total_tva=".price2num($this->total_tva).""; + $sql.= ", total_ttc=".price2num($this->total_ttc).""; + $sql.= ", total_localtax1=".price2num($this->total_localtax1).""; + $sql.= ", total_localtax2=".price2num($this->total_localtax2).""; + } $sql.= ", fk_product_fournisseur_price=".(! empty($this->fk_fournprice)?"'".$this->db->escape($this->fk_fournprice)."'":"null"); $sql.= ", buy_price_ht=".price2num($this->pa_ht); - if (strlen($this->special_code)) $sql.= ", special_code=".$this->special_code; - $sql.= ", fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); - if (! empty($this->rang)) $sql.= ", rang=".$this->rang; - $sql.= ", date_start=".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null"); - $sql.= ", date_end=".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); - $sql.= ", fk_unit=".(!$this->fk_unit ? 'NULL' : $this->fk_unit); + if (strlen($this->special_code)) $sql.= ", special_code=".$this->special_code; + $sql.= ", fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); + if (! empty($this->rang)) $sql.= ", rang=".$this->rang; + $sql.= ", date_start=".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null"); + $sql.= ", date_end=".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); + $sql.= ", fk_unit=".(!$this->fk_unit ? 'NULL' : $this->fk_unit); // Multicurrency $sql.= ", multicurrency_subprice=".price2num($this->multicurrency_subprice).""; - $sql.= ", multicurrency_total_ht=".price2num($this->multicurrency_total_ht).""; - $sql.= ", multicurrency_total_tva=".price2num($this->multicurrency_total_tva).""; - $sql.= ", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc).""; - - $sql.= " WHERE rowid = ".$this->rowid; - - dol_syslog(get_class($this)."::update", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $this->id=$this->rowid; - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('LINEPROPAL_UPDATE',$user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - // End call triggers - } - - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -2; - } - } - - /** - * Update DB line fields total_xxx - * Used by migration - * - * @return int <0 if ko, >0 if ok - */ - function update_total() - { - $this->db->begin(); - - // Mise a jour ligne en base - $sql = "UPDATE ".MAIN_DB_PREFIX."propaldet SET"; - $sql.= " total_ht=".price2num($this->total_ht,'MT').""; - $sql.= ",total_tva=".price2num($this->total_tva,'MT').""; - $sql.= ",total_ttc=".price2num($this->total_ttc,'MT').""; - $sql.= " WHERE rowid = ".$this->rowid; - - dol_syslog("PropaleLigne::update_total", LOG_DEBUG); - - $resql=$this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -2; - } - } + $sql.= ", multicurrency_total_ht=".price2num($this->multicurrency_total_ht).""; + $sql.= ", multicurrency_total_tva=".price2num($this->multicurrency_total_tva).""; + $sql.= ", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc).""; + + $sql.= " WHERE rowid = ".$this->rowid; + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $this->id=$this->rowid; + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINEPROPAL_UPDATE',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // End call triggers + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -2; + } + } + + /** + * Update DB line fields total_xxx + * Used by migration + * + * @return int <0 if ko, >0 if ok + */ + function update_total() + { + $this->db->begin(); + + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."propaldet SET"; + $sql.= " total_ht=".price2num($this->total_ht,'MT').""; + $sql.= ",total_tva=".price2num($this->total_tva,'MT').""; + $sql.= ",total_ttc=".price2num($this->total_ttc,'MT').""; + $sql.= " WHERE rowid = ".$this->rowid; + + dol_syslog("PropaleLigne::update_total", LOG_DEBUG); + + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -2; + } + } } diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 352e1db5e6b9522d36c6ef7eed63af2863efad14..27de7b6e863657ec2211ab70b43bc864f03757a7 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -72,204 +72,204 @@ if ($cancel) $action=''; if ($action == 'add') { - $error=0; + $error=0; - $db->begin(); + $db->begin(); - // Create account - $object = new Account($db); + // Create account + $object = new Account($db); - $object->ref = dol_sanitizeFileName(trim($_POST["ref"])); - $object->label = trim($_POST["label"]); - $object->courant = $_POST["type"]; - $object->clos = $_POST["clos"]; - $object->rappro = (isset($_POST["norappro"]) && $_POST["norappro"])?0:1; - $object->url = $_POST["url"]; + $object->ref = dol_sanitizeFileName(trim($_POST["ref"])); + $object->label = trim($_POST["label"]); + $object->courant = $_POST["type"]; + $object->clos = $_POST["clos"]; + $object->rappro = (isset($_POST["norappro"]) && $_POST["norappro"])?0:1; + $object->url = $_POST["url"]; $object->bank = trim($_POST["bank"]); - $object->code_banque = trim($_POST["code_banque"]); - $object->code_guichet = trim($_POST["code_guichet"]); - $object->number = trim($_POST["number"]); - $object->cle_rib = trim($_POST["cle_rib"]); - $object->bic = trim($_POST["bic"]); - $object->iban = trim($_POST["iban"]); - $object->domiciliation = trim($_POST["domiciliation"]); + $object->code_banque = trim($_POST["code_banque"]); + $object->code_guichet = trim($_POST["code_guichet"]); + $object->number = trim($_POST["number"]); + $object->cle_rib = trim($_POST["cle_rib"]); + $object->bic = trim($_POST["bic"]); + $object->iban = trim($_POST["iban"]); + $object->domiciliation = trim($_POST["domiciliation"]); - $object->proprio = trim($_POST["proprio"]); - $object->owner_address = trim($_POST["owner_address"]); + $object->proprio = trim($_POST["proprio"]); + $object->owner_address = trim($_POST["owner_address"]); $account_number = GETPOST('account_number','alpha'); if ($account_number <= 0) { $object->account_number = ''; } else { $object->account_number = $account_number; } $fk_accountancy_journal = GETPOST('fk_accountancy_journal','int'); if ($fk_accountancy_journal <= 0) { $object->fk_accountancy_journal = ''; } else { $object->fk_accountancy_journal = $fk_accountancy_journal; } - $object->solde = $_POST["solde"]; - $object->date_solde = dol_mktime(12,0,0,$_POST["remonth"],$_POST["reday"],$_POST["reyear"]); - - $object->currency_code = trim($_POST["account_currency_code"]); - - $object->state_id = $_POST["account_state_id"]; - $object->country_id = $_POST["account_country_id"]; - - $object->min_allowed = GETPOST("account_min_allowed",'int'); - $object->min_desired = GETPOST("account_min_desired",'int'); - $object->comment = trim(GETPOST("account_comment")); - - $object->fk_user_author = $user->id; - - if ($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED && empty($object->account_number)) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("AccountancyCode")), null, 'errors'); - $action='create'; // Force chargement page en mode creation - $error++; - } - if (empty($object->ref)) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); - $action='create'; // Force chargement page en mode creation - $error++; - } - if (empty($object->label)) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("LabelBankCashAccount")), null, 'errors'); - $action='create'; // Force chargement page en mode creation - $error++; - } - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - if (! $error) - { - $id = $object->create($user); - if ($id > 0) - { - // Category association - $categories = GETPOST('categories', 'array'); - $object->setCategories($categories); - - $_GET["id"]=$id; // Force chargement page en mode visu - - $action=''; - } - else { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); - - $action='create'; // Force chargement page en mode creation - } - } - - if (! $error) - { - $db->commit(); - } - else - { - $db->rollback(); - } + $object->solde = $_POST["solde"]; + $object->date_solde = dol_mktime(12,0,0,$_POST["remonth"],$_POST["reday"],$_POST["reyear"]); + + $object->currency_code = trim($_POST["account_currency_code"]); + + $object->state_id = $_POST["account_state_id"]; + $object->country_id = $_POST["account_country_id"]; + + $object->min_allowed = GETPOST("account_min_allowed",'int'); + $object->min_desired = GETPOST("account_min_desired",'int'); + $object->comment = trim(GETPOST("account_comment")); + + $object->fk_user_author = $user->id; + + if ($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED && empty($object->account_number)) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("AccountancyCode")), null, 'errors'); + $action='create'; // Force chargement page en mode creation + $error++; + } + if (empty($object->ref)) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + $action='create'; // Force chargement page en mode creation + $error++; + } + if (empty($object->label)) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("LabelBankCashAccount")), null, 'errors'); + $action='create'; // Force chargement page en mode creation + $error++; + } + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + if (! $error) + { + $id = $object->create($user); + if ($id > 0) + { + // Category association + $categories = GETPOST('categories', 'array'); + $object->setCategories($categories); + + $_GET["id"]=$id; // Force chargement page en mode visu + + $action=''; + } + else { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + + $action='create'; // Force chargement page en mode creation + } + } + + if (! $error) + { + $db->commit(); + } + else + { + $db->rollback(); + } } if ($action == 'update') { - $error=0; - - // Update account - $object = new Account($db); - $object->fetch(GETPOST("id")); - - $object->ref = dol_string_nospecial(trim($_POST["ref"])); - $object->label = trim($_POST["label"]); - $object->courant = $_POST["type"]; - $object->clos = $_POST["clos"]; - $object->rappro = (isset($_POST["norappro"]) && $_POST["norappro"])?0:1; - $object->url = trim($_POST["url"]); - - $object->bank = trim($_POST["bank"]); - $object->code_banque = trim($_POST["code_banque"]); - $object->code_guichet = trim($_POST["code_guichet"]); - $object->number = trim($_POST["number"]); - $object->cle_rib = trim($_POST["cle_rib"]); - $object->bic = trim($_POST["bic"]); - $object->iban = trim($_POST["iban"]); - $object->domiciliation = trim($_POST["domiciliation"]); - - $object->proprio = trim($_POST["proprio"]); - $object->owner_address = trim($_POST["owner_address"]); + $error=0; + + // Update account + $object = new Account($db); + $object->fetch(GETPOST("id")); + + $object->ref = dol_string_nospecial(trim($_POST["ref"])); + $object->label = trim($_POST["label"]); + $object->courant = $_POST["type"]; + $object->clos = $_POST["clos"]; + $object->rappro = (isset($_POST["norappro"]) && $_POST["norappro"])?0:1; + $object->url = trim($_POST["url"]); + + $object->bank = trim($_POST["bank"]); + $object->code_banque = trim($_POST["code_banque"]); + $object->code_guichet = trim($_POST["code_guichet"]); + $object->number = trim($_POST["number"]); + $object->cle_rib = trim($_POST["cle_rib"]); + $object->bic = trim($_POST["bic"]); + $object->iban = trim($_POST["iban"]); + $object->domiciliation = trim($_POST["domiciliation"]); + + $object->proprio = trim($_POST["proprio"]); + $object->owner_address = trim($_POST["owner_address"]); $account_number = GETPOST('account_number', 'int'); if ($account_number <= 0) { $object->account_number = ''; } else { $object->account_number = $account_number; } $fk_accountancy_journal = GETPOST('fk_accountancy_journal','int'); if ($fk_accountancy_journal <= 0) { $object->fk_accountancy_journal = ''; } else { $object->fk_accountancy_journal = $fk_accountancy_journal; } - $object->currency_code = trim($_POST["account_currency_code"]); - - $object->state_id = $_POST["account_state_id"]; - $object->country_id = $_POST["account_country_id"]; - - $object->min_allowed = GETPOST("account_min_allowed",'int'); - $object->min_desired = GETPOST("account_min_desired",'int'); - $object->comment = trim(GETPOST("account_comment")); - - if ($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED && empty($object->account_number)) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("AccountancyCode")), null, 'error'); - $action='edit'; // Force chargement page en mode creation - $error++; - } - if (empty($object->ref)) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); - $action='edit'; // Force chargement page en mode creation - $error++; - } - if (empty($object->label)) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("LabelBankCashAccount")), null, 'errors'); - $action='edit'; // Force chargement page en mode creation - $error++; - } - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - if (! $error) - { - $result = $object->update($user); - if ($result >= 0) - { - // Category association - $categories = GETPOST('categories', 'array'); - $object->setCategories($categories); - - $_GET["id"]=$_POST["id"]; // Force chargement page en mode visu - } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - $action='edit'; // Force chargement page edition - } - } + $object->currency_code = trim($_POST["account_currency_code"]); + + $object->state_id = $_POST["account_state_id"]; + $object->country_id = $_POST["account_country_id"]; + + $object->min_allowed = GETPOST("account_min_allowed",'int'); + $object->min_desired = GETPOST("account_min_desired",'int'); + $object->comment = trim(GETPOST("account_comment")); + + if ($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED && empty($object->account_number)) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("AccountancyCode")), null, 'error'); + $action='edit'; // Force chargement page en mode creation + $error++; + } + if (empty($object->ref)) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + $action='edit'; // Force chargement page en mode creation + $error++; + } + if (empty($object->label)) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("LabelBankCashAccount")), null, 'errors'); + $action='edit'; // Force chargement page en mode creation + $error++; + } + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + if (! $error) + { + $result = $object->update($user); + if ($result >= 0) + { + // Category association + $categories = GETPOST('categories', 'array'); + $object->setCategories($categories); + + $_GET["id"]=$_POST["id"]; // Force chargement page en mode visu + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + $action='edit'; // Force chargement page edition + } + } } if ($action == 'confirm_delete' && $_POST["confirm"] == "yes" && $user->rights->banque->configurer) { - // Delete - $object = new Account($db); - $object->fetch(GETPOST("id","int")); - $result = $object->delete($user); - - if ($result > 0) - { - setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); - header("Location: ".DOL_URL_ROOT."/compta/bank/list.php"); - exit; - } - else - { - setEventMessages($account->error, $account->errors, 'errors'); - $action=''; - } + // Delete + $object = new Account($db); + $object->fetch(GETPOST("id","int")); + $result = $object->delete($user); + + if ($result > 0) + { + setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); + header("Location: ".DOL_URL_ROOT."/compta/bank/list.php"); + exit; + } + else + { + setEventMessages($account->error, $account->errors, 'errors'); + $action=''; + } } @@ -297,10 +297,10 @@ if ($action == 'create') print load_fiche_titre($langs->trans("NewFinancialAccount"), '', 'title_bank.png'); - if ($conf->use_javascript_ajax) - { + if ($conf->use_javascript_ajax) + { print "\n".'<script type="text/javascript" language="javascript">'; - print 'jQuery(document).ready(function () { + print 'jQuery(document).ready(function () { jQuery("#selecttype").change(function() { document.formsoc.action.value="create"; document.formsoc.submit(); @@ -310,8 +310,8 @@ if ($action == 'create') document.formsoc.submit(); }); })'; - print '</script>'."\n"; - } + print '</script>'."\n"; + } print '<form action="'.$_SERVER["PHP_SELF"].'" name="formsoc" method="post">'; print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; @@ -347,12 +347,12 @@ if ($action == 'create') print '</td></tr>'; // Status - print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td>'; - print '<td>'; - print $form->selectarray("clos", $object->status,(GETPOST("clos",'int')!=''?GETPOST("clos",'int'):$object->clos)); - print '</td></tr>'; + print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td>'; + print '<td>'; + print $form->selectarray("clos", $object->status,(GETPOST("clos",'int')!=''?GETPOST("clos",'int'):$object->clos)); + print '</td></tr>'; - // Country + // Country $selectedcode=''; if (isset($_POST["account_country_id"])) { @@ -383,24 +383,24 @@ if ($action == 'create') print '<tr><td>'.$langs->trans("Web").'</td>'; print '<td><input class="minwidth300" type="text" class="flat" name="url" value="'.GETPOST("url").'"></td></tr>'; - // Tags-Categories - if ($conf->categorie->enabled) - { - print '<tr><td class="tdtop">'.$langs->trans("Categories").'</td><td>'; - $cate_arbo = $form->select_all_categories(Categorie::TYPE_ACCOUNT, '', 'parent', 64, 0, 1); - $c = new Categorie($db); - $cats = $c->containing($object->id,Categorie::TYPE_ACCOUNT); - foreach($cats as $cat) { - $arrayselected[] = $cat->id; - } - print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); - print "</td></tr>"; - } + // Tags-Categories + if ($conf->categorie->enabled) + { + print '<tr><td class="tdtop">'.$langs->trans("Categories").'</td><td>'; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_ACCOUNT, '', 'parent', 64, 0, 1); + $c = new Categorie($db); + $cats = $c->containing($object->id,Categorie::TYPE_ACCOUNT); + foreach($cats as $cat) { + $arrayselected[] = $cat->id; + } + print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); + print "</td></tr>"; + } // Comment print '<tr><td class="tdtop">'.$langs->trans("Comment").'</td>'; print '<td>'; - // Editor wysiwyg + // Editor wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor=new DolEditor('account_comment',(GETPOST("account_comment")?GETPOST("account_comment"):$object->comment),'',90,'dolibarr_notes','',false,true,$conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_4,'90%'); $doleditor->Create(); @@ -409,7 +409,7 @@ if ($action == 'create') // Other attributes $parameters=array(); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; + print $hookmanager->resPrint; if (empty($reshook) && ! empty($extrafields->attribute_label)) { print $object->showOptionals($extrafields,'edit',$parameters); @@ -504,7 +504,7 @@ if ($action == 'create') print '<table class="border" width="100%">'; // Accountancy code $fieldrequired=''; - if (! empty($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED)) $fieldrequired='fieldrequired '; + if (! empty($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED)) $fieldrequired='fieldrequired '; if (! empty($conf->accounting->enabled)) { @@ -523,7 +523,7 @@ if ($action == 'create') if (! empty($conf->accounting->enabled)) { print '<tr><td>'.$langs->trans("AccountancyJournal").'</td>'; - print '<td>'; + print '<td>'; print $formaccounting->select_journal($object->fk_accountancy_journal, 'fk_accountancy_journal', 4, 1, 0, 0); print '</td></tr>'; } @@ -547,7 +547,7 @@ if ($action == 'create') /* ************************************************************************** */ else { - if (($_GET["id"] || $_GET["ref"]) && $action != 'edit') + if (($_GET["id"] || $_GET["ref"]) && $action != 'edit') { $object = new Account($db); if ($_GET["id"]) @@ -605,7 +605,7 @@ else print '<td>'; $conciliate=$object->canBeConciliated(); if ($conciliate == -2) print $langs->trans("No").' ('.$langs->trans("CashAccount").')'; - else if ($conciliate == -3) print $langs->trans("No").' ('.$langs->trans("Closed").')'; + else if ($conciliate == -3) print $langs->trans("No").' ('.$langs->trans("Closed").')'; else print ($object->rappro==1 ? $langs->trans("Yes") : ($langs->trans("No").' ('.$langs->trans("ConciliationDisabled").')')); print '</td></tr>'; @@ -624,15 +624,15 @@ else print $accountingaccount->getNomUrl(0,1,1,'',1); } else { - print $object->account_number; + print $object->account_number; } print '</td></tr>'; // Accountancy journal if (! empty($conf->accounting->enabled)) { - print '<tr><td>'.$langs->trans("AccountancyJournal").'</td>'; - print '<td>'; + print '<tr><td>'.$langs->trans("AccountancyJournal").'</td>'; + print '<td>'; $accountingjournal = new AccountingJournal($db); $accountingjournal->fetch($object->fk_accountancy_journal); @@ -655,12 +655,12 @@ else print '<table class="border centpercent">'; - // Categories - if ($conf->categorie->enabled) { - print '<tr><td class="titlefield">'.$langs->trans("Categories").'</td><td>'; - print $form->showCategories($object->id,'bank_account',1); - print "</td></tr>"; - } + // Categories + if ($conf->categorie->enabled) { + print '<tr><td class="titlefield">'.$langs->trans("Categories").'</td><td>'; + print $form->showCategories($object->id,'bank_account',1); + print "</td></tr>"; + } print '<tr><td class="tdtop titlefield">'.$langs->trans("Comment").'</td>'; print '<td>'.dol_htmlentitiesbr($object->comment).'</td></tr>'; @@ -669,11 +669,11 @@ else if ($object->type == Account::TYPE_SAVINGS || $object->type == Account::TYPE_CURRENT) { - print '<br>'; + print '<br>'; - print '<div class="underbanner clearboth"></div>'; + print '<div class="underbanner clearboth"></div>'; - print '<table class="border centpercent">'; + print '<table class="border centpercent">'; print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("BankName").'</td>'; print '<td>'.$object->bank.'</td></tr>'; @@ -764,23 +764,23 @@ else } - /* ************************************************************************** */ - /* */ - /* Edition */ - /* */ - /* ************************************************************************** */ + /* ************************************************************************** */ + /* */ + /* Edition */ + /* */ + /* ************************************************************************** */ - if (GETPOST('id','int') && $action == 'edit' && $user->rights->banque->configurer) - { - $object = new Account($db); - $object->fetch(GETPOST('id','int')); + if (GETPOST('id','int') && $action == 'edit' && $user->rights->banque->configurer) + { + $object = new Account($db); + $object->fetch(GETPOST('id','int')); - print load_fiche_titre($langs->trans("EditFinancialAccount"), '', 'title_bank.png'); + print load_fiche_titre($langs->trans("EditFinancialAccount"), '', 'title_bank.png'); - if ($conf->use_javascript_ajax) - { - print "\n".'<script type="text/javascript" language="javascript">'; - print 'jQuery(document).ready(function () { + if ($conf->use_javascript_ajax) + { + print "\n".'<script type="text/javascript" language="javascript">'; + print 'jQuery(document).ready(function () { jQuery("#selecttype").change(function() { document.formsoc.action.value="edit"; document.formsoc.submit(); @@ -793,33 +793,33 @@ else document.formsoc.submit(); }); })'; - print '</script>'."\n"; - } + print '</script>'."\n"; + } - print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post" name="formsoc">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="update">'; - print '<input type="hidden" name="id" value="'.$_REQUEST["id"].'">'."\n\n"; + print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post" name="formsoc">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="update">'; + print '<input type="hidden" name="id" value="'.$_REQUEST["id"].'">'."\n\n"; - dol_fiche_head(''); + dol_fiche_head(''); - print '<div class="underbanner clearboth"></div>'; + print '<div class="underbanner clearboth"></div>'; - print '<table class="border" width="100%">'; + print '<table class="border" width="100%">'; // Ref print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("Ref").'</td>'; print '<td><input size="8" type="text" class="flat" name="ref" value="'.(isset($_POST["ref"])?GETPOST("ref"):$object->ref).'"></td></tr>'; // Label - print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>'; - print '<td><input type="text" class="flat minwidth300" name="label" value="'.(isset($_POST["label"])?GETPOST("label"):$object->label).'"></td></tr>'; + print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>'; + print '<td><input type="text" class="flat minwidth300" name="label" value="'.(isset($_POST["label"])?GETPOST("label"):$object->label).'"></td></tr>'; - // Type - print '<tr><td class="fieldrequired">'.$langs->trans("AccountType").'</td>'; - print '<td class="maxwidth200onsmartphone">'; + // Type + print '<tr><td class="fieldrequired">'.$langs->trans("AccountType").'</td>'; + print '<td class="maxwidth200onsmartphone">'; $formbank->selectTypeOfBankAccount((isset($_POST["type"])?$_POST["type"]:$object->type),"type"); - print '</td></tr>'; + print '</td></tr>'; // Currency print '<tr><td class="fieldrequired">'.$langs->trans("Currency"); @@ -834,10 +834,10 @@ else print '</td></tr>'; // Status - print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td>'; - print '<td class="maxwidth200onsmartphone">'; - print $form->selectarray("clos", $object->status, (isset($_POST["clos"])?$_POST["clos"]:$object->clos)); - print '</td></tr>'; + print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td>'; + print '<td class="maxwidth200onsmartphone">'; + print $form->selectarray("clos", $object->status, (isset($_POST["clos"])?$_POST["clos"]:$object->clos)); + print '</td></tr>'; // Country $object->country_id=$object->country_id?$object->country_id:$mysoc->country_id; @@ -865,15 +865,15 @@ else print '</td></tr>'; // Conciliable - print '<tr><td>'.$langs->trans("Conciliable").'</td>'; - print '<td>'; - $conciliate=$object->canBeConciliated(); - if ($conciliate == -2) print $langs->trans("No").' ('.$langs->trans("CashAccount").')'; - else if ($conciliate == -3) print $langs->trans("No").' ('.$langs->trans("Closed").')'; - else print '<input type="checkbox" class="flat" name="norappro"'.(($conciliate > 0)?'':' checked="checked"').'"> '.$langs->trans("DisableConciliation"); - print '</td></tr>'; - - // Balance + print '<tr><td>'.$langs->trans("Conciliable").'</td>'; + print '<td>'; + $conciliate=$object->canBeConciliated(); + if ($conciliate == -2) print $langs->trans("No").' ('.$langs->trans("CashAccount").')'; + else if ($conciliate == -3) print $langs->trans("No").' ('.$langs->trans("Closed").')'; + else print '<input type="checkbox" class="flat" name="norappro"'.(($conciliate > 0)?'':' checked="checked"').'"> '.$langs->trans("DisableConciliation"); + print '</td></tr>'; + + // Balance print '<tr><td>'.$langs->trans("BalanceMinimalAllowed").'</td>'; print '<td><input size="12" type="text" class="flat" name="account_min_allowed" value="'.(isset($_POST["account_min_allowed"])?GETPOST("account_min_allowed"):$object->min_allowed).'"></td></tr>'; @@ -881,28 +881,28 @@ else print '<td ><input size="12" type="text" class="flat" name="account_min_desired" value="'.(isset($_POST["account_min_desired"])?GETPOST("account_min_desired"):$object->min_desired).'"></td></tr>'; // Web - print '<tr><td>'.$langs->trans("Web").'</td>'; - print '<td><input class="maxwidth200onsmartphone" type="text" class="flat" name="url" value="'.(isset($_POST["url"])?GETPOST("url"):$object->url).'">'; - print '</td></tr>'; - - // Tags-Categories - if ($conf->categorie->enabled) - { - print '<tr><td class="tdtop">'.$langs->trans("Categories").'</td><td>'; - $cate_arbo = $form->select_all_categories(Categorie::TYPE_ACCOUNT, '', 'parent', 64, 0, 1); - $c = new Categorie($db); - $cats = $c->containing($object->id,Categorie::TYPE_ACCOUNT); - foreach($cats as $cat) { - $arrayselected[] = $cat->id; - } - print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); - print "</td></tr>"; - } + print '<tr><td>'.$langs->trans("Web").'</td>'; + print '<td><input class="maxwidth200onsmartphone" type="text" class="flat" name="url" value="'.(isset($_POST["url"])?GETPOST("url"):$object->url).'">'; + print '</td></tr>'; + + // Tags-Categories + if ($conf->categorie->enabled) + { + print '<tr><td class="tdtop">'.$langs->trans("Categories").'</td><td>'; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_ACCOUNT, '', 'parent', 64, 0, 1); + $c = new Categorie($db); + $cats = $c->containing($object->id,Categorie::TYPE_ACCOUNT); + foreach($cats as $cat) { + $arrayselected[] = $cat->id; + } + print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); + print "</td></tr>"; + } // Comment print '<tr><td class="tdtop">'.$langs->trans("Comment").'</td>'; print '<td>'; - // Editor wysiwyg + // Editor wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor=new DolEditor('account_comment',(GETPOST("account_comment")?GETPOST("account_comment"):$object->comment),'',90,'dolibarr_notes','',false,true,$conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_4,'95%'); $doleditor->Create(); @@ -911,7 +911,7 @@ else // Other attributes $parameters=array(); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; + print $hookmanager->resPrint; if (empty($reshook) && ! empty($extrafields->attribute_label)) { print $object->showOptionals($extrafields,'edit'); @@ -929,15 +929,15 @@ else $tdextra = ' class="titlefieldcreate"'; if (!empty($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED)) { - $tdextra = ' class="fieldrequired titlefieldcreate"'; + $tdextra = ' class="fieldrequired titlefieldcreate"'; } print '<tr class="liste_titre_add"><td'.$tdextra.'>'.$langs->trans("AccountancyCode").'</td>'; print '<td>'; if (!empty($conf->accounting->enabled)) { - print $formaccounting->select_account($object->account_number, 'account_number', 1, '', 1, 1); + print $formaccounting->select_account($object->account_number, 'account_number', 1, '', 1, 1); } else { - print '<input type="text" name="account_number" value="'.(GETPOST("account_number") ? GETPOST("account_number") : $object->account_number).'">'; + print '<input type="text" name="account_number" value="'.(GETPOST("account_number") ? GETPOST("account_number") : $object->account_number).'">'; } print '</td></tr>'; @@ -954,9 +954,9 @@ else if ($_POST["type"] == Account::TYPE_SAVINGS || $_POST["type"] == Account::TYPE_CURRENT) { - print '<br>'; + print '<br>'; - //print '<div class="underbanner clearboth"></div>'; + //print '<div class="underbanner clearboth"></div>'; print '<table class="border" width="100%">'; diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index 7dff138f8499c2f9bf39ab6fb096f4f93992ea2b..1634ec4bf5f0dfa8d8a494eb1dc9a05ad789ee5d 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -63,50 +63,50 @@ if ($action == 'confirm_paid' && $user->rights->tax->charges->creer && $confirm } if ($action == 'reopen' && $user->rights->tax->charges->creer) { - $result = $object->fetch($id); - if ($object->paye) - { - $result = $object->set_unpaid($user); - if ($result > 0) - { - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); - exit(); - } else { - setEventMessages($object->error, $object->errors, 'errors'); - } - } + $result = $object->fetch($id); + if ($object->paye) + { + $result = $object->set_unpaid($user); + if ($result > 0) + { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); + exit(); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } } // Link to a project if ($action == 'classin' && $user->rights->tax->charges->creer) { - $object->fetch($id); - $object->setProject(GETPOST('projectid')); + $object->fetch($id); + $object->setProject(GETPOST('projectid')); } if ($action == 'setlib' && $user->rights->tax->charges->creer) { - $object->fetch($id); - $result = $object->setValueFrom('libelle', GETPOST('lib'), '', '', 'text', '', $user, 'TAX_MODIFY'); - if ($result < 0) - setEventMessages($object->error, $object->errors, 'errors'); + $object->fetch($id); + $result = $object->setValueFrom('libelle', GETPOST('lib'), '', '', 'text', '', $user, 'TAX_MODIFY'); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); } // payment mode if ($action == 'setmode' && $user->rights->tax->charges->creer) { - $object->fetch($id); - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); - if ($result < 0) - setEventMessages($object->error, $object->errors, 'errors'); + $object->fetch($id); + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); } // bank account if ($action == 'setbankaccount' && $user->rights->tax->charges->creer) { - $object->fetch($id); - $result=$object->setBankAccount(GETPOST('fk_account', 'int')); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } + $object->fetch($id); + $result=$object->setBankAccount(GETPOST('fk_account', 'int')); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } } // Delete social contribution @@ -131,8 +131,8 @@ if ($action == 'add' && $user->rights->tax->charges->creer) { $dateech=dol_mktime(GETPOST('echhour'),GETPOST('echmin'),GETPOST('echsec'),GETPOST('echmonth'),GETPOST('echday'),GETPOST('echyear')); $dateperiod=dol_mktime(GETPOST('periodhour'),GETPOST('periodmin'),GETPOST('periodsec'),GETPOST('periodmonth'),GETPOST('periodday'),GETPOST('periodyear')); - $amount=price2num(GETPOST('amount')); - $actioncode=GETPOST('actioncode'); + $amount=price2num(GETPOST('amount')); + $actioncode=GETPOST('actioncode'); if (! $dateech) { @@ -166,8 +166,8 @@ if ($action == 'add' && $user->rights->tax->charges->creer) $object->date_ech = $dateech; $object->periode = $dateperiod; $object->amount = $amount; - $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->fk_account = GETPOST('fk_account', 'int'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->fk_account = GETPOST('fk_account', 'int'); $object->fk_project = GETPOST('fk_project'); $id=$object->create($user); @@ -182,43 +182,43 @@ if ($action == 'add' && $user->rights->tax->charges->creer) if ($action == 'update' && ! $_POST["cancel"] && $user->rights->tax->charges->creer) { - $dateech=dol_mktime(GETPOST('echhour'),GETPOST('echmin'),GETPOST('echsec'),GETPOST('echmonth'),GETPOST('echday'),GETPOST('echyear')); - $dateperiod=dol_mktime(GETPOST('periodhour'),GETPOST('periodmin'),GETPOST('periodsec'),GETPOST('periodmonth'),GETPOST('periodday'),GETPOST('periodyear')); - $amount=price2num(GETPOST('amount')); - - if (! $dateech) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateDue")), null, 'errors'); - $action = 'edit'; - } - elseif (! $dateperiod) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Period")), null, 'errors'); - $action = 'edit'; - } - elseif (empty($amount)) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors'); - $action = 'edit'; - } + $dateech=dol_mktime(GETPOST('echhour'),GETPOST('echmin'),GETPOST('echsec'),GETPOST('echmonth'),GETPOST('echday'),GETPOST('echyear')); + $dateperiod=dol_mktime(GETPOST('periodhour'),GETPOST('periodmin'),GETPOST('periodsec'),GETPOST('periodmonth'),GETPOST('periodday'),GETPOST('periodyear')); + $amount=price2num(GETPOST('amount')); + + if (! $dateech) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateDue")), null, 'errors'); + $action = 'edit'; + } + elseif (! $dateperiod) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Period")), null, 'errors'); + $action = 'edit'; + } + elseif (empty($amount)) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors'); + $action = 'edit'; + } elseif (! is_numeric($amount)) { setEventMessages($langs->trans("ErrorFieldMustBeANumeric",$langs->transnoentities("Amount")), null, 'errors'); $action = 'create'; } - else + else { - $result=$object->fetch($id); + $result=$object->fetch($id); - $object->date_ech = $dateech; - $object->periode = $dateperiod; - $object->amount = price2num($amount); + $object->date_ech = $dateech; + $object->periode = $dateperiod; + $object->amount = price2num($amount); - $result=$object->update($user); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - } + $result=$object->update($user); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } } } @@ -293,51 +293,51 @@ if ($action == 'create') { print load_fiche_titre($langs->trans("NewSocialContribution")); - $var=false; + $var=false; - print '<form name="charge" method="post" action="'.$_SERVER["PHP_SELF"].'">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="add">'; + print '<form name="charge" method="post" action="'.$_SERVER["PHP_SELF"].'">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="add">'; - dol_fiche_head(); + dol_fiche_head(); print '<table class="border" width="100%">'; - // Label - print "<tr>"; - print '<td class="titlefieldcreate fieldrequired">'; - print $langs->trans("Label"); - print '</td>'; - print '<td><input type="text" size="34" name="label" class="flat" value="'.dol_escape_htmltag(GETPOST('label','alpha')).'" autofocus></td>'; - print '</tr>'; - print '<tr>'; - - // Type - print '<td class="fieldrequired">'; - print $langs->trans("Type"); - print '</td>'; - print '<td>'; - $formsocialcontrib->select_type_socialcontrib(GETPOST("actioncode",'alpha')?GETPOST("actioncode",'alpha'):'','actioncode',1); - print '</td>'; - print '</tr>'; + // Label + print "<tr>"; + print '<td class="titlefieldcreate fieldrequired">'; + print $langs->trans("Label"); + print '</td>'; + print '<td><input type="text" size="34" name="label" class="flat" value="'.dol_escape_htmltag(GETPOST('label','alpha')).'" autofocus></td>'; + print '</tr>'; + print '<tr>'; + + // Type + print '<td class="fieldrequired">'; + print $langs->trans("Type"); + print '</td>'; + print '<td>'; + $formsocialcontrib->select_type_socialcontrib(GETPOST("actioncode",'alpha')?GETPOST("actioncode",'alpha'):'','actioncode',1); + print '</td>'; + print '</tr>'; // Date end period - print '<tr>'; - print '<td class="fieldrequired">'; - print $langs->trans("PeriodEndDate"); - print '</td>'; + print '<tr>'; + print '<td class="fieldrequired">'; + print $langs->trans("PeriodEndDate"); + print '</td>'; print '<td>'; - print $form->select_date(! empty($dateperiod)?$dateperiod:'-1', 'period', 0, 0, 0, 'charge', 1); + print $form->select_date(! empty($dateperiod)?$dateperiod:'-1', 'period', 0, 0, 0, 'charge', 1); print '</td>'; - print '</tr>'; + print '</tr>'; - // Amount - print '<tr>'; - print '<td class="fieldrequired">'; - print $langs->trans("Amount"); - print '</td>'; + // Amount + print '<tr>'; + print '<td class="fieldrequired">'; + print $langs->trans("Amount"); + print '</td>'; print '<td><input type="text" size="6" name="amount" class="flat" value="'.dol_escape_htmltag(GETPOST('amount','alpha')).'"></td>'; - print '</tr>'; + print '</tr>'; // Project if (! empty($conf->projet->enabled)) @@ -354,30 +354,30 @@ if ($action == 'create') print '</td></tr>'; } - // Payment Mode - print '<tr><td>' . $langs->trans('PaymentMode') . '</td><td colspan="2">'; - $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id'); - print '</td></tr>'; - - // Bank Account - if (! empty($conf->banque->enabled)) - { - print '<tr><td>' . $langs->trans('BankAccount') . '</td><td colspan="2">'; - $form->select_comptes($fk_account, 'fk_account', 0, '', 1); - print '</td></tr>'; - } - - // Date due - print '<tr>'; - print '<td class="fieldrequired">'; - print $langs->trans("DateDue"); - print '</td>'; - print '<td>'; - print $form->select_date(! empty($dateech)?$dateech:'-1', 'ech', 0, 0, 0, 'charge', 1); + // Payment Mode + print '<tr><td>' . $langs->trans('PaymentMode') . '</td><td colspan="2">'; + $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id'); + print '</td></tr>'; + + // Bank Account + if (! empty($conf->banque->enabled)) + { + print '<tr><td>' . $langs->trans('BankAccount') . '</td><td colspan="2">'; + $form->select_comptes($fk_account, 'fk_account', 0, '', 1); + print '</td></tr>'; + } + + // Date due + print '<tr>'; + print '<td class="fieldrequired">'; + print $langs->trans("DateDue"); + print '</td>'; + print '<td>'; + print $form->select_date(! empty($dateech)?$dateech:'-1', 'ech', 0, 0, 0, 'charge', 1); print '</td>'; - print "</tr>\n"; + print "</tr>\n"; - print '</table>'; + print '</table>'; dol_fiche_end(); @@ -387,7 +387,7 @@ if ($action == 'create') print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">'; print '</div>'; - print '</form>'; + print '</form>'; } /* *************************************************************************** */ @@ -398,7 +398,7 @@ if ($action == 'create') if ($id > 0) { $object = new ChargeSociales($db); - $result=$object->fetch($id); + $result=$object->fetch($id); if ($result > 0) { @@ -414,7 +414,7 @@ if ($id > 0) ); - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id,$langs->trans('CloneTax'),$langs->trans('ConfirmCloneTax',$object->ref),'confirm_clone',$formclone,'yes'); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id,$langs->trans('CloneTax'),$langs->trans('ConfirmCloneTax',$object->ref),'confirm_clone',$formclone,'yes'); } // Confirmation de la suppression de la charge @@ -445,34 +445,34 @@ if ($id > 0) // Project if (! empty($conf->projet->enabled)) { - $langs->load("projects"); - $morehtmlref.='<br>'.$langs->trans('Project') . ' '; - if ($user->rights->tax->charges->creer) - { - if ($action != 'classify') - $morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">'; - $morehtmlref.='<input type="hidden" name="action" value="classin">'; - $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $morehtmlref.=$formproject->select_projects(0, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - $morehtmlref.='</form>'; - } 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.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">'; - $morehtmlref.=$proj->ref; - $morehtmlref.='</a>'; - } else { - $morehtmlref.=''; - } - } + $langs->load("projects"); + $morehtmlref.='<br>'.$langs->trans('Project') . ' '; + if ($user->rights->tax->charges->creer) + { + if ($action != 'classify') + $morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">'; + $morehtmlref.='<input type="hidden" name="action" value="classin">'; + $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $morehtmlref.=$formproject->select_projects(0, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + $morehtmlref.='</form>'; + } 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.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">'; + $morehtmlref.=$proj->ref; + $morehtmlref.='</a>'; + } else { + $morehtmlref.=''; + } + } } $morehtmlref.='</div>'; @@ -492,7 +492,7 @@ if ($id > 0) print '<tr><td class="titlefield">'.$langs->trans("Type")."</td><td>".$object->type_libelle."</td>"; print "</tr>"; - // Period end date + // Period end date print "<tr><td>".$langs->trans("PeriodEndDate")."</td>"; print "<td>"; if ($action == 'edit') @@ -517,51 +517,51 @@ if ($id > 0) } // Amount - if ($action == 'edit') - { - print '<tr><td>'.$langs->trans("AmountTTC")."</td><td>"; - print '<input type="text" name="amount" size="12" class="flat" value="'.$object->amount.'">'; - print "</td></tr>"; - } - else { - print '<tr><td>'.$langs->trans("AmountTTC").'</td><td>'.price($object->amount,0,$outputlangs,1,-1,-1,$conf->currency).'</td></tr>'; - } - - // Mode of payment - print '<tr><td>'; - print '<table class="nobordernopadding" width="100%"><tr><td>'; - print $langs->trans('PaymentMode'); - print '</td>'; - if ($action != 'editmode') - print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmode&id=' . $object->id . '">' . img_edit($langs->trans('SetMode'), 1) . '</a></td>'; - print '</tr></table>'; - print '</td><td>'; - if ($action == 'editmode') { - $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id'); - } else { - $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'none'); - } - print '</td></tr>'; - - // Bank Account - if (! empty($conf->banque->enabled)) - { - print '<tr><td class="nowrap">'; - print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">'; - print $langs->trans('BankAccount'); - print '<td>'; - if ($action != 'editbankaccount' && $user->rights->tax->charges->creer) - print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>'; - print '</tr></table>'; - print '</td><td>'; - if ($action == 'editbankaccount') { - $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1); - } else { - $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none'); - } - print '</td>'; - print '</tr>'; - } + if ($action == 'edit') + { + print '<tr><td>'.$langs->trans("AmountTTC")."</td><td>"; + print '<input type="text" name="amount" size="12" class="flat" value="'.$object->amount.'">'; + print "</td></tr>"; + } + else { + print '<tr><td>'.$langs->trans("AmountTTC").'</td><td>'.price($object->amount,0,$outputlangs,1,-1,-1,$conf->currency).'</td></tr>'; + } + + // Mode of payment + print '<tr><td>'; + print '<table class="nobordernopadding" width="100%"><tr><td>'; + print $langs->trans('PaymentMode'); + print '</td>'; + if ($action != 'editmode') + print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmode&id=' . $object->id . '">' . img_edit($langs->trans('SetMode'), 1) . '</a></td>'; + print '</tr></table>'; + print '</td><td>'; + if ($action == 'editmode') { + $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id'); + } else { + $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'none'); + } + print '</td></tr>'; + + // Bank Account + if (! empty($conf->banque->enabled)) + { + print '<tr><td class="nowrap">'; + print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">'; + print $langs->trans('BankAccount'); + print '<td>'; + if ($action != 'editbankaccount' && $user->rights->tax->charges->creer) + print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>'; + print '</tr></table>'; + print '</td><td>'; + if ($action == 'editbankaccount') { + $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1); + } else { + $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none'); + } + print '</td>'; + print '</tr>'; + } print '</table>'; @@ -588,59 +588,59 @@ if ($id > 0) $resql = $db->query($sql); if ($resql) { - $totalpaye = 0; - - $num = $db->num_rows($resql); - $i = 0; $total = 0; - print '<table class="noborder paymenttable">'; - print '<tr class="liste_titre">'; - print '<td>'.$langs->trans("RefPayment").'</td>'; - print '<td>'.$langs->trans("Date").'</td>'; - print '<td>'.$langs->trans("Type").'</td>'; - print '<td align="right">'.$langs->trans("Amount").'</td>'; - print '</tr>'; - - $var=true; - if ($num > 0) - { - while ($i < $num) - { - $objp = $db->fetch_object($resql); - - print "<tr ".$bc[$var]."><td>"; - print '<a href="'.DOL_URL_ROOT.'/compta/payment_sc/card.php?id='.$objp->rowid.'">'.img_object($langs->trans("Payment"),"payment").' '.$objp->rowid.'</a></td>'; - print '<td>'.dol_print_date($db->jdate($objp->dp),'day')."</td>\n"; - $labeltype=$langs->trans("PaymentType".$objp->type_code)!=("PaymentType".$objp->type_code)?$langs->trans("PaymentType".$objp->type_code):$objp->paiement_type; - print "<td>".$labeltype.' '.$objp->num_paiement."</td>\n"; - print '<td align="right">'.price($objp->amount)."</td>\n"; - print "</tr>"; - $totalpaye += $objp->amount; - $i++; - } - } - else - { - - print '<tr class="oddeven"><td colspan="'.$nbcols.'" class="opacitymedium">'.$langs->trans("None").'</td><td></td><td></td><td></td></tr>'; - } - - //if ($object->status == ChargeSociales::STATUS_DRAFT) - //{ - print "<tr><td colspan=\"3\" align=\"right\">".$langs->trans("AlreadyPaid")." :</td><td align=\"right\">".price($totalpaye)."</td></tr>\n"; - print "<tr><td colspan=\"3\" align=\"right\">".$langs->trans("AmountExpected")." :</td><td align=\"right\">".price($object->amount)."</td></tr>\n"; - - $resteapayer = $object->amount - $totalpaye; - $cssforamountpaymentcomplete = 'amountpaymentcomplete'; - - print "<tr><td colspan=\"3\" align=\"right\">".$langs->trans("RemainderToPay")." :</td>"; - print '<td align="right"'.($resteapayer?' class="amountremaintopay"':(' class="'.$cssforamountpaymentcomplete.'"')).'>'.price($resteapayer)."</td></tr>\n"; - //} - print "</table>"; - $db->free($resql); + $totalpaye = 0; + + $num = $db->num_rows($resql); + $i = 0; $total = 0; + print '<table class="noborder paymenttable">'; + print '<tr class="liste_titre">'; + print '<td>'.$langs->trans("RefPayment").'</td>'; + print '<td>'.$langs->trans("Date").'</td>'; + print '<td>'.$langs->trans("Type").'</td>'; + print '<td align="right">'.$langs->trans("Amount").'</td>'; + print '</tr>'; + + $var=true; + if ($num > 0) + { + while ($i < $num) + { + $objp = $db->fetch_object($resql); + + print "<tr ".$bc[$var]."><td>"; + print '<a href="'.DOL_URL_ROOT.'/compta/payment_sc/card.php?id='.$objp->rowid.'">'.img_object($langs->trans("Payment"),"payment").' '.$objp->rowid.'</a></td>'; + print '<td>'.dol_print_date($db->jdate($objp->dp),'day')."</td>\n"; + $labeltype=$langs->trans("PaymentType".$objp->type_code)!=("PaymentType".$objp->type_code)?$langs->trans("PaymentType".$objp->type_code):$objp->paiement_type; + print "<td>".$labeltype.' '.$objp->num_paiement."</td>\n"; + print '<td align="right">'.price($objp->amount)."</td>\n"; + print "</tr>"; + $totalpaye += $objp->amount; + $i++; + } + } + else + { + + print '<tr class="oddeven"><td colspan="'.$nbcols.'" class="opacitymedium">'.$langs->trans("None").'</td><td></td><td></td><td></td></tr>'; + } + + //if ($object->status == ChargeSociales::STATUS_DRAFT) + //{ + print "<tr><td colspan=\"3\" align=\"right\">".$langs->trans("AlreadyPaid")." :</td><td align=\"right\">".price($totalpaye)."</td></tr>\n"; + print "<tr><td colspan=\"3\" align=\"right\">".$langs->trans("AmountExpected")." :</td><td align=\"right\">".price($object->amount)."</td></tr>\n"; + + $resteapayer = $object->amount - $totalpaye; + $cssforamountpaymentcomplete = 'amountpaymentcomplete'; + + print "<tr><td colspan=\"3\" align=\"right\">".$langs->trans("RemainderToPay")." :</td>"; + print '<td align="right"'.($resteapayer?' class="amountremaintopay"':(' class="'.$cssforamountpaymentcomplete.'"')).'>'.price($resteapayer)."</td></tr>\n"; + //} + print "</table>"; + $db->free($resql); } else { - dol_print_error($db); + dol_print_error($db); } print '</div>'; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 5d96945c17a6f7c0f29623af8d106673b0361ad9..a09ae3722d444c84512b72dc35ef72974cdaa6b0 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -40,24 +40,24 @@ */ abstract class CommonObject { - /** - * @var DoliDb Database handler (result of a new DoliDB) - */ + /** + * @var DoliDb Database handler (result of a new DoliDB) + */ public $db; /** * @var int The object identifier */ public $id; - /** - * @var string Error string - * @deprecated Use instead the array of error strings - * @see errors - */ - public $error; /** - * @var string[] Array of error strings - */ - public $errors=array(); + * @var string Error string + * @deprecated Use instead the array of error strings + * @see errors + */ + public $error; + /** + * @var string[] Array of error strings + */ + public $errors=array(); /** * @var string */ @@ -70,45 +70,45 @@ abstract class CommonObject * @var */ public $table_element_line; - /** - * @var string Key value used to track if data is coming from import wizard - */ - public $import_key; - /** - * @var mixed Contains data to manage extrafields - */ - public $array_options=array(); - /** - * @var int[] Array of linked objects ids. Loaded by ->fetchObjectLinked - */ - public $linkedObjectsIds; - /** - * @var mixed Array of linked objects. Loaded by ->fetchObjectLinked - */ - public $linkedObjects; - /** - * @var Object To store a cloned copy of object before to edit it and keep track of old properties - */ - public $oldcopy; - - /** - * @var string Column name of the ref field. - */ - protected $table_ref_field = ''; - - - - // Following vars are used by some objects only. We keep this property here in CommonObject to be able to provide common method using them. - - /** - * @var string[] Can be used to pass information when only object is provided to method - */ - public $context=array(); - - /** - * @var string Contains canvas name if record is an alternative canvas record - */ - public $canvas; + /** + * @var string Key value used to track if data is coming from import wizard + */ + public $import_key; + /** + * @var mixed Contains data to manage extrafields + */ + public $array_options=array(); + /** + * @var int[] Array of linked objects ids. Loaded by ->fetchObjectLinked + */ + public $linkedObjectsIds; + /** + * @var mixed Array of linked objects. Loaded by ->fetchObjectLinked + */ + public $linkedObjects; + /** + * @var Object To store a cloned copy of object before to edit it and keep track of old properties + */ + public $oldcopy; + + /** + * @var string Column name of the ref field. + */ + protected $table_ref_field = ''; + + + + // Following vars are used by some objects only. We keep this property here in CommonObject to be able to provide common method using them. + + /** + * @var string[] Can be used to pass information when only object is provided to method + */ + public $context=array(); + + /** + * @var string Contains canvas name if record is an alternative canvas record + */ + public $canvas; /** * @var Project The related project @@ -332,13 +332,13 @@ abstract class CommonObject */ public $location_incoterms; - public $name; - public $lastname; - public $firstname; - public $civility_id; + public $name; + public $lastname; + public $firstname; + public $civility_id; - // No constructor as it is an abstract class + // No constructor as it is an abstract class /** @@ -390,84 +390,84 @@ abstract class CommonObject return $this->error.(is_array($this->errors)?(($this->error!=''?', ':'').join(', ',$this->errors)):''); } - /** - * Return full name (civility+' '+name+' '+lastname) - * - * @param Translate $langs Language object for translation of civility - * @param int $option 0=No option, 1=Add civility - * @param int $nameorder -1=Auto, 0=Lastname+Firstname, 1=Firstname+Lastname, 2=Firstname - * @param int $maxlen Maximum length - * @return string String with full name - */ - function getFullName($langs,$option=0,$nameorder=-1,$maxlen=0) - { - //print "lastname=".$this->lastname." name=".$this->name." nom=".$this->nom."<br>\n"; - $lastname=$this->lastname; - $firstname=$this->firstname; - if (empty($lastname)) $lastname=(isset($this->lastname)?$this->lastname:(isset($this->name)?$this->name:(isset($this->nom)?$this->nom:(isset($this->societe)?$this->societe:(isset($this->company)?$this->company:''))))); - - $ret=''; - if ($option && $this->civility_id) - { - if ($langs->transnoentitiesnoconv("Civility".$this->civility_id)!="Civility".$this->civility_id) $ret.=$langs->transnoentitiesnoconv("Civility".$this->civility_id).' '; - else $ret.=$this->civility_id.' '; - } - - $ret.=dolGetFirstLastname($firstname, $lastname, $nameorder); - - return dol_trunc($ret,$maxlen); - } - - /** - * Return full address of contact - * - * @param int $withcountry 1=Add country into address string - * @param string $sep Separator to use to build string - * @return string Full address string - */ - function getFullAddress($withcountry=0,$sep="\n") - { - if ($withcountry && $this->country_id && (empty($this->country_code) || empty($this->country))) - { - require_once DOL_DOCUMENT_ROOT .'/core/lib/company.lib.php'; - $tmparray=getCountry($this->country_id,'all'); - $this->country_code=$tmparray['code']; - $this->country =$tmparray['label']; - } - - return dol_format_address($this, $withcountry, $sep); - } - - - /** - * Return full address for banner - * - * @param string $htmlkey HTML id to make banner content unique - * @param Object $object Object (thirdparty, thirdparty of contact for contact, null for a member) - * @return string Full address string - */ - function getBannerAddress($htmlkey, $object) - { - global $conf, $langs; - - $countriesusingstate=array('AU','US','IN','GB','ES','UK','TR'); // See also option MAIN_FORCE_STATE_INTO_ADDRESS - - $contactid=0; - $thirdpartyid=0; - if ($this->element == 'societe') - { - $thirdpartyid=$this->id; - } - if ($this->element == 'contact') - { - $contactid=$this->id; + /** + * Return full name (civility+' '+name+' '+lastname) + * + * @param Translate $langs Language object for translation of civility + * @param int $option 0=No option, 1=Add civility + * @param int $nameorder -1=Auto, 0=Lastname+Firstname, 1=Firstname+Lastname, 2=Firstname + * @param int $maxlen Maximum length + * @return string String with full name + */ + function getFullName($langs,$option=0,$nameorder=-1,$maxlen=0) + { + //print "lastname=".$this->lastname." name=".$this->name." nom=".$this->nom."<br>\n"; + $lastname=$this->lastname; + $firstname=$this->firstname; + if (empty($lastname)) $lastname=(isset($this->lastname)?$this->lastname:(isset($this->name)?$this->name:(isset($this->nom)?$this->nom:(isset($this->societe)?$this->societe:(isset($this->company)?$this->company:''))))); + + $ret=''; + if ($option && $this->civility_id) + { + if ($langs->transnoentitiesnoconv("Civility".$this->civility_id)!="Civility".$this->civility_id) $ret.=$langs->transnoentitiesnoconv("Civility".$this->civility_id).' '; + else $ret.=$this->civility_id.' '; + } + + $ret.=dolGetFirstLastname($firstname, $lastname, $nameorder); + + return dol_trunc($ret,$maxlen); + } + + /** + * Return full address of contact + * + * @param int $withcountry 1=Add country into address string + * @param string $sep Separator to use to build string + * @return string Full address string + */ + function getFullAddress($withcountry=0,$sep="\n") + { + if ($withcountry && $this->country_id && (empty($this->country_code) || empty($this->country))) + { + require_once DOL_DOCUMENT_ROOT .'/core/lib/company.lib.php'; + $tmparray=getCountry($this->country_id,'all'); + $this->country_code=$tmparray['code']; + $this->country =$tmparray['label']; + } + + return dol_format_address($this, $withcountry, $sep); + } + + + /** + * Return full address for banner + * + * @param string $htmlkey HTML id to make banner content unique + * @param Object $object Object (thirdparty, thirdparty of contact for contact, null for a member) + * @return string Full address string + */ + function getBannerAddress($htmlkey, $object) + { + global $conf, $langs; + + $countriesusingstate=array('AU','US','IN','GB','ES','UK','TR'); // See also option MAIN_FORCE_STATE_INTO_ADDRESS + + $contactid=0; + $thirdpartyid=0; + if ($this->element == 'societe') + { + $thirdpartyid=$this->id; + } + if ($this->element == 'contact') + { + $contactid=$this->id; $thirdpartyid=$object->fk_soc; - } - if ($this->element == 'user') - { - $contactid=$this->contact_id; + } + if ($this->element == 'user') + { + $contactid=$this->contact_id; $thirdpartyid=$object->fk_soc; - } + } $out='<!-- BEGIN part to show address block -->'; @@ -495,7 +495,7 @@ abstract class CommonObject } if (! empty($this->phone) || ! empty($this->phone_pro) || ! empty($this->phone_mobile) || ! empty($this->phone_perso) || ! empty($this->fax) || ! empty($this->office_phone) || ! empty($this->user_mobile) || ! empty($this->office_fax)) $out.=($outdone?'<br>':''); - if (! empty($this->phone) && empty($this->phone_pro)) { // For objects that store pro phone into ->phone + if (! empty($this->phone) && empty($this->phone_pro)) { // For objects that store pro phone into ->phone $out.=dol_print_phone($this->phone,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePro")); $outdone++; } if (! empty($this->phone_pro)) { @@ -510,7 +510,7 @@ abstract class CommonObject if (! empty($this->fax)) { $out.=dol_print_phone($this->fax,$this->country_code,$contactid,$thirdpartyid,'AC_FAX',' ','fax',$langs->trans("Fax")); $outdone++; } - if (! empty($this->office_phone)) { + if (! empty($this->office_phone)) { $out.=dol_print_phone($this->office_phone,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePro")); $outdone++; } if (! empty($this->user_mobile)) { @@ -527,7 +527,7 @@ abstract class CommonObject $out.=dol_print_email($this->email,$this->id,$object->id,'AC_EMAIL',0,0,1); $outdone++; } - if (! empty($this->url)) + if (! empty($this->url)) { $out.=dol_print_url($this->url,'_goout',0,1); $outdone++; @@ -542,2631 +542,2631 @@ abstract class CommonObject $out.='<!-- END Part to show address block -->'; return $out; - } - - /** - * Add a link between element $this->element and a contact - * - * @param int $fk_socpeople Id of thirdparty contact (if source = 'external') or id of user (if souce = 'internal') to link - * @param int $type_contact Type of contact (code or id). Must be id or code found into table llx_c_type_contact. For example: SALESREPFOLL - * @param string $source external=Contact extern (llx_socpeople), internal=Contact intern (llx_user) - * @param int $notrigger Disable all triggers - * @return int <0 if KO, >0 if OK - */ - function add_contact($fk_socpeople, $type_contact, $source='external',$notrigger=0) - { - global $user,$langs; - - - dol_syslog(get_class($this)."::add_contact $fk_socpeople, $type_contact, $source, $notrigger"); - - // Check parameters - if ($fk_socpeople <= 0) - { - $langs->load("errors"); - $this->error=$langs->trans("ErrorWrongValueForParameterX","1"); - dol_syslog(get_class($this)."::add_contact ".$this->error,LOG_ERR); - return -1; - } - if (! $type_contact) - { - $langs->load("errors"); - $this->error=$langs->trans("ErrorWrongValueForParameterX","2"); - dol_syslog(get_class($this)."::add_contact ".$this->error,LOG_ERR); - return -2; - } - - $id_type_contact=0; - if (is_numeric($type_contact)) - { - $id_type_contact=$type_contact; - } - else - { - // On recherche id type_contact - $sql = "SELECT tc.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; - $sql.= " WHERE tc.element='".$this->db->escape($this->element)."'"; - $sql.= " AND tc.source='".$this->db->escape($source)."'"; - $sql.= " AND tc.code='".$this->db->escape($type_contact)."' AND tc.active=1"; - //print $sql; - $resql=$this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - if ($obj) $id_type_contact=$obj->rowid; - } - } - - if ($id_type_contact == 0) - { - $this->error='CODE_NOT_VALID_FOR_THIS_ELEMENT'; - dol_syslog("CODE_NOT_VALID_FOR_THIS_ELEMENT"); - return -3; - } - - $datecreate = dol_now(); - - // Socpeople must have already been added by some a trigger, then we have to check it to avoid DB_ERROR_RECORD_ALREADY_EXISTS error - $TListeContacts=$this->liste_contact(-1, $source); - $already_added=false; - if(!empty($TListeContacts)) { - foreach($TListeContacts as $array_contact) { - if($array_contact['status'] == 4 && $array_contact['id'] == $fk_socpeople && $array_contact['fk_c_type_contact'] == $id_type_contact) { - $already_added=true; - break; - } - } - } - - if(!$already_added) { - - $this->db->begin(); - - // Insertion dans la base - $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_contact"; - $sql.= " (element_id, fk_socpeople, datecreate, statut, fk_c_type_contact) "; - $sql.= " VALUES (".$this->id.", ".$fk_socpeople." , " ; - $sql.= "'".$this->db->idate($datecreate)."'"; - $sql.= ", 4, ". $id_type_contact; - $sql.= ")"; - - $resql=$this->db->query($sql); - if ($resql) - { - if (! $notrigger) - { - $result=$this->call_trigger(strtoupper($this->element).'_ADD_CONTACT', $user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - } - - $this->db->commit(); - return 1; - } - else - { - if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $this->error=$this->db->errno(); - $this->db->rollback(); - echo 'err rollback'; - return -2; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } - } else return 0; - } - - /** - * Copy contact from one element to current - * - * @param CommonObject $objFrom Source element - * @param string $source Nature of contact ('internal' or 'external') - * @return int >0 if OK, <0 if KO - */ - function copy_linked_contact($objFrom, $source='internal') - { - $contacts = $objFrom->liste_contact(-1, $source); - foreach($contacts as $contact) - { - if ($this->add_contact($contact['id'], $contact['fk_c_type_contact'], $contact['source']) < 0) - { - $this->error=$this->db->lasterror(); - return -1; - } - } - return 1; - } - - /** - * Update a link to contact line - * - * @param int $rowid Id of line contact-element - * @param int $statut New status of link - * @param int $type_contact_id Id of contact type (not modified if 0) - * @param int $fk_socpeople Id of soc_people to update (not modified if 0) - * @return int <0 if KO, >= 0 if OK - */ - function update_contact($rowid, $statut, $type_contact_id=0, $fk_socpeople=0) - { - // Insertion dans la base - $sql = "UPDATE ".MAIN_DB_PREFIX."element_contact set"; - $sql.= " statut = ".$statut; - if ($type_contact_id) $sql.= ", fk_c_type_contact = '".$type_contact_id ."'"; - if ($fk_socpeople) $sql.= ", fk_socpeople = '".$fk_socpeople ."'"; - $sql.= " where rowid = ".$rowid; - $resql=$this->db->query($sql); - if ($resql) - { - return 0; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } - - /** - * Delete a link to contact line - * - * @param int $rowid Id of contact link line to delete - * @param int $notrigger Disable all triggers - * @return int >0 if OK, <0 if KO - */ - function delete_contact($rowid, $notrigger=0) - { - global $user; - - - $this->db->begin(); - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact"; - $sql.= " WHERE rowid =".$rowid; - - dol_syslog(get_class($this)."::delete_contact", LOG_DEBUG); - if ($this->db->query($sql)) - { - if (! $notrigger) - { - $result=$this->call_trigger(strtoupper($this->element).'_DELETE_CONTACT', $user); - if ($result < 0) { $this->db->rollback(); return -1; } - } - - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Delete all links between an object $this and all its contacts - * - * @param string $source '' or 'internal' or 'external' - * @param string $code Type of contact (code or id) - * @return int >0 if OK, <0 if KO - */ - function delete_linked_contact($source='',$code='') - { - $temp = array(); - $typeContact = $this->liste_type_contact($source,'',0,0,$code); - - foreach($typeContact as $key => $value) - { - array_push($temp,$key); - } - $listId = implode(",", $temp); - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact"; - $sql.= " WHERE element_id = ".$this->id; - if ($listId) - $sql.= " AND fk_c_type_contact IN (".$listId.")"; - - dol_syslog(get_class($this)."::delete_linked_contact", LOG_DEBUG); - if ($this->db->query($sql)) - { - return 1; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } - - /** - * Get array of all contacts for an object - * - * @param int $statut Status of links to get (-1=all) - * @param string $source Source of contact: external or thirdparty (llx_socpeople) or internal (llx_user) - * @param int $list 0:Return array contains all properties, 1:Return array contains just id - * @param string $code Filter on this code of contact type ('SHIPPING', 'BILLING', ...) - * @return array Array of contacts - */ - function liste_contact($statut=-1,$source='external',$list=0,$code='') - { - global $langs; - - $tab=array(); - - $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user - if ($source == 'internal') $sql.=", '-1' as socid, t.statut as statuscontact, t.login, t.photo"; - if ($source == 'external' || $source == 'thirdparty') $sql.=", t.fk_soc as socid, t.statut as statuscontact"; - $sql.= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; - $sql.= ", tc.source, tc.element, tc.code, tc.libelle"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact tc"; - $sql.= ", ".MAIN_DB_PREFIX."element_contact ec"; - if ($source == 'internal') $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."user t on ec.fk_socpeople = t.rowid"; - if ($source == 'external'|| $source == 'thirdparty') $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."socpeople t on ec.fk_socpeople = t.rowid"; - $sql.= " WHERE ec.element_id =".$this->id; - $sql.= " AND ec.fk_c_type_contact=tc.rowid"; - $sql.= " AND tc.element='".$this->db->escape($this->element)."'"; - if ($code) $sql.= " AND tc.code = '".$this->db->escape($code)."'"; - if ($source == 'internal') $sql.= " AND tc.source = 'internal'"; - if ($source == 'external' || $source == 'thirdparty') $sql.= " AND tc.source = 'external'"; - $sql.= " AND tc.active=1"; - if ($statut >= 0) $sql.= " AND ec.statut = '".$statut."'"; - $sql.=" ORDER BY t.lastname ASC"; - - dol_syslog(get_class($this)."::liste_contact", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $num=$this->db->num_rows($resql); - $i=0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - - if (! $list) - { - $transkey="TypeContact_".$obj->element."_".$obj->source."_".$obj->code; - $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle); - $tab[$i]=array('source'=>$obj->source,'socid'=>$obj->socid,'id'=>$obj->id, - 'nom'=>$obj->lastname, // For backward compatibility - 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email, 'login'=>$obj->login, 'photo'=>$obj->photo, 'statuscontact'=>$obj->statuscontact, - 'rowid'=>$obj->rowid, 'code'=>$obj->code, 'libelle'=>$libelle_type, 'status'=>$obj->statuslink, 'fk_c_type_contact'=>$obj->fk_c_type_contact); - } - else - { - $tab[$i]=$obj->id; - } - - $i++; - } - - return $tab; - } - else - { - $this->error=$this->db->lasterror(); - dol_print_error($this->db); - return -1; - } - } - - - /** - * Update status of a contact linked to object - * - * @param int $rowid Id of link between object and contact - * @return int <0 if KO, >=0 if OK - */ - function swapContactStatus($rowid) - { - $sql = "SELECT ec.datecreate, ec.statut, ec.fk_socpeople, ec.fk_c_type_contact,"; - $sql.= " tc.code, tc.libelle"; - //$sql.= ", s.fk_soc"; - $sql.= " FROM (".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc)"; - //$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as s ON ec.fk_socpeople=s.rowid"; // Si contact de type external, alors il est lie a une societe - $sql.= " WHERE ec.rowid =".$rowid; - $sql.= " AND ec.fk_c_type_contact=tc.rowid"; - $sql.= " AND tc.element = '".$this->db->escape($this->element)."'"; - - dol_syslog(get_class($this)."::swapContactStatus", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - $newstatut = ($obj->statut == 4) ? 5 : 4; - $result = $this->update_contact($rowid, $newstatut); - $this->db->free($resql); - return $result; - } - else - { - $this->error=$this->db->error(); - dol_print_error($this->db); - return -1; - } - - } - - /** - * Return array with list of possible values for type of contacts - * - * @param string $source 'internal', 'external' or 'all' - * @param string $order Sort order by : 'position', 'code', 'rowid'... - * @param int $option 0=Return array id->label, 1=Return array code->label - * @param int $activeonly 0=all status of contact, 1=only the active - * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE') - * @return array Array list of type of contacts (id->label if option=0, code->label if option=1) - */ - function liste_type_contact($source='internal', $order='position', $option=0, $activeonly=0, $code='') - { - global $langs; - - if (empty($order)) $order='position'; - if ($order == 'position') $order.=',code'; - - $tab = array(); - $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; - $sql.= " WHERE tc.element='".$this->db->escape($this->element)."'"; - if ($activeonly == 1) $sql.= " AND tc.active=1"; // only the active types - if (! empty($source) && $source != 'all') $sql.= " AND tc.source='".$this->db->escape($source)."'"; - if (! empty($code)) $sql.= " AND tc.code='".$this->db->escape($code)."'"; - $sql.= $this->db->order($order,'ASC'); - - //print "sql=".$sql; - $resql=$this->db->query($sql); - if ($resql) - { - $num=$this->db->num_rows($resql); - $i=0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - - $transkey="TypeContact_".$this->element."_".$source."_".$obj->code; - $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle); - if (empty($option)) $tab[$obj->rowid]=$libelle_type; - else $tab[$obj->code]=$libelle_type; - $i++; - } - return $tab; - } - else - { - $this->error=$this->db->lasterror(); - //dol_print_error($this->db); - return null; - } - } - - /** - * Return id of contacts for a source and a contact code. - * Example: contact client de facturation ('external', 'BILLING') - * Example: contact client de livraison ('external', 'SHIPPING') - * Example: contact interne suivi paiement ('internal', 'SALESREPFOLL') - * - * @param string $source 'external' or 'internal' - * @param string $code 'BILLING', 'SHIPPING', 'SALESREPFOLL', ... - * @param int $status limited to a certain status - * @return array List of id for such contacts - */ - function getIdContact($source,$code,$status=0) - { - global $conf; - - $result=array(); - $i=0; - //cas particulier pour les expeditions - if($this->element=='shipping' && $this->origin_id != 0) { - $id=$this->origin_id; - $element='commande'; - } else { - $id=$this->id; - $element=$this->element; - } - - $sql = "SELECT ec.fk_socpeople"; - $sql.= " FROM ".MAIN_DB_PREFIX."element_contact as ec,"; - if ($source == 'internal') $sql.= " ".MAIN_DB_PREFIX."user as c,"; - if ($source == 'external') $sql.= " ".MAIN_DB_PREFIX."socpeople as c,"; - $sql.= " ".MAIN_DB_PREFIX."c_type_contact as tc"; - $sql.= " WHERE ec.element_id = ".$id; - $sql.= " AND ec.fk_socpeople = c.rowid"; - if ($source == 'internal') $sql.= " AND c.entity IN (0,".$conf->entity.")"; - if ($source == 'external') $sql.= " AND c.entity IN (".getEntity('societe').")"; - $sql.= " AND ec.fk_c_type_contact = tc.rowid"; - $sql.= " AND tc.element = '".$element."'"; - $sql.= " AND tc.source = '".$source."'"; - $sql.= " AND tc.code = '".$code."'"; - $sql.= " AND tc.active = 1"; - if ($status) $sql.= " AND ec.statut = ".$status; - - dol_syslog(get_class($this)."::getIdContact", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj = $this->db->fetch_object($resql)) - { - $result[$i]=$obj->fk_socpeople; - $i++; - } - } - else - { - $this->error=$this->db->error(); - return null; - } - - return $result; - } - - /** - * Load object contact with id=$this->contactid into $this->contact - * - * @param int $contactid Id du contact. Use this->contactid if empty. - * @return int <0 if KO, >0 if OK - */ - function fetch_contact($contactid=null) - { - if (empty($contactid)) $contactid=$this->contactid; - - if (empty($contactid)) return 0; - - require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; - $contact = new Contact($this->db); - $result=$contact->fetch($contactid); - $this->contact = $contact; - return $result; - } - - /** - * Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty - * - * @param int $force_thirdparty_id Force thirdparty id - * @return int <0 if KO, >0 if OK - */ - function fetch_thirdparty($force_thirdparty_id=0) - { - global $conf; - - if (empty($this->socid) && empty($this->fk_soc) && empty($this->fk_thirdparty) && empty($force_thirdparty_id)) - return 0; - - require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; - - $idtofetch = isset($this->socid) ? $this->socid : (isset($this->fk_soc) ? $this->fk_soc : $this->fk_thirdparty); - if ($force_thirdparty_id) - $idtofetch = $force_thirdparty_id; - - if ($idtofetch) { - $thirdparty = new Societe($this->db); - $result = $thirdparty->fetch($idtofetch); - $this->thirdparty = $thirdparty; - - // Use first price level if level not defined for third party - if (!empty($conf->global->PRODUIT_MULTIPRICES) && empty($this->thirdparty->price_level)) { - $this->thirdparty->price_level = 1; - } - - return $result; - } else - return -1; - } - - - /** - * Looks for an object with ref matching the wildcard provided - * It does only work when $this->table_ref_field is set - * - * @param string $ref Wildcard - * @return int >1 = OK, 0 = Not found or table_ref_field not defined, <0 = KO - */ - public function fetchOneLike($ref) - { - if (!$this->table_ref_field) { - return 0; - } - - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE '.$this->table_ref_field.' LIKE "'.$this->db->escape($ref).'" LIMIT 1'; - - $query = $this->db->query($sql); - - if (!$this->db->num_rows($query)) { - return 0; - } - - $result = $this->db->fetch_object($query); - - return $this->fetch($result->rowid); - } - - /** - * Load data for barcode into properties ->barcode_type* - * Properties ->barcode_type that is id of barcode. Type is used to find other properties, but - * if it is not defined, ->element must be defined to know default barcode type. - * - * @return int <0 if KO, 0 if can't guess type of barcode (ISBN, EAN13...), >0 if OK (all barcode properties loaded) - */ - function fetch_barcode() - { - global $conf; - - dol_syslog(get_class($this).'::fetch_barcode this->element='.$this->element.' this->barcode_type='.$this->barcode_type); - - $idtype=$this->barcode_type; - if (empty($idtype) && $idtype != '0') // If type of barcode no set, we try to guess. If set to '0' it means we forced to have type remain not defined - { - if ($this->element == 'product') $idtype = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE; - else if ($this->element == 'societe') $idtype = $conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY; - else dol_syslog('Call fetch_barcode with barcode_type not defined and cant be guessed', LOG_WARNING); - } - - if ($idtype > 0) - { - if (empty($this->barcode_type) || empty($this->barcode_type_code) || empty($this->barcode_type_label) || empty($this->barcode_type_coder)) // If data not already loaded - { - $sql = "SELECT rowid, code, libelle as label, coder"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_barcode_type"; - $sql.= " WHERE rowid = ".$idtype; - dol_syslog(get_class($this).'::fetch_barcode', LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - $this->barcode_type = $obj->rowid; - $this->barcode_type_code = $obj->code; - $this->barcode_type_label = $obj->label; - $this->barcode_type_coder = $obj->coder; - return 1; - } - else - { - dol_print_error($this->db); - return -1; - } - } - } - return 0; - } - - /** - * Charge le projet d'id $this->fk_project dans this->projet - * - * @return int <0 if KO, >=0 if OK - */ - function fetch_projet() - { - include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - - if (empty($this->fk_project) && ! empty($this->fk_projet)) $this->fk_project = $this->fk_projet; // For backward compatibility - if (empty($this->fk_project)) return 0; - - $project = new Project($this->db); - $result = $project->fetch($this->fk_project); - - $this->projet = $project; // deprecated - $this->project = $project; - return $result; - } - - /** - * Charge le user d'id userid dans this->user - * - * @param int $userid Id du contact - * @return int <0 if KO, >0 if OK - */ - function fetch_user($userid) - { - $user = new User($this->db); - $result=$user->fetch($userid); - $this->user = $user; - return $result; - } - - /** - * Read linked origin object - * - * @return void - */ - function fetch_origin() - { - if ($this->origin == 'shipping') $this->origin = 'expedition'; - if ($this->origin == 'delivery') $this->origin = 'livraison'; - - $origin = $this->origin; - - $classname = ucfirst($origin); - $this->$origin = new $classname($this->db); - $this->$origin->fetch($this->origin_id); - } - - /** - * Load object from specific field - * - * @param string $table Table element or element line - * @param string $field Field selected - * @param string $key Import key - * @return int <0 if KO, >0 if OK - */ - function fetchObjectFrom($table,$field,$key) - { - global $conf; - - $result=false; - - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$table; - $sql.= " WHERE ".$field." = '".$key."'"; - $sql.= " AND entity = ".$conf->entity; - - dol_syslog(get_class($this).'::fetchObjectFrom', LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - $result = $this->fetch($row[0]); - } - - return $result; - } - - /** - * Getter generic. Load value from a specific field - * - * @param string $table Table of element or element line - * @param int $id Element id - * @param string $field Field selected - * @return int <0 if KO, >0 if OK - */ - function getValueFrom($table, $id, $field) - { - $result=false; - if (!empty($id) && !empty($field) && !empty($table)) { - $sql = "SELECT ".$field." FROM ".MAIN_DB_PREFIX.$table; - $sql.= " WHERE rowid = ".$id; - - dol_syslog(get_class($this).'::getValueFrom', LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - $result = $row[0]; - } - } - return $result; - } - - /** - * Setter generic. Update a specific field into database. - * Warning: Trigger is run only if param trigkey is provided. - * - * @param string $field Field to update - * @param mixed $value New value - * @param string $table To force other table element or element line (should not be used) - * @param int $id To force other object id (should not be used) - * @param string $format Data format ('text', 'date'). 'text' is used if not defined - * @param string $id_field To force rowid field name. 'rowid' is used if not defined - * @param User|string $fuser Update the user of last update field with this user. If not provided, current user is used except if value is 'none' - * @param string $trigkey Trigger key to run (in most cases something like 'XXX_MODIFY') - * @return int <0 if KO, >0 if OK - */ - function setValueFrom($field, $value, $table='', $id=null, $format='', $id_field='', $fuser=null, $trigkey='') - { - global $user,$langs,$conf; - - if (empty($table)) $table=$this->table_element; - if (empty($id)) $id=$this->id; - if (empty($format)) $format='text'; - if (empty($id_field)) $id_field='rowid'; - - $error=0; - - $this->db->begin(); - - // Special case - if ($table == 'product' && $field == 'note_private') $field='note'; - - $sql = "UPDATE ".MAIN_DB_PREFIX.$table." SET "; - if ($format == 'text') $sql.= $field." = '".$this->db->escape($value)."'"; - else if ($format == 'int') $sql.= $field." = ".$this->db->escape($value); - else if ($format == 'date') $sql.= $field." = ".($value ? "'".$this->db->idate($value)."'" : "null"); - if (! empty($fuser) && is_object($fuser)) $sql.=", fk_user_modif = ".$fuser->id; - elseif (empty($fuser) || $fuser != 'none') $sql.=", fk_user_modif = ".$user->id; - $sql.= " WHERE ".$id_field." = ".$id; - - dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - if ($trigkey) - { - $result=$this->call_trigger($trigkey, (! empty($fuser) && is_object($fuser)) ? $fuser : $user); // This may set this->errors - if ($result < 0) $error++; - } - - if (! $error) - { - if (property_exists($this, $field)) $this->$field = $value; - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -2; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Load properties id_previous and id_next - * - * @param string $filter Optional filter. Example: " AND (t.field1 = 'aa' OR t.field2 = 'bb')" - * @param string $fieldid Name of field to use for the select MAX and MIN - * @param int $nodbprefix Do not include DB prefix to forge table name - * @return int <0 if KO, >0 if OK - */ - function load_previous_next_ref($filter, $fieldid, $nodbprefix=0) - { - global $user; - - if (! $this->table_element) - { - dol_print_error('',get_class($this)."::load_previous_next_ref was called on objet with property table_element not defined"); - return -1; - } - if ($fieldid == 'none') return 1; + } - // this->ismultientitymanaged contains - // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - $alias = 's'; - if ($this->element == 'societe') $alias = 'te'; - - $sql = "SELECT MAX(te.".$fieldid.")"; - $sql.= " FROM ".(empty($nodbprefix)?MAIN_DB_PREFIX:'').$this->table_element." as te"; - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && empty($user->rights->societe->client->voir))) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity - if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; - $sql.= " WHERE te.".$fieldid." < '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) - if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id; - if (! empty($filter)) - { - if (! preg_match('/^\s*AND/i', $filter)) $sql.=" AND "; // For backward compatibility - $sql.=$filter; - } - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element, 1).')'; - - //print $filter.' '.$sql."<br>"; - $result = $this->db->query($sql); - if (! $result) - { - $this->error=$this->db->lasterror(); - return -1; - } - $row = $this->db->fetch_row($result); - $this->ref_previous = $row[0]; - - - $sql = "SELECT MIN(te.".$fieldid.")"; - $sql.= " FROM ".(empty($nodbprefix)?MAIN_DB_PREFIX:'').$this->table_element." as te"; - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity - if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; - $sql.= " WHERE te.".$fieldid." > '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) - if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id; - if (! empty($filter)) - { - if (! preg_match('/^\s*AND/i', $filter)) $sql.=" AND "; // For backward compatibility - $sql.=$filter; - } - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element, 1).')'; - // Rem: Bug in some mysql version: SELECT MIN(rowid) FROM llx_socpeople WHERE rowid > 1 when one row in database with rowid=1, returns 1 instead of null - - //print $sql."<br>"; - $result = $this->db->query($sql); - if (! $result) - { - $this->error=$this->db->lasterror(); - return -2; - } - $row = $this->db->fetch_row($result); - $this->ref_next = $row[0]; - - return 1; - } - - - /** - * Return list of id of contacts of project - * - * @param string $source Source of contact: external (llx_socpeople) or internal (llx_user) or thirdparty (llx_societe) - * @return array Array of id of contacts (if source=external or internal) - * Array of id of third parties with at least one contact on project (if source=thirdparty) - */ - function getListContactId($source='external') - { - $contactAlreadySelected = array(); - $tab = $this->liste_contact(-1,$source); - $num=count($tab); - $i = 0; - while ($i < $num) - { - if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid']; - else $contactAlreadySelected[$i] = $tab[$i]['id']; - $i++; - } - return $contactAlreadySelected; - } - - - /** - * Link element with a project - * - * @param int $projectid Project id to link element to - * @return int <0 if KO, >0 if OK - */ - function setProject($projectid) - { - if (! $this->table_element) - { - dol_syslog(get_class($this)."::setProject was called on objet with property table_element not defined",LOG_ERR); - return -1; - } + /** + * Add a link between element $this->element and a contact + * + * @param int $fk_socpeople Id of thirdparty contact (if source = 'external') or id of user (if souce = 'internal') to link + * @param int $type_contact Type of contact (code or id). Must be id or code found into table llx_c_type_contact. For example: SALESREPFOLL + * @param string $source external=Contact extern (llx_socpeople), internal=Contact intern (llx_user) + * @param int $notrigger Disable all triggers + * @return int <0 if KO, >0 if OK + */ + function add_contact($fk_socpeople, $type_contact, $source='external',$notrigger=0) + { + global $user,$langs; - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - if ($this->table_element == 'actioncomm') - { - if ($projectid) $sql.= ' SET fk_project = '.$projectid; - else $sql.= ' SET fk_project = NULL'; - $sql.= ' WHERE id = '.$this->id; - } - else - { - if ($projectid) $sql.= ' SET fk_projet = '.$projectid; - else $sql.= ' SET fk_projet = NULL'; - $sql.= ' WHERE rowid = '.$this->id; - } - dol_syslog(get_class($this)."::setProject", LOG_DEBUG); - if ($this->db->query($sql)) - { - $this->fk_project = $projectid; - return 1; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Change the payments methods - * - * @param int $id Id of new payment method - * @return int >0 if OK, <0 if KO - */ - function setPaymentMethods($id) - { - dol_syslog(get_class($this).'::setPaymentMethods('.$id.')'); - if ($this->statut >= 0 || $this->element == 'societe') - { - // TODO uniformize field name - $fieldname = 'fk_mode_reglement'; - if ($this->element == 'societe') $fieldname = 'mode_reglement'; - if (get_class($this) == 'Fournisseur') $fieldname = 'mode_reglement_supplier'; - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET '.$fieldname.' = '.$id; - $sql .= ' WHERE rowid='.$this->id; - - if ($this->db->query($sql)) - { - $this->mode_reglement_id = $id; - // for supplier - if (get_class($this) == 'Fournisseur') $this->mode_reglement_supplier_id = $id; - return 1; - } - else - { - dol_syslog(get_class($this).'::setPaymentMethods Erreur '.$sql.' - '.$this->db->error()); - $this->error=$this->db->error(); - return -1; - } - } - else - { - dol_syslog(get_class($this).'::setPaymentMethods, status of the object is incompatible'); - $this->error='Status of the object is incompatible '.$this->statut; - return -2; - } - } - - /** - * Change the multicurrency code - * - * @param string $code multicurrency code - * @return int >0 if OK, <0 if KO - */ - function setMulticurrencyCode($code) - { - dol_syslog(get_class($this).'::setMulticurrencyCode('.$id.')'); - if ($this->statut >= 0 || $this->element == 'societe') - { - $fieldname = 'multicurrency_code'; - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET '.$fieldname." = '".$this->db->escape($code)."'"; - $sql .= ' WHERE rowid='.$this->id; - - if ($this->db->query($sql)) - { - $this->multicurrency_code = $code; + dol_syslog(get_class($this)."::add_contact $fk_socpeople, $type_contact, $source, $notrigger"); - list($fk_multicurrency, $rate) = MultiCurrency::getIdAndTxFromCode($this->db, $code); - if ($rate) $this->setMulticurrencyRate($rate); + // Check parameters + if ($fk_socpeople <= 0) + { + $langs->load("errors"); + $this->error=$langs->trans("ErrorWrongValueForParameterX","1"); + dol_syslog(get_class($this)."::add_contact ".$this->error,LOG_ERR); + return -1; + } + if (! $type_contact) + { + $langs->load("errors"); + $this->error=$langs->trans("ErrorWrongValueForParameterX","2"); + dol_syslog(get_class($this)."::add_contact ".$this->error,LOG_ERR); + return -2; + } - return 1; - } - else - { - dol_syslog(get_class($this).'::setMulticurrencyCode Erreur '.$sql.' - '.$this->db->error()); - $this->error=$this->db->error(); - return -1; - } - } - else - { - dol_syslog(get_class($this).'::setMulticurrencyCode, status of the object is incompatible'); - $this->error='Status of the object is incompatible '.$this->statut; - return -2; - } - } - - /** - * Change the multicurrency rate - * - * @param double $rate multicurrency rate - * @param int $mode mode 1 : amounts in company currency will be recalculated, mode 2 : amounts in foreign currency - * @return int >0 if OK, <0 if KO - */ - function setMulticurrencyRate($rate, $mode=1) - { - dol_syslog(get_class($this).'::setMulticurrencyRate('.$id.')'); - if ($this->statut >= 0 || $this->element == 'societe') - { - $fieldname = 'multicurrency_tx'; - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET '.$fieldname.' = '.$rate; - $sql .= ' WHERE rowid='.$this->id; - - if ($this->db->query($sql)) - { - $this->multicurrency_tx = $rate; + $id_type_contact=0; + if (is_numeric($type_contact)) + { + $id_type_contact=$type_contact; + } + else + { + // On recherche id type_contact + $sql = "SELECT tc.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql.= " WHERE tc.element='".$this->db->escape($this->element)."'"; + $sql.= " AND tc.source='".$this->db->escape($source)."'"; + $sql.= " AND tc.code='".$this->db->escape($type_contact)."' AND tc.active=1"; + //print $sql; + $resql=$this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + if ($obj) $id_type_contact=$obj->rowid; + } + } - // Update line price - if (!empty($this->lines)) - { - foreach ($this->lines as &$line) - { - if($mode == 1) { - $line->subprice = 0; - } + if ($id_type_contact == 0) + { + $this->error='CODE_NOT_VALID_FOR_THIS_ELEMENT'; + dol_syslog("CODE_NOT_VALID_FOR_THIS_ELEMENT"); + return -3; + } - switch ($this->element) { - case 'propal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); - break; - case 'commande': - $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); - break; - case 'facture': - $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); - break; - case 'supplier_proposal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); - break; - case 'order_supplier': - $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); - break; - case 'invoice_supplier': - $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); - break; - default: - dol_syslog(get_class($this).'::setMulticurrencyRate no updateline defined', LOG_DEBUG); - break; - } + $datecreate = dol_now(); - } + // Socpeople must have already been added by some a trigger, then we have to check it to avoid DB_ERROR_RECORD_ALREADY_EXISTS error + $TListeContacts=$this->liste_contact(-1, $source); + $already_added=false; + if(!empty($TListeContacts)) { + foreach($TListeContacts as $array_contact) { + if($array_contact['status'] == 4 && $array_contact['id'] == $fk_socpeople && $array_contact['fk_c_type_contact'] == $id_type_contact) { + $already_added=true; + break; } + } + } - return 1; - } - else - { - dol_syslog(get_class($this).'::setMulticurrencyRate Erreur '.$sql.' - '.$this->db->error()); - $this->error=$this->db->error(); - return -1; - } - } - else - { - dol_syslog(get_class($this).'::setMulticurrencyRate, status of the object is incompatible'); - $this->error='Status of the object is incompatible '.$this->statut; - return -2; - } - } - - /** - * Change the payments terms - * - * @param int $id Id of new payment terms - * @return int >0 if OK, <0 if KO - */ - function setPaymentTerms($id) - { - dol_syslog(get_class($this).'::setPaymentTerms('.$id.')'); - if ($this->statut >= 0 || $this->element == 'societe') - { - // TODO uniformize field name - $fieldname = 'fk_cond_reglement'; - if ($this->element == 'societe') $fieldname = 'cond_reglement'; - if (get_class($this) == 'Fournisseur') $fieldname = 'cond_reglement_supplier'; - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET '.$fieldname.' = '.$id; - $sql .= ' WHERE rowid='.$this->id; - - if ($this->db->query($sql)) - { - $this->cond_reglement_id = $id; - // for supplier - if (get_class($this) == 'Fournisseur') $this->cond_reglement_supplier_id = $id; - $this->cond_reglement = $id; // for compatibility - return 1; - } - else - { - dol_syslog(get_class($this).'::setPaymentTerms Erreur '.$sql.' - '.$this->db->error()); - $this->error=$this->db->error(); - return -1; - } - } - else - { - dol_syslog(get_class($this).'::setPaymentTerms, status of the object is incompatible'); - $this->error='Status of the object is incompatible '.$this->statut; - return -2; - } - } - - /** - * Define delivery address - * @deprecated - * - * @param int $id Address id - * @return int <0 si ko, >0 si ok - */ - function setDeliveryAddress($id) - { - $fieldname = 'fk_delivery_address'; - if ($this->element == 'delivery' || $this->element == 'shipping') $fieldname = 'fk_address'; - - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ".$fieldname." = ".$id; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; - - if ($this->db->query($sql)) - { - $this->fk_delivery_address = $id; - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this).'::setDeliveryAddress Erreur '.$sql.' - '.$this->error); - return -1; - } - } - - - /** - * Change the shipping method - * - * @param int $shipping_method_id Id of shipping method - * @return int 1 if OK, 0 if KO - */ - function setShippingMethod($shipping_method_id) - { - if (! $this->table_element) { - dol_syslog(get_class($this)."::setShippingMethod was called on objet with property table_element not defined",LOG_ERR); - return -1; - } - if ($shipping_method_id<0) $shipping_method_id='NULL'; - dol_syslog(get_class($this).'::setShippingMethod('.$shipping_method_id.')'); - - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_shipping_method = ".$shipping_method_id; - $sql.= " WHERE rowid=".$this->id; - - if ($this->db->query($sql)) { - $this->shipping_method_id = ($shipping_method_id=='NULL')?null:$shipping_method_id; - return 1; - } else { - dol_syslog(get_class($this).'::setShippingMethod Error ', LOG_DEBUG); - $this->error=$this->db->error(); - return 0; - } - } - - - /** - * Change the warehouse - * - * @param int $warehouse_id Id of warehouse - * @return int 1 if OK, 0 if KO - */ - function setWarehouse($warehouse_id) - { - if (! $this->table_element) { - dol_syslog(get_class($this)."::setWarehouse was called on objet with property table_element not defined",LOG_ERR); - return -1; - } - if ($warehouse_id<0) $warehouse_id='NULL'; - dol_syslog(get_class($this).'::setWarehouse('.$warehouse_id.')'); - - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_warehouse = ".$warehouse_id; - $sql.= " WHERE rowid=".$this->id; - - if ($this->db->query($sql)) { - $this->warehouse_id = ($warehouse_id=='NULL')?null:$warehouse_id; - return 1; - } else { - dol_syslog(get_class($this).'::setWarehouse Error ', LOG_DEBUG); - $this->error=$this->db->error(); - return 0; - } - } - - - /** - * Set last model used by doc generator - * - * @param User $user User object that make change - * @param string $modelpdf Modele name - * @return int <0 if KO, >0 if OK - */ - function setDocModel($user, $modelpdf) - { - if (! $this->table_element) - { - dol_syslog(get_class($this)."::setDocModel was called on objet with property table_element not defined",LOG_ERR); - return -1; - } - - $newmodelpdf=dol_trunc($modelpdf,255); - - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET model_pdf = '".$this->db->escape($newmodelpdf)."'"; - $sql.= " WHERE rowid = ".$this->id; - // if ($this->element == 'facture') $sql.= " AND fk_statut < 2"; - // if ($this->element == 'propal') $sql.= " AND fk_statut = 0"; - - dol_syslog(get_class($this)."::setDocModel", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->modelpdf=$modelpdf; - return 1; - } - else - { - dol_print_error($this->db); - return 0; - } - } - - - /** - * Change the bank account - * - * @param int $fk_account Id of bank account - * @return int 1 if OK, 0 if KO - */ - function setBankAccount($fk_account) - { - if (! $this->table_element) { - dol_syslog(get_class($this)."::setBankAccount was called on objet with property table_element not defined",LOG_ERR); - return -1; - } - if ($fk_account<0) $fk_account='NULL'; - dol_syslog(get_class($this).'::setBankAccount('.$fk_account.')'); - - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_account = ".$fk_account; - $sql.= " WHERE rowid=".$this->id; - - if ($this->db->query($sql)) { - $this->fk_account = ($fk_account=='NULL')?null:$fk_account; - return 1; - } else { - dol_syslog(get_class($this).'::setBankAccount Error '.$sql.' - '.$this->db->error()); - $this->error=$this->db->error(); - return 0; - } - } - - // TODO: Move line related operations to CommonObjectLine? - - /** - * Save a new position (field rang) for details lines. - * You can choose to set position for lines with already a position or lines without any position defined. - * - * @param boolean $renum True to renum all already ordered lines, false to renum only not already ordered lines. - * @param string $rowidorder ASC or DESC - * @param boolean $fk_parent_line Table with fk_parent_line field or not - * @return int <0 if KO, >0 if OK - */ - function line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true) - { - if (! $this->table_element_line) - { - dol_syslog(get_class($this)."::line_order was called on objet with property table_element_line not defined",LOG_ERR); - return -1; - } - if (! $this->fk_element) - { - dol_syslog(get_class($this)."::line_order was called on objet with property fk_element not defined",LOG_ERR); - return -1; - } - - // Count number of lines to reorder (according to choice $renum) - $nl=0; - $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE '.$this->fk_element.'='.$this->id; - if (! $renum) $sql.= ' AND rang = 0'; - if ($renum) $sql.= ' AND rang <> 0'; + if(!$already_added) { - dol_syslog(get_class($this)."::line_order", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - $nl = $row[0]; - } - else dol_print_error($this->db); - if ($nl > 0) - { - // The goal of this part is to reorder all lines, with all children lines sharing the same - // counter that parents. - $rows=array(); + $this->db->begin(); - // We first search all lines that are parent lines (for multilevel details lines) - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - if ($fk_parent_line) $sql.= ' AND fk_parent_line IS NULL'; - $sql.= ' ORDER BY rang ASC, rowid '.$rowidorder; + // Insertion dans la base + $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_contact"; + $sql.= " (element_id, fk_socpeople, datecreate, statut, fk_c_type_contact) "; + $sql.= " VALUES (".$this->id.", ".$fk_socpeople." , " ; + $sql.= "'".$this->db->idate($datecreate)."'"; + $sql.= ", 4, ". $id_type_contact; + $sql.= ")"; - dol_syslog(get_class($this)."::line_order search all parent lines", LOG_DEBUG); - $resql = $this->db->query($sql); + $resql=$this->db->query($sql); if ($resql) { - $i=0; - $num = $this->db->num_rows($resql); - while ($i < $num) + if (! $notrigger) { - $row = $this->db->fetch_row($resql); - $rows[] = $row[0]; // Add parent line into array rows - $childrens = $this->getChildrenOfLine($row[0]); - if (! empty($childrens)) + $result=$this->call_trigger(strtoupper($this->element).'_ADD_CONTACT', $user); + if ($result < 0) { - foreach($childrens as $child) - { - array_push($rows, $child); - } + $this->db->rollback(); + return -1; } - $i++; } - // Now we set a new number for each lines (parent and children with children included into parent tree) - if (! empty($rows)) + $this->db->commit(); + return 1; + } + else + { + if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - foreach($rows as $key => $row) - { - $this->updateRangOfLine($row, ($key+1)); - } + $this->error=$this->db->errno(); + $this->db->rollback(); + echo 'err rollback'; + return -2; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; } } - else + } else return 0; + } + + /** + * Copy contact from one element to current + * + * @param CommonObject $objFrom Source element + * @param string $source Nature of contact ('internal' or 'external') + * @return int >0 if OK, <0 if KO + */ + function copy_linked_contact($objFrom, $source='internal') + { + $contacts = $objFrom->liste_contact(-1, $source); + foreach($contacts as $contact) + { + if ($this->add_contact($contact['id'], $contact['fk_c_type_contact'], $contact['source']) < 0) { - dol_print_error($this->db); + $this->error=$this->db->lasterror(); + return -1; } } return 1; } /** - * Get children of line + * Update a link to contact line * - * @param int $id Id of parent line - * @return array Array with list of children lines id + * @param int $rowid Id of line contact-element + * @param int $statut New status of link + * @param int $type_contact_id Id of contact type (not modified if 0) + * @param int $fk_socpeople Id of soc_people to update (not modified if 0) + * @return int <0 if KO, >= 0 if OK */ - function getChildrenOfLine($id) + function update_contact($rowid, $statut, $type_contact_id=0, $fk_socpeople=0) { - $rows=array(); - - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - $sql.= ' AND fk_parent_line = '.$id; - $sql.= ' ORDER BY rang ASC'; - - dol_syslog(get_class($this)."::getChildrenOfLine search children lines for line ".$id."", LOG_DEBUG); - $resql = $this->db->query($sql); + // Insertion dans la base + $sql = "UPDATE ".MAIN_DB_PREFIX."element_contact set"; + $sql.= " statut = ".$statut; + if ($type_contact_id) $sql.= ", fk_c_type_contact = '".$type_contact_id ."'"; + if ($fk_socpeople) $sql.= ", fk_socpeople = '".$fk_socpeople ."'"; + $sql.= " where rowid = ".$rowid; + $resql=$this->db->query($sql); if ($resql) { - $i=0; - $num = $this->db->num_rows($resql); - while ($i < $num) - { - $row = $this->db->fetch_row($resql); - $rows[$i] = $row[0]; - $i++; - } + return 0; + } + else + { + $this->error=$this->db->lasterror(); + return -1; } - - return $rows; } - /** - * Update a line to have a lower rank - * - * @param int $rowid Id of line - * @param boolean $fk_parent_line Table with fk_parent_line field or not - * @return void - */ - function line_up($rowid, $fk_parent_line=true) - { - $this->line_order(false, 'ASC', $fk_parent_line); - - // Get rang of line - $rang = $this->getRangOfLine($rowid); - - // Update position of line - $this->updateLineUp($rowid, $rang); - } - - /** - * Update a line to have a higher rank - * - * @param int $rowid Id of line - * @param boolean $fk_parent_line Table with fk_parent_line field or not - * @return void - */ - function line_down($rowid, $fk_parent_line=true) - { - $this->line_order(false, 'ASC', $fk_parent_line); - - // Get rang of line - $rang = $this->getRangOfLine($rowid); - - // Get max value for rang - $max = $this->line_max(); - - // Update position of line - $this->updateLineDown($rowid, $rang, $max); - } - /** - * Update position of line (rang) + * Delete a link to contact line * - * @param int $rowid Id of line - * @param int $rang Position - * @return void + * @param int $rowid Id of contact link line to delete + * @param int $notrigger Disable all triggers + * @return int >0 if OK, <0 if KO */ - function updateRangOfLine($rowid,$rang) + function delete_contact($rowid, $notrigger=0) { - $fieldposition = 'rang'; - if ($this->table_element_line == 'ecm_files') $fieldposition = 'position'; + global $user; - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET '.$fieldposition.' = '.$rang; - $sql.= ' WHERE rowid = '.$rowid; - dol_syslog(get_class($this)."::updateRangOfLine", LOG_DEBUG); - if (! $this->db->query($sql)) + $this->db->begin(); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact"; + $sql.= " WHERE rowid =".$rowid; + + dol_syslog(get_class($this)."::delete_contact", LOG_DEBUG); + if ($this->db->query($sql)) { - dol_print_error($this->db); + if (! $notrigger) + { + $result=$this->call_trigger(strtoupper($this->element).'_DELETE_CONTACT', $user); + if ($result < 0) { $this->db->rollback(); return -1; } + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; } } - /** - * Update position of line with ajax (rang) - * - * @param array $rows Array of rows - * @return void - */ - function line_ajaxorder($rows) - { - $num = count($rows); - for ($i = 0 ; $i < $num ; $i++) - { - $this->updateRangOfLine($rows[$i], ($i+1)); - } - } - - /** - * Update position of line up (rang) - * - * @param int $rowid Id of line - * @param int $rang Position - * @return void - */ - function updateLineUp($rowid,$rang) - { - if ($rang > 1 ) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.$rang ; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - $sql.= ' AND rang = '.($rang - 1); - if ($this->db->query($sql) ) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.($rang - 1); - $sql.= ' WHERE rowid = '.$rowid; - if (! $this->db->query($sql) ) - { - dol_print_error($this->db); - } - } - else - { - dol_print_error($this->db); - } - } - } - - /** - * Update position of line down (rang) - * - * @param int $rowid Id of line - * @param int $rang Position - * @param int $max Max - * @return void - */ - function updateLineDown($rowid,$rang,$max) - { - if ($rang < $max) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.$rang; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - $sql.= ' AND rang = '.($rang+1); - if ($this->db->query($sql) ) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.($rang+1); - $sql.= ' WHERE rowid = '.$rowid; - if (! $this->db->query($sql) ) - { - dol_print_error($this->db); - } - } - else - { - dol_print_error($this->db); - } - } - } - - /** - * Get position of line (rang) - * - * @param int $rowid Id of line - * @return int Value of rang in table of lines - */ - function getRangOfLine($rowid) - { - $sql = 'SELECT rang FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE rowid ='.$rowid; - - dol_syslog(get_class($this)."::getRangOfLine", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - return $row[0]; - } - } - - /** - * Get rowid of the line relative to its position - * - * @param int $rang Rang value - * @return int Rowid of the line - */ - function getIdOfLine($rang) - { - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - $sql.= ' AND rang = '.$rang; - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - return $row[0]; - } - } - - /** - * Get max value used for position of line (rang) - * - * @param int $fk_parent_line Parent line id - * @return int Max value of rang in table of lines - */ - function line_max($fk_parent_line=0) - { - // Search the last rang with fk_parent_line - if ($fk_parent_line) - { - $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - $sql.= ' AND fk_parent_line = '.$fk_parent_line; - - dol_syslog(get_class($this)."::line_max", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - if (! empty($row[0])) - { - return $row[0]; - } - else - { - return $this->getRangOfLine($fk_parent_line); - } - } - } - // If not, search the last rang of element - else - { - $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - - dol_syslog(get_class($this)."::line_max", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - return $row[0]; - } - } - } - - /** - * Update external ref of element - * - * @param string $ref_ext Update field ref_ext - * @return int <0 if KO, >0 if OK - */ - function update_ref_ext($ref_ext) - { - if (! $this->table_element) - { - dol_syslog(get_class($this)."::update_ref_ext was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref_ext = '".$this->db->escape($ref_ext)."'"; - $sql.= " WHERE ".(isset($this->table_rowid)?$this->table_rowid:'rowid')." = ". $this->id; + /** + * Delete all links between an object $this and all its contacts + * + * @param string $source '' or 'internal' or 'external' + * @param string $code Type of contact (code or id) + * @return int >0 if OK, <0 if KO + */ + function delete_linked_contact($source='',$code='') + { + $temp = array(); + $typeContact = $this->liste_type_contact($source,'',0,0,$code); - dol_syslog(get_class($this)."::update_ref_ext", LOG_DEBUG); - if ($this->db->query($sql)) - { - $this->ref_ext = $ref_ext; - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } - - /** - * Update note of element - * - * @param string $note New value for note - * @param string $suffix '', '_public' or '_private' - * @return int <0 if KO, >0 if OK - */ - function update_note($note,$suffix='') - { - global $user; - - if (! $this->table_element) - { - dol_syslog(get_class($this)."::update_note was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - if (! in_array($suffix,array('','_public','_private'))) + foreach($typeContact as $key => $value) { - dol_syslog(get_class($this)."::update_note Parameter suffix must be empty, '_private' or '_public'", LOG_ERR); - return -2; + array_push($temp,$key); } - // Special cas - //var_dump($this->table_element);exit; - if ($this->table_element == 'product') $suffix=''; + $listId = implode(",", $temp); - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET note".$suffix." = ".(!empty($note)?("'".$this->db->escape($note)."'"):"NULL"); - $sql.= " ,".(in_array($this->table_element, array('actioncomm', 'adherent', 'advtargetemailing', 'cronjob', 'establishment'))?"fk_user_mod":"fk_user_modif")." = ".$user->id; - $sql.= " WHERE rowid =". $this->id; - - dol_syslog(get_class($this)."::update_note", LOG_DEBUG); - if ($this->db->query($sql)) - { - if ($suffix == '_public') $this->note_public = $note; - else if ($suffix == '_private') $this->note_private = $note; - else - { - $this->note = $note; // deprecated - $this->note_private = $note; - } - return 1; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } - - /** - * Update public note (kept for backward compatibility) - * - * @param string $note New value for note - * @return int <0 if KO, >0 if OK - * @deprecated - * @see update_note() - */ - function update_note_public($note) - { - return $this->update_note($note,'_public'); - } - - /** - * Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines). - * Must be called at end of methods addline or updateline. - * - * @param int $exclspec >0 = Exclude special product (product_type=9) - * @param string $roundingadjust 'none'=Do nothing, 'auto'=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND if defined, or '0'), '0'=Force mode total of rounding, '1'=Force mode rounding of total - * @param int $nodatabaseupdate 1=Do not update database. Update only properties of object. - * @param Societe $seller If roundingadjust is '0' or '1' or maybe 'auto', it means we recalculate total for lines before calculating total for object and for this, we need seller object. - * @return int <0 if KO, >0 if OK - */ - function update_price($exclspec=0,$roundingadjust='none',$nodatabaseupdate=0,$seller=null) - { - global $conf; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact"; + $sql.= " WHERE element_id = ".$this->id; + if ($listId) + $sql.= " AND fk_c_type_contact IN (".$listId.")"; - // Some external module want no update price after a trigger because they have another method to calculate the total (ex: with an extrafield) - $MODULE = ""; - if ($this->element == 'propal') - $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_PROPOSAL"; - elseif ($this->element == 'order') - $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_ORDER"; - elseif ($this->element == 'facture') - $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_INVOICE"; - elseif ($this->element == 'facture_fourn') - $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_INVOICE"; - elseif ($this->element == 'order_supplier') - $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_ORDER"; - elseif ($this->element == 'supplier_proposal') - $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_PROPOSAL"; - - if (! empty($MODULE)) { - if (! empty($conf->global->$MODULE)) { - $modsactivated = explode(',', $conf->global->$MODULE); - foreach ($modsactivated as $mod) { - if ($conf->$mod->enabled) - return 1; // update was disabled by specific setup - } - } + dol_syslog(get_class($this)."::delete_linked_contact", LOG_DEBUG); + if ($this->db->query($sql)) + { + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; } + } - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + /** + * Get array of all contacts for an object + * + * @param int $statut Status of links to get (-1=all) + * @param string $source Source of contact: external or thirdparty (llx_socpeople) or internal (llx_user) + * @param int $list 0:Return array contains all properties, 1:Return array contains just id + * @param string $code Filter on this code of contact type ('SHIPPING', 'BILLING', ...) + * @return array Array of contacts + */ + function liste_contact($statut=-1,$source='external',$list=0,$code='') + { + global $langs; + + $tab=array(); + + $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user + if ($source == 'internal') $sql.=", '-1' as socid, t.statut as statuscontact, t.login, t.photo"; + if ($source == 'external' || $source == 'thirdparty') $sql.=", t.fk_soc as socid, t.statut as statuscontact"; + $sql.= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; + $sql.= ", tc.source, tc.element, tc.code, tc.libelle"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact tc"; + $sql.= ", ".MAIN_DB_PREFIX."element_contact ec"; + if ($source == 'internal') $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."user t on ec.fk_socpeople = t.rowid"; + if ($source == 'external'|| $source == 'thirdparty') $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."socpeople t on ec.fk_socpeople = t.rowid"; + $sql.= " WHERE ec.element_id =".$this->id; + $sql.= " AND ec.fk_c_type_contact=tc.rowid"; + $sql.= " AND tc.element='".$this->db->escape($this->element)."'"; + if ($code) $sql.= " AND tc.code = '".$this->db->escape($code)."'"; + if ($source == 'internal') $sql.= " AND tc.source = 'internal'"; + if ($source == 'external' || $source == 'thirdparty') $sql.= " AND tc.source = 'external'"; + $sql.= " AND tc.active=1"; + if ($statut >= 0) $sql.= " AND ec.statut = '".$statut."'"; + $sql.=" ORDER BY t.lastname ASC"; + + dol_syslog(get_class($this)."::liste_contact", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $num=$this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); - if ($roundingadjust == '-1') $roundingadjust='auto'; // For backward compatibility + if (! $list) + { + $transkey="TypeContact_".$obj->element."_".$obj->source."_".$obj->code; + $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle); + $tab[$i]=array('source'=>$obj->source,'socid'=>$obj->socid,'id'=>$obj->id, + 'nom'=>$obj->lastname, // For backward compatibility + 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email, 'login'=>$obj->login, 'photo'=>$obj->photo, 'statuscontact'=>$obj->statuscontact, + 'rowid'=>$obj->rowid, 'code'=>$obj->code, 'libelle'=>$libelle_type, 'status'=>$obj->statuslink, 'fk_c_type_contact'=>$obj->fk_c_type_contact); + } + else + { + $tab[$i]=$obj->id; + } - $forcedroundingmode=$roundingadjust; - if ($forcedroundingmode == 'auto' && isset($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)) $forcedroundingmode=$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND; - elseif ($forcedroundingmode == 'auto') $forcedroundingmode='0'; + $i++; + } - $error=0; + return $tab; + } + else + { + $this->error=$this->db->lasterror(); + dol_print_error($this->db); + return -1; + } + } - $multicurrency_tx = !empty($this->multicurrency_tx) ? $this->multicurrency_tx : 1; - // Define constants to find lines to sum - $fieldtva='total_tva'; - $fieldlocaltax1='total_localtax1'; - $fieldlocaltax2='total_localtax2'; - $fieldup='subprice'; - if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') + /** + * Update status of a contact linked to object + * + * @param int $rowid Id of link between object and contact + * @return int <0 if KO, >=0 if OK + */ + function swapContactStatus($rowid) + { + $sql = "SELECT ec.datecreate, ec.statut, ec.fk_socpeople, ec.fk_c_type_contact,"; + $sql.= " tc.code, tc.libelle"; + //$sql.= ", s.fk_soc"; + $sql.= " FROM (".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc)"; + //$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as s ON ec.fk_socpeople=s.rowid"; // Si contact de type external, alors il est lie a une societe + $sql.= " WHERE ec.rowid =".$rowid; + $sql.= " AND ec.fk_c_type_contact=tc.rowid"; + $sql.= " AND tc.element = '".$this->db->escape($this->element)."'"; + + dol_syslog(get_class($this)."::swapContactStatus", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) { - $fieldtva='tva'; - $fieldup='pu_ht'; + $obj = $this->db->fetch_object($resql); + $newstatut = ($obj->statut == 4) ? 5 : 4; + $result = $this->update_contact($rowid, $newstatut); + $this->db->free($resql); + return $result; } - if ($this->element == 'expensereport') + else { - $fieldup='value_unit'; + $this->error=$this->db->error(); + dol_print_error($this->db); + return -1; } - $sql = 'SELECT rowid, qty, '.$fieldup.' as up, remise_percent, total_ht, '.$fieldtva.' as total_tva, total_ttc, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2,'; - $sql.= ' tva_tx as vatrate, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, info_bits, product_type'; - if ($this->table_element_line == 'facturedet') $sql.= ', situation_percent'; - $sql.= ', multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; - if ($exclspec) + } + + /** + * Return array with list of possible values for type of contacts + * + * @param string $source 'internal', 'external' or 'all' + * @param string $order Sort order by : 'position', 'code', 'rowid'... + * @param int $option 0=Return array id->label, 1=Return array code->label + * @param int $activeonly 0=all status of contact, 1=only the active + * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE') + * @return array Array list of type of contacts (id->label if option=0, code->label if option=1) + */ + function liste_type_contact($source='internal', $order='position', $option=0, $activeonly=0, $code='') + { + global $langs; + + if (empty($order)) $order='position'; + if ($order == 'position') $order.=',code'; + + $tab = array(); + $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql.= " WHERE tc.element='".$this->db->escape($this->element)."'"; + if ($activeonly == 1) $sql.= " AND tc.active=1"; // only the active types + if (! empty($source) && $source != 'all') $sql.= " AND tc.source='".$this->db->escape($source)."'"; + if (! empty($code)) $sql.= " AND tc.code='".$this->db->escape($code)."'"; + $sql.= $this->db->order($order,'ASC'); + + //print "sql=".$sql; + $resql=$this->db->query($sql); + if ($resql) { - $product_field='product_type'; - if ($this->table_element_line == 'contratdet') $product_field=''; // contratdet table has no product_type field - if ($product_field) $sql.= ' AND '.$product_field.' <> 9'; + $num=$this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + $transkey="TypeContact_".$this->element."_".$source."_".$obj->code; + $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle); + if (empty($option)) $tab[$obj->rowid]=$libelle_type; + else $tab[$obj->code]=$libelle_type; + $i++; + } + return $tab; } - $sql.= ' ORDER by rowid'; // We want to be sure to always use same order of line to not change lines differently when option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND is used + else + { + $this->error=$this->db->lasterror(); + //dol_print_error($this->db); + return null; + } + } - dol_syslog(get_class($this)."::update_price", LOG_DEBUG); - $resql = $this->db->query($sql); + /** + * Return id of contacts for a source and a contact code. + * Example: contact client de facturation ('external', 'BILLING') + * Example: contact client de livraison ('external', 'SHIPPING') + * Example: contact interne suivi paiement ('internal', 'SALESREPFOLL') + * + * @param string $source 'external' or 'internal' + * @param string $code 'BILLING', 'SHIPPING', 'SALESREPFOLL', ... + * @param int $status limited to a certain status + * @return array List of id for such contacts + */ + function getIdContact($source,$code,$status=0) + { + global $conf; + + $result=array(); + $i=0; + //cas particulier pour les expeditions + if($this->element=='shipping' && $this->origin_id != 0) { + $id=$this->origin_id; + $element='commande'; + } else { + $id=$this->id; + $element=$this->element; + } + + $sql = "SELECT ec.fk_socpeople"; + $sql.= " FROM ".MAIN_DB_PREFIX."element_contact as ec,"; + if ($source == 'internal') $sql.= " ".MAIN_DB_PREFIX."user as c,"; + if ($source == 'external') $sql.= " ".MAIN_DB_PREFIX."socpeople as c,"; + $sql.= " ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql.= " WHERE ec.element_id = ".$id; + $sql.= " AND ec.fk_socpeople = c.rowid"; + if ($source == 'internal') $sql.= " AND c.entity IN (0,".$conf->entity.")"; + if ($source == 'external') $sql.= " AND c.entity IN (".getEntity('societe').")"; + $sql.= " AND ec.fk_c_type_contact = tc.rowid"; + $sql.= " AND tc.element = '".$element."'"; + $sql.= " AND tc.source = '".$source."'"; + $sql.= " AND tc.code = '".$code."'"; + $sql.= " AND tc.active = 1"; + if ($status) $sql.= " AND ec.statut = ".$status; + + dol_syslog(get_class($this)."::getIdContact", LOG_DEBUG); + $resql=$this->db->query($sql); if ($resql) { - $this->total_ht = 0; - $this->total_tva = 0; - $this->total_localtax1 = 0; - $this->total_localtax2 = 0; - $this->total_ttc = 0; - $total_ht_by_vats = array(); - $total_tva_by_vats = array(); - $total_ttc_by_vats = array(); - $this->multicurrency_total_ht = 0; - $this->multicurrency_total_tva = 0; - $this->multicurrency_total_ttc = 0; + while ($obj = $this->db->fetch_object($resql)) + { + $result[$i]=$obj->fk_socpeople; + $i++; + } + } + else + { + $this->error=$this->db->error(); + return null; + } - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + return $result; + } - // Note: There is no check on detail line and no check on total, if $forcedroundingmode = 'none' - if ($forcedroundingmode == '0') // Check if data on line are consistent. This may solve lines that were not consistent because set with $forcedroundingmode='auto' - { - $localtax_array=array($obj->localtax1_type,$obj->localtax1_tx,$obj->localtax2_type,$obj->localtax2_tx); - $tmpcal=calcul_price_total($obj->qty, $obj->up, $obj->remise_percent, $obj->vatrate, $obj->localtax1_tx, $obj->localtax2_tx, 0, 'HT', $obj->info_bits, $obj->product_type, $seller, $localtax_array, (isset($obj->situation_percent) ? $obj->situation_percent : 100), $multicurrency_tx); - $diff=price2num($tmpcal[1] - $obj->total_tva, 'MT', 1); - if ($diff) - { - $sqlfix="UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".$tmpcal[1].", total_ttc = ".$tmpcal[2]." WHERE rowid = ".$obj->rowid; - dol_syslog('We found unconsistent data into detailed line (difference of '.$diff.') for line rowid = '.$obj->rowid." (total vat of line calculated=".$tmpcal[1].", database=".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix); - $resqlfix=$this->db->query($sqlfix); - if (! $resqlfix) dol_print_error($this->db,'Failed to update line'); - $obj->total_tva = $tmpcal[1]; - $obj->total_ttc = $tmpcal[2]; - // - } - } + /** + * Load object contact with id=$this->contactid into $this->contact + * + * @param int $contactid Id du contact. Use this->contactid if empty. + * @return int <0 if KO, >0 if OK + */ + function fetch_contact($contactid=null) + { + if (empty($contactid)) $contactid=$this->contactid; - $this->total_ht += $obj->total_ht; // The field visible at end of line detail - $this->total_tva += $obj->total_tva; - $this->total_localtax1 += $obj->total_localtax1; - $this->total_localtax2 += $obj->total_localtax2; - $this->total_ttc += $obj->total_ttc; - $this->multicurrency_total_ht += $obj->multicurrency_total_ht; // The field visible at end of line detail - $this->multicurrency_total_tva += $obj->multicurrency_total_tva; - $this->multicurrency_total_ttc += $obj->multicurrency_total_ttc; + if (empty($contactid)) return 0; - if (! isset($total_ht_by_vats[$obj->vatrate])) $total_ht_by_vats[$obj->vatrate]=0; - if (! isset($total_tva_by_vats[$obj->vatrate])) $total_tva_by_vats[$obj->vatrate]=0; - if (! isset($total_ttc_by_vats[$obj->vatrate])) $total_ttc_by_vats[$obj->vatrate]=0; - $total_ht_by_vats[$obj->vatrate] += $obj->total_ht; - $total_tva_by_vats[$obj->vatrate] += $obj->total_tva; - $total_ttc_by_vats[$obj->vatrate] += $obj->total_ttc; + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + $contact = new Contact($this->db); + $result=$contact->fetch($contactid); + $this->contact = $contact; + return $result; + } - if ($forcedroundingmode == '1') // Check if we need adjustement onto line for vat. TODO This works on the company currency but not on multicurrency - { - $tmpvat=price2num($total_ht_by_vats[$obj->vatrate] * $obj->vatrate / 100, 'MT', 1); - $diff=price2num($total_tva_by_vats[$obj->vatrate]-$tmpvat, 'MT', 1); - //print 'Line '.$i.' rowid='.$obj->rowid.' vat_rate='.$obj->vatrate.' total_ht='.$obj->total_ht.' total_tva='.$obj->total_tva.' total_ttc='.$obj->total_ttc.' total_ht_by_vats='.$total_ht_by_vats[$obj->vatrate].' total_tva_by_vats='.$total_tva_by_vats[$obj->vatrate].' (new calculation = '.$tmpvat.') total_ttc_by_vats='.$total_ttc_by_vats[$obj->vatrate].($diff?" => DIFF":"")."<br>\n"; - if ($diff) - { - if (abs($diff) > 0.1) { dol_syslog('A rounding difference was detected into TOTAL but is too high to be corrected', LOG_WARNING); exit; } - $sqlfix="UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".($obj->total_tva - $diff).", total_ttc = ".($obj->total_ttc - $diff)." WHERE rowid = ".$obj->rowid; - dol_syslog('We found a difference of '.$diff.' for line rowid = '.$obj->rowid.". We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix); - $resqlfix=$this->db->query($sqlfix); - if (! $resqlfix) dol_print_error($this->db,'Failed to update line'); - $this->total_tva -= $diff; - $this->total_ttc -= $diff; - $total_tva_by_vats[$obj->vatrate] -= $diff; - $total_ttc_by_vats[$obj->vatrate] -= $diff; + /** + * Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty + * + * @param int $force_thirdparty_id Force thirdparty id + * @return int <0 if KO, >0 if OK + */ + function fetch_thirdparty($force_thirdparty_id=0) + { + global $conf; - } - } + if (empty($this->socid) && empty($this->fk_soc) && empty($this->fk_thirdparty) && empty($force_thirdparty_id)) + return 0; - $i++; - } + require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; - // Add revenue stamp to total - $this->total_ttc += isset($this->revenuestamp)?$this->revenuestamp:0; - $this->multicurrency_total_ttc += isset($this->revenuestamp)?($this->revenuestamp * $multicurrency_tx):0; + $idtofetch = isset($this->socid) ? $this->socid : (isset($this->fk_soc) ? $this->fk_soc : $this->fk_thirdparty); + if ($force_thirdparty_id) + $idtofetch = $force_thirdparty_id; - // Situations totals + if ($idtofetch) { + $thirdparty = new Societe($this->db); + $result = $thirdparty->fetch($idtofetch); + $this->thirdparty = $thirdparty; + + // Use first price level if level not defined for third party + if (!empty($conf->global->PRODUIT_MULTIPRICES) && empty($this->thirdparty->price_level)) { + $this->thirdparty->price_level = 1; + } + + return $result; + } else + return -1; + } + + + /** + * Looks for an object with ref matching the wildcard provided + * It does only work when $this->table_ref_field is set + * + * @param string $ref Wildcard + * @return int >1 = OK, 0 = Not found or table_ref_field not defined, <0 = KO + */ + public function fetchOneLike($ref) + { + if (!$this->table_ref_field) { + return 0; + } + + $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE '.$this->table_ref_field.' LIKE "'.$this->db->escape($ref).'" LIMIT 1'; + + $query = $this->db->query($sql); + + if (!$this->db->num_rows($query)) { + return 0; + } + + $result = $this->db->fetch_object($query); + + return $this->fetch($result->rowid); + } + + /** + * Load data for barcode into properties ->barcode_type* + * Properties ->barcode_type that is id of barcode. Type is used to find other properties, but + * if it is not defined, ->element must be defined to know default barcode type. + * + * @return int <0 if KO, 0 if can't guess type of barcode (ISBN, EAN13...), >0 if OK (all barcode properties loaded) + */ + function fetch_barcode() + { + global $conf; + + dol_syslog(get_class($this).'::fetch_barcode this->element='.$this->element.' this->barcode_type='.$this->barcode_type); + + $idtype=$this->barcode_type; + if (empty($idtype) && $idtype != '0') // If type of barcode no set, we try to guess. If set to '0' it means we forced to have type remain not defined + { + if ($this->element == 'product') $idtype = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE; + else if ($this->element == 'societe') $idtype = $conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY; + else dol_syslog('Call fetch_barcode with barcode_type not defined and cant be guessed', LOG_WARNING); + } + + if ($idtype > 0) + { + if (empty($this->barcode_type) || empty($this->barcode_type_code) || empty($this->barcode_type_label) || empty($this->barcode_type_coder)) // If data not already loaded + { + $sql = "SELECT rowid, code, libelle as label, coder"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_barcode_type"; + $sql.= " WHERE rowid = ".$idtype; + dol_syslog(get_class($this).'::fetch_barcode', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $this->barcode_type = $obj->rowid; + $this->barcode_type_code = $obj->code; + $this->barcode_type_label = $obj->label; + $this->barcode_type_coder = $obj->coder; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + } + return 0; + } + + /** + * Charge le projet d'id $this->fk_project dans this->projet + * + * @return int <0 if KO, >=0 if OK + */ + function fetch_projet() + { + include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + + if (empty($this->fk_project) && ! empty($this->fk_projet)) $this->fk_project = $this->fk_projet; // For backward compatibility + if (empty($this->fk_project)) return 0; + + $project = new Project($this->db); + $result = $project->fetch($this->fk_project); + + $this->projet = $project; // deprecated + $this->project = $project; + return $result; + } + + /** + * Charge le user d'id userid dans this->user + * + * @param int $userid Id du contact + * @return int <0 if KO, >0 if OK + */ + function fetch_user($userid) + { + $user = new User($this->db); + $result=$user->fetch($userid); + $this->user = $user; + return $result; + } + + /** + * Read linked origin object + * + * @return void + */ + function fetch_origin() + { + if ($this->origin == 'shipping') $this->origin = 'expedition'; + if ($this->origin == 'delivery') $this->origin = 'livraison'; + + $origin = $this->origin; + + $classname = ucfirst($origin); + $this->$origin = new $classname($this->db); + $this->$origin->fetch($this->origin_id); + } + + /** + * Load object from specific field + * + * @param string $table Table element or element line + * @param string $field Field selected + * @param string $key Import key + * @return int <0 if KO, >0 if OK + */ + function fetchObjectFrom($table,$field,$key) + { + global $conf; + + $result=false; + + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$table; + $sql.= " WHERE ".$field." = '".$key."'"; + $sql.= " AND entity = ".$conf->entity; + + dol_syslog(get_class($this).'::fetchObjectFrom', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + $result = $this->fetch($row[0]); + } + + return $result; + } + + /** + * Getter generic. Load value from a specific field + * + * @param string $table Table of element or element line + * @param int $id Element id + * @param string $field Field selected + * @return int <0 if KO, >0 if OK + */ + function getValueFrom($table, $id, $field) + { + $result=false; + if (!empty($id) && !empty($field) && !empty($table)) { + $sql = "SELECT ".$field." FROM ".MAIN_DB_PREFIX.$table; + $sql.= " WHERE rowid = ".$id; + + dol_syslog(get_class($this).'::getValueFrom', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + $result = $row[0]; + } + } + return $result; + } + + /** + * Setter generic. Update a specific field into database. + * Warning: Trigger is run only if param trigkey is provided. + * + * @param string $field Field to update + * @param mixed $value New value + * @param string $table To force other table element or element line (should not be used) + * @param int $id To force other object id (should not be used) + * @param string $format Data format ('text', 'date'). 'text' is used if not defined + * @param string $id_field To force rowid field name. 'rowid' is used if not defined + * @param User|string $fuser Update the user of last update field with this user. If not provided, current user is used except if value is 'none' + * @param string $trigkey Trigger key to run (in most cases something like 'XXX_MODIFY') + * @return int <0 if KO, >0 if OK + */ + function setValueFrom($field, $value, $table='', $id=null, $format='', $id_field='', $fuser=null, $trigkey='') + { + global $user,$langs,$conf; + + if (empty($table)) $table=$this->table_element; + if (empty($id)) $id=$this->id; + if (empty($format)) $format='text'; + if (empty($id_field)) $id_field='rowid'; + + $error=0; + + $this->db->begin(); + + // Special case + if ($table == 'product' && $field == 'note_private') $field='note'; + + $sql = "UPDATE ".MAIN_DB_PREFIX.$table." SET "; + if ($format == 'text') $sql.= $field." = '".$this->db->escape($value)."'"; + else if ($format == 'int') $sql.= $field." = ".$this->db->escape($value); + else if ($format == 'date') $sql.= $field." = ".($value ? "'".$this->db->idate($value)."'" : "null"); + if (! empty($fuser) && is_object($fuser)) $sql.=", fk_user_modif = ".$fuser->id; + elseif (empty($fuser) || $fuser != 'none') $sql.=", fk_user_modif = ".$user->id; + $sql.= " WHERE ".$id_field." = ".$id; + + dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + if ($trigkey) + { + $result=$this->call_trigger($trigkey, (! empty($fuser) && is_object($fuser)) ? $fuser : $user); // This may set this->errors + if ($result < 0) $error++; + } + + if (! $error) + { + if (property_exists($this, $field)) $this->$field = $value; + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + /** + * Load properties id_previous and id_next + * + * @param string $filter Optional filter. Example: " AND (t.field1 = 'aa' OR t.field2 = 'bb')" + * @param string $fieldid Name of field to use for the select MAX and MIN + * @param int $nodbprefix Do not include DB prefix to forge table name + * @return int <0 if KO, >0 if OK + */ + function load_previous_next_ref($filter, $fieldid, $nodbprefix=0) + { + global $user; + + if (! $this->table_element) + { + dol_print_error('',get_class($this)."::load_previous_next_ref was called on objet with property table_element not defined"); + return -1; + } + if ($fieldid == 'none') return 1; + + // this->ismultientitymanaged contains + // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + $alias = 's'; + if ($this->element == 'societe') $alias = 'te'; + + $sql = "SELECT MAX(te.".$fieldid.")"; + $sql.= " FROM ".(empty($nodbprefix)?MAIN_DB_PREFIX:'').$this->table_element." as te"; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && empty($user->rights->societe->client->voir))) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity + if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; + $sql.= " WHERE te.".$fieldid." < '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) + if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id; + if (! empty($filter)) + { + if (! preg_match('/^\s*AND/i', $filter)) $sql.=" AND "; // For backward compatibility + $sql.=$filter; + } + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element, 1).')'; + + //print $filter.' '.$sql."<br>"; + $result = $this->db->query($sql); + if (! $result) + { + $this->error=$this->db->lasterror(); + return -1; + } + $row = $this->db->fetch_row($result); + $this->ref_previous = $row[0]; + + + $sql = "SELECT MIN(te.".$fieldid.")"; + $sql.= " FROM ".(empty($nodbprefix)?MAIN_DB_PREFIX:'').$this->table_element." as te"; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity + if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; + $sql.= " WHERE te.".$fieldid." > '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) + if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id; + if (! empty($filter)) + { + if (! preg_match('/^\s*AND/i', $filter)) $sql.=" AND "; // For backward compatibility + $sql.=$filter; + } + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN ('.getEntity($this->element, 1).')'; + // Rem: Bug in some mysql version: SELECT MIN(rowid) FROM llx_socpeople WHERE rowid > 1 when one row in database with rowid=1, returns 1 instead of null + + //print $sql."<br>"; + $result = $this->db->query($sql); + if (! $result) + { + $this->error=$this->db->lasterror(); + return -2; + } + $row = $this->db->fetch_row($result); + $this->ref_next = $row[0]; + + return 1; + } + + + /** + * Return list of id of contacts of project + * + * @param string $source Source of contact: external (llx_socpeople) or internal (llx_user) or thirdparty (llx_societe) + * @return array Array of id of contacts (if source=external or internal) + * Array of id of third parties with at least one contact on project (if source=thirdparty) + */ + function getListContactId($source='external') + { + $contactAlreadySelected = array(); + $tab = $this->liste_contact(-1,$source); + $num=count($tab); + $i = 0; + while ($i < $num) + { + if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid']; + else $contactAlreadySelected[$i] = $tab[$i]['id']; + $i++; + } + return $contactAlreadySelected; + } + + + /** + * Link element with a project + * + * @param int $projectid Project id to link element to + * @return int <0 if KO, >0 if OK + */ + function setProject($projectid) + { + if (! $this->table_element) + { + dol_syslog(get_class($this)."::setProject was called on objet with property table_element not defined",LOG_ERR); + return -1; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + if ($this->table_element == 'actioncomm') + { + if ($projectid) $sql.= ' SET fk_project = '.$projectid; + else $sql.= ' SET fk_project = NULL'; + $sql.= ' WHERE id = '.$this->id; + } + else + { + if ($projectid) $sql.= ' SET fk_projet = '.$projectid; + else $sql.= ' SET fk_projet = NULL'; + $sql.= ' WHERE rowid = '.$this->id; + } + + dol_syslog(get_class($this)."::setProject", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->fk_project = $projectid; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Change the payments methods + * + * @param int $id Id of new payment method + * @return int >0 if OK, <0 if KO + */ + function setPaymentMethods($id) + { + dol_syslog(get_class($this).'::setPaymentMethods('.$id.')'); + if ($this->statut >= 0 || $this->element == 'societe') + { + // TODO uniformize field name + $fieldname = 'fk_mode_reglement'; + if ($this->element == 'societe') $fieldname = 'mode_reglement'; + if (get_class($this) == 'Fournisseur') $fieldname = 'mode_reglement_supplier'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET '.$fieldname.' = '.$id; + $sql .= ' WHERE rowid='.$this->id; + + if ($this->db->query($sql)) + { + $this->mode_reglement_id = $id; + // for supplier + if (get_class($this) == 'Fournisseur') $this->mode_reglement_supplier_id = $id; + return 1; + } + else + { + dol_syslog(get_class($this).'::setPaymentMethods Erreur '.$sql.' - '.$this->db->error()); + $this->error=$this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this).'::setPaymentMethods, status of the object is incompatible'); + $this->error='Status of the object is incompatible '.$this->statut; + return -2; + } + } + + /** + * Change the multicurrency code + * + * @param string $code multicurrency code + * @return int >0 if OK, <0 if KO + */ + function setMulticurrencyCode($code) + { + dol_syslog(get_class($this).'::setMulticurrencyCode('.$id.')'); + if ($this->statut >= 0 || $this->element == 'societe') + { + $fieldname = 'multicurrency_code'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET '.$fieldname." = '".$this->db->escape($code)."'"; + $sql .= ' WHERE rowid='.$this->id; + + if ($this->db->query($sql)) + { + $this->multicurrency_code = $code; + + list($fk_multicurrency, $rate) = MultiCurrency::getIdAndTxFromCode($this->db, $code); + if ($rate) $this->setMulticurrencyRate($rate); + + return 1; + } + else + { + dol_syslog(get_class($this).'::setMulticurrencyCode Erreur '.$sql.' - '.$this->db->error()); + $this->error=$this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this).'::setMulticurrencyCode, status of the object is incompatible'); + $this->error='Status of the object is incompatible '.$this->statut; + return -2; + } + } + + /** + * Change the multicurrency rate + * + * @param double $rate multicurrency rate + * @param int $mode mode 1 : amounts in company currency will be recalculated, mode 2 : amounts in foreign currency + * @return int >0 if OK, <0 if KO + */ + function setMulticurrencyRate($rate, $mode=1) + { + dol_syslog(get_class($this).'::setMulticurrencyRate('.$id.')'); + if ($this->statut >= 0 || $this->element == 'societe') + { + $fieldname = 'multicurrency_tx'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET '.$fieldname.' = '.$rate; + $sql .= ' WHERE rowid='.$this->id; + + if ($this->db->query($sql)) + { + $this->multicurrency_tx = $rate; + + // Update line price + if (!empty($this->lines)) + { + foreach ($this->lines as &$line) + { + if($mode == 1) { + $line->subprice = 0; + } + + switch ($this->element) { + case 'propal': + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + break; + case 'commande': + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + break; + case 'facture': + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); + break; + case 'supplier_proposal': + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); + break; + case 'order_supplier': + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + break; + case 'invoice_supplier': + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + break; + default: + dol_syslog(get_class($this).'::setMulticurrencyRate no updateline defined', LOG_DEBUG); + break; + } + + } + } + + return 1; + } + else + { + dol_syslog(get_class($this).'::setMulticurrencyRate Erreur '.$sql.' - '.$this->db->error()); + $this->error=$this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this).'::setMulticurrencyRate, status of the object is incompatible'); + $this->error='Status of the object is incompatible '.$this->statut; + return -2; + } + } + + /** + * Change the payments terms + * + * @param int $id Id of new payment terms + * @return int >0 if OK, <0 if KO + */ + function setPaymentTerms($id) + { + dol_syslog(get_class($this).'::setPaymentTerms('.$id.')'); + if ($this->statut >= 0 || $this->element == 'societe') + { + // TODO uniformize field name + $fieldname = 'fk_cond_reglement'; + if ($this->element == 'societe') $fieldname = 'cond_reglement'; + if (get_class($this) == 'Fournisseur') $fieldname = 'cond_reglement_supplier'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET '.$fieldname.' = '.$id; + $sql .= ' WHERE rowid='.$this->id; + + if ($this->db->query($sql)) + { + $this->cond_reglement_id = $id; + // for supplier + if (get_class($this) == 'Fournisseur') $this->cond_reglement_supplier_id = $id; + $this->cond_reglement = $id; // for compatibility + return 1; + } + else + { + dol_syslog(get_class($this).'::setPaymentTerms Erreur '.$sql.' - '.$this->db->error()); + $this->error=$this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this).'::setPaymentTerms, status of the object is incompatible'); + $this->error='Status of the object is incompatible '.$this->statut; + return -2; + } + } + + /** + * Define delivery address + * @deprecated + * + * @param int $id Address id + * @return int <0 si ko, >0 si ok + */ + function setDeliveryAddress($id) + { + $fieldname = 'fk_delivery_address'; + if ($this->element == 'delivery' || $this->element == 'shipping') $fieldname = 'fk_address'; + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ".$fieldname." = ".$id; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + + if ($this->db->query($sql)) + { + $this->fk_delivery_address = $id; + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this).'::setDeliveryAddress Erreur '.$sql.' - '.$this->error); + return -1; + } + } + + + /** + * Change the shipping method + * + * @param int $shipping_method_id Id of shipping method + * @return int 1 if OK, 0 if KO + */ + function setShippingMethod($shipping_method_id) + { + if (! $this->table_element) { + dol_syslog(get_class($this)."::setShippingMethod was called on objet with property table_element not defined",LOG_ERR); + return -1; + } + if ($shipping_method_id<0) $shipping_method_id='NULL'; + dol_syslog(get_class($this).'::setShippingMethod('.$shipping_method_id.')'); + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_shipping_method = ".$shipping_method_id; + $sql.= " WHERE rowid=".$this->id; + + if ($this->db->query($sql)) { + $this->shipping_method_id = ($shipping_method_id=='NULL')?null:$shipping_method_id; + return 1; + } else { + dol_syslog(get_class($this).'::setShippingMethod Error ', LOG_DEBUG); + $this->error=$this->db->error(); + return 0; + } + } + + + /** + * Change the warehouse + * + * @param int $warehouse_id Id of warehouse + * @return int 1 if OK, 0 if KO + */ + function setWarehouse($warehouse_id) + { + if (! $this->table_element) { + dol_syslog(get_class($this)."::setWarehouse was called on objet with property table_element not defined",LOG_ERR); + return -1; + } + if ($warehouse_id<0) $warehouse_id='NULL'; + dol_syslog(get_class($this).'::setWarehouse('.$warehouse_id.')'); + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_warehouse = ".$warehouse_id; + $sql.= " WHERE rowid=".$this->id; + + if ($this->db->query($sql)) { + $this->warehouse_id = ($warehouse_id=='NULL')?null:$warehouse_id; + return 1; + } else { + dol_syslog(get_class($this).'::setWarehouse Error ', LOG_DEBUG); + $this->error=$this->db->error(); + return 0; + } + } + + + /** + * Set last model used by doc generator + * + * @param User $user User object that make change + * @param string $modelpdf Modele name + * @return int <0 if KO, >0 if OK + */ + function setDocModel($user, $modelpdf) + { + if (! $this->table_element) + { + dol_syslog(get_class($this)."::setDocModel was called on objet with property table_element not defined",LOG_ERR); + return -1; + } + + $newmodelpdf=dol_trunc($modelpdf,255); + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET model_pdf = '".$this->db->escape($newmodelpdf)."'"; + $sql.= " WHERE rowid = ".$this->id; + // if ($this->element == 'facture') $sql.= " AND fk_statut < 2"; + // if ($this->element == 'propal') $sql.= " AND fk_statut = 0"; + + dol_syslog(get_class($this)."::setDocModel", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->modelpdf=$modelpdf; + return 1; + } + else + { + dol_print_error($this->db); + return 0; + } + } + + + /** + * Change the bank account + * + * @param int $fk_account Id of bank account + * @return int 1 if OK, 0 if KO + */ + function setBankAccount($fk_account) + { + if (! $this->table_element) { + dol_syslog(get_class($this)."::setBankAccount was called on objet with property table_element not defined",LOG_ERR); + return -1; + } + if ($fk_account<0) $fk_account='NULL'; + dol_syslog(get_class($this).'::setBankAccount('.$fk_account.')'); + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_account = ".$fk_account; + $sql.= " WHERE rowid=".$this->id; + + if ($this->db->query($sql)) { + $this->fk_account = ($fk_account=='NULL')?null:$fk_account; + return 1; + } else { + dol_syslog(get_class($this).'::setBankAccount Error '.$sql.' - '.$this->db->error()); + $this->error=$this->db->error(); + return 0; + } + } + + // TODO: Move line related operations to CommonObjectLine? + + /** + * Save a new position (field rang) for details lines. + * You can choose to set position for lines with already a position or lines without any position defined. + * + * @param boolean $renum True to renum all already ordered lines, false to renum only not already ordered lines. + * @param string $rowidorder ASC or DESC + * @param boolean $fk_parent_line Table with fk_parent_line field or not + * @return int <0 if KO, >0 if OK + */ + function line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true) + { + if (! $this->table_element_line) + { + dol_syslog(get_class($this)."::line_order was called on objet with property table_element_line not defined",LOG_ERR); + return -1; + } + if (! $this->fk_element) + { + dol_syslog(get_class($this)."::line_order was called on objet with property fk_element not defined",LOG_ERR); + return -1; + } + + // Count number of lines to reorder (according to choice $renum) + $nl=0; + $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE '.$this->fk_element.'='.$this->id; + if (! $renum) $sql.= ' AND rang = 0'; + if ($renum) $sql.= ' AND rang <> 0'; + + dol_syslog(get_class($this)."::line_order", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + $nl = $row[0]; + } + else dol_print_error($this->db); + if ($nl > 0) + { + // The goal of this part is to reorder all lines, with all children lines sharing the same + // counter that parents. + $rows=array(); + + // We first search all lines that are parent lines (for multilevel details lines) + $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + if ($fk_parent_line) $sql.= ' AND fk_parent_line IS NULL'; + $sql.= ' ORDER BY rang ASC, rowid '.$rowidorder; + + dol_syslog(get_class($this)."::line_order search all parent lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $i=0; + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $row = $this->db->fetch_row($resql); + $rows[] = $row[0]; // Add parent line into array rows + $childrens = $this->getChildrenOfLine($row[0]); + if (! empty($childrens)) + { + foreach($childrens as $child) + { + array_push($rows, $child); + } + } + $i++; + } + + // Now we set a new number for each lines (parent and children with children included into parent tree) + if (! empty($rows)) + { + foreach($rows as $key => $row) + { + $this->updateRangOfLine($row, ($key+1)); + } + } + } + else + { + dol_print_error($this->db); + } + } + return 1; + } + + /** + * Get children of line + * + * @param int $id Id of parent line + * @return array Array with list of children lines id + */ + function getChildrenOfLine($id) + { + $rows=array(); + + $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + $sql.= ' AND fk_parent_line = '.$id; + $sql.= ' ORDER BY rang ASC'; + + dol_syslog(get_class($this)."::getChildrenOfLine search children lines for line ".$id."", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $i=0; + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $row = $this->db->fetch_row($resql); + $rows[$i] = $row[0]; + $i++; + } + } + + return $rows; + } + + /** + * Update a line to have a lower rank + * + * @param int $rowid Id of line + * @param boolean $fk_parent_line Table with fk_parent_line field or not + * @return void + */ + function line_up($rowid, $fk_parent_line=true) + { + $this->line_order(false, 'ASC', $fk_parent_line); + + // Get rang of line + $rang = $this->getRangOfLine($rowid); + + // Update position of line + $this->updateLineUp($rowid, $rang); + } + + /** + * Update a line to have a higher rank + * + * @param int $rowid Id of line + * @param boolean $fk_parent_line Table with fk_parent_line field or not + * @return void + */ + function line_down($rowid, $fk_parent_line=true) + { + $this->line_order(false, 'ASC', $fk_parent_line); + + // Get rang of line + $rang = $this->getRangOfLine($rowid); + + // Get max value for rang + $max = $this->line_max(); + + // Update position of line + $this->updateLineDown($rowid, $rang, $max); + } + + /** + * Update position of line (rang) + * + * @param int $rowid Id of line + * @param int $rang Position + * @return void + */ + function updateRangOfLine($rowid,$rang) + { + $fieldposition = 'rang'; + if ($this->table_element_line == 'ecm_files') $fieldposition = 'position'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET '.$fieldposition.' = '.$rang; + $sql.= ' WHERE rowid = '.$rowid; + + dol_syslog(get_class($this)."::updateRangOfLine", LOG_DEBUG); + if (! $this->db->query($sql)) + { + dol_print_error($this->db); + } + } + + /** + * Update position of line with ajax (rang) + * + * @param array $rows Array of rows + * @return void + */ + function line_ajaxorder($rows) + { + $num = count($rows); + for ($i = 0 ; $i < $num ; $i++) + { + $this->updateRangOfLine($rows[$i], ($i+1)); + } + } + + /** + * Update position of line up (rang) + * + * @param int $rowid Id of line + * @param int $rang Position + * @return void + */ + function updateLineUp($rowid,$rang) + { + if ($rang > 1 ) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.$rang ; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + $sql.= ' AND rang = '.($rang - 1); + if ($this->db->query($sql) ) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.($rang - 1); + $sql.= ' WHERE rowid = '.$rowid; + if (! $this->db->query($sql) ) + { + dol_print_error($this->db); + } + } + else + { + dol_print_error($this->db); + } + } + } + + /** + * Update position of line down (rang) + * + * @param int $rowid Id of line + * @param int $rang Position + * @param int $max Max + * @return void + */ + function updateLineDown($rowid,$rang,$max) + { + if ($rang < $max) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.$rang; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + $sql.= ' AND rang = '.($rang+1); + if ($this->db->query($sql) ) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.($rang+1); + $sql.= ' WHERE rowid = '.$rowid; + if (! $this->db->query($sql) ) + { + dol_print_error($this->db); + } + } + else + { + dol_print_error($this->db); + } + } + } + + /** + * Get position of line (rang) + * + * @param int $rowid Id of line + * @return int Value of rang in table of lines + */ + function getRangOfLine($rowid) + { + $sql = 'SELECT rang FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE rowid ='.$rowid; + + dol_syslog(get_class($this)."::getRangOfLine", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + return $row[0]; + } + } + + /** + * Get rowid of the line relative to its position + * + * @param int $rang Rang value + * @return int Rowid of the line + */ + function getIdOfLine($rang) + { + $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + $sql.= ' AND rang = '.$rang; + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + return $row[0]; + } + } + + /** + * Get max value used for position of line (rang) + * + * @param int $fk_parent_line Parent line id + * @return int Max value of rang in table of lines + */ + function line_max($fk_parent_line=0) + { + // Search the last rang with fk_parent_line + if ($fk_parent_line) + { + $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + $sql.= ' AND fk_parent_line = '.$fk_parent_line; + + dol_syslog(get_class($this)."::line_max", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + if (! empty($row[0])) + { + return $row[0]; + } + else + { + return $this->getRangOfLine($fk_parent_line); + } + } + } + // If not, search the last rang of element + else + { + $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + + dol_syslog(get_class($this)."::line_max", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + return $row[0]; + } + } + } + + /** + * Update external ref of element + * + * @param string $ref_ext Update field ref_ext + * @return int <0 if KO, >0 if OK + */ + function update_ref_ext($ref_ext) + { + if (! $this->table_element) + { + dol_syslog(get_class($this)."::update_ref_ext was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET ref_ext = '".$this->db->escape($ref_ext)."'"; + $sql.= " WHERE ".(isset($this->table_rowid)?$this->table_rowid:'rowid')." = ". $this->id; + + dol_syslog(get_class($this)."::update_ref_ext", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->ref_ext = $ref_ext; + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + /** + * Update note of element + * + * @param string $note New value for note + * @param string $suffix '', '_public' or '_private' + * @return int <0 if KO, >0 if OK + */ + function update_note($note,$suffix='') + { + global $user; + + if (! $this->table_element) + { + dol_syslog(get_class($this)."::update_note was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + if (! in_array($suffix,array('','_public','_private'))) + { + dol_syslog(get_class($this)."::update_note Parameter suffix must be empty, '_private' or '_public'", LOG_ERR); + return -2; + } + // Special cas + //var_dump($this->table_element);exit; + if ($this->table_element == 'product') $suffix=''; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET note".$suffix." = ".(!empty($note)?("'".$this->db->escape($note)."'"):"NULL"); + $sql.= " ,".(in_array($this->table_element, array('actioncomm', 'adherent', 'advtargetemailing', 'cronjob', 'establishment'))?"fk_user_mod":"fk_user_modif")." = ".$user->id; + $sql.= " WHERE rowid =". $this->id; + + dol_syslog(get_class($this)."::update_note", LOG_DEBUG); + if ($this->db->query($sql)) + { + if ($suffix == '_public') $this->note_public = $note; + else if ($suffix == '_private') $this->note_private = $note; + else + { + $this->note = $note; // deprecated + $this->note_private = $note; + } + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Update public note (kept for backward compatibility) + * + * @param string $note New value for note + * @return int <0 if KO, >0 if OK + * @deprecated + * @see update_note() + */ + function update_note_public($note) + { + return $this->update_note($note,'_public'); + } + + /** + * Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines). + * Must be called at end of methods addline or updateline. + * + * @param int $exclspec >0 = Exclude special product (product_type=9) + * @param string $roundingadjust 'none'=Do nothing, 'auto'=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND if defined, or '0'), '0'=Force mode total of rounding, '1'=Force mode rounding of total + * @param int $nodatabaseupdate 1=Do not update database. Update only properties of object. + * @param Societe $seller If roundingadjust is '0' or '1' or maybe 'auto', it means we recalculate total for lines before calculating total for object and for this, we need seller object. + * @return int <0 if KO, >0 if OK + */ + function update_price($exclspec=0,$roundingadjust='none',$nodatabaseupdate=0,$seller=null) + { + global $conf; + + // Some external module want no update price after a trigger because they have another method to calculate the total (ex: with an extrafield) + $MODULE = ""; + if ($this->element == 'propal') + $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_PROPOSAL"; + elseif ($this->element == 'order') + $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_ORDER"; + elseif ($this->element == 'facture') + $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_INVOICE"; + elseif ($this->element == 'facture_fourn') + $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_INVOICE"; + elseif ($this->element == 'order_supplier') + $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_ORDER"; + elseif ($this->element == 'supplier_proposal') + $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_PROPOSAL"; + + if (! empty($MODULE)) { + if (! empty($conf->global->$MODULE)) { + $modsactivated = explode(',', $conf->global->$MODULE); + foreach ($modsactivated as $mod) { + if ($conf->$mod->enabled) + return 1; // update was disabled by specific setup + } + } + } + + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + if ($roundingadjust == '-1') $roundingadjust='auto'; // For backward compatibility + + $forcedroundingmode=$roundingadjust; + if ($forcedroundingmode == 'auto' && isset($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)) $forcedroundingmode=$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND; + elseif ($forcedroundingmode == 'auto') $forcedroundingmode='0'; + + $error=0; + + $multicurrency_tx = !empty($this->multicurrency_tx) ? $this->multicurrency_tx : 1; + + // Define constants to find lines to sum + $fieldtva='total_tva'; + $fieldlocaltax1='total_localtax1'; + $fieldlocaltax2='total_localtax2'; + $fieldup='subprice'; + if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') + { + $fieldtva='tva'; + $fieldup='pu_ht'; + } + if ($this->element == 'expensereport') + { + $fieldup='value_unit'; + } + + $sql = 'SELECT rowid, qty, '.$fieldup.' as up, remise_percent, total_ht, '.$fieldtva.' as total_tva, total_ttc, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2,'; + $sql.= ' tva_tx as vatrate, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, info_bits, product_type'; + if ($this->table_element_line == 'facturedet') $sql.= ', situation_percent'; + $sql.= ', multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; + if ($exclspec) + { + $product_field='product_type'; + if ($this->table_element_line == 'contratdet') $product_field=''; // contratdet table has no product_type field + if ($product_field) $sql.= ' AND '.$product_field.' <> 9'; + } + $sql.= ' ORDER by rowid'; // We want to be sure to always use same order of line to not change lines differently when option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND is used + + dol_syslog(get_class($this)."::update_price", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $this->total_ht = 0; + $this->total_tva = 0; + $this->total_localtax1 = 0; + $this->total_localtax2 = 0; + $this->total_ttc = 0; + $total_ht_by_vats = array(); + $total_tva_by_vats = array(); + $total_ttc_by_vats = array(); + $this->multicurrency_total_ht = 0; + $this->multicurrency_total_tva = 0; + $this->multicurrency_total_ttc = 0; + + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + // Note: There is no check on detail line and no check on total, if $forcedroundingmode = 'none' + if ($forcedroundingmode == '0') // Check if data on line are consistent. This may solve lines that were not consistent because set with $forcedroundingmode='auto' + { + $localtax_array=array($obj->localtax1_type,$obj->localtax1_tx,$obj->localtax2_type,$obj->localtax2_tx); + $tmpcal=calcul_price_total($obj->qty, $obj->up, $obj->remise_percent, $obj->vatrate, $obj->localtax1_tx, $obj->localtax2_tx, 0, 'HT', $obj->info_bits, $obj->product_type, $seller, $localtax_array, (isset($obj->situation_percent) ? $obj->situation_percent : 100), $multicurrency_tx); + $diff=price2num($tmpcal[1] - $obj->total_tva, 'MT', 1); + if ($diff) + { + $sqlfix="UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".$tmpcal[1].", total_ttc = ".$tmpcal[2]." WHERE rowid = ".$obj->rowid; + dol_syslog('We found unconsistent data into detailed line (difference of '.$diff.') for line rowid = '.$obj->rowid." (total vat of line calculated=".$tmpcal[1].", database=".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix); + $resqlfix=$this->db->query($sqlfix); + if (! $resqlfix) dol_print_error($this->db,'Failed to update line'); + $obj->total_tva = $tmpcal[1]; + $obj->total_ttc = $tmpcal[2]; + // + } + } + + $this->total_ht += $obj->total_ht; // The field visible at end of line detail + $this->total_tva += $obj->total_tva; + $this->total_localtax1 += $obj->total_localtax1; + $this->total_localtax2 += $obj->total_localtax2; + $this->total_ttc += $obj->total_ttc; + $this->multicurrency_total_ht += $obj->multicurrency_total_ht; // The field visible at end of line detail + $this->multicurrency_total_tva += $obj->multicurrency_total_tva; + $this->multicurrency_total_ttc += $obj->multicurrency_total_ttc; + + if (! isset($total_ht_by_vats[$obj->vatrate])) $total_ht_by_vats[$obj->vatrate]=0; + if (! isset($total_tva_by_vats[$obj->vatrate])) $total_tva_by_vats[$obj->vatrate]=0; + if (! isset($total_ttc_by_vats[$obj->vatrate])) $total_ttc_by_vats[$obj->vatrate]=0; + $total_ht_by_vats[$obj->vatrate] += $obj->total_ht; + $total_tva_by_vats[$obj->vatrate] += $obj->total_tva; + $total_ttc_by_vats[$obj->vatrate] += $obj->total_ttc; + + if ($forcedroundingmode == '1') // Check if we need adjustement onto line for vat. TODO This works on the company currency but not on multicurrency + { + $tmpvat=price2num($total_ht_by_vats[$obj->vatrate] * $obj->vatrate / 100, 'MT', 1); + $diff=price2num($total_tva_by_vats[$obj->vatrate]-$tmpvat, 'MT', 1); + //print 'Line '.$i.' rowid='.$obj->rowid.' vat_rate='.$obj->vatrate.' total_ht='.$obj->total_ht.' total_tva='.$obj->total_tva.' total_ttc='.$obj->total_ttc.' total_ht_by_vats='.$total_ht_by_vats[$obj->vatrate].' total_tva_by_vats='.$total_tva_by_vats[$obj->vatrate].' (new calculation = '.$tmpvat.') total_ttc_by_vats='.$total_ttc_by_vats[$obj->vatrate].($diff?" => DIFF":"")."<br>\n"; + if ($diff) + { + if (abs($diff) > 0.1) { dol_syslog('A rounding difference was detected into TOTAL but is too high to be corrected', LOG_WARNING); exit; } + $sqlfix="UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".($obj->total_tva - $diff).", total_ttc = ".($obj->total_ttc - $diff)." WHERE rowid = ".$obj->rowid; + dol_syslog('We found a difference of '.$diff.' for line rowid = '.$obj->rowid.". We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix); + $resqlfix=$this->db->query($sqlfix); + if (! $resqlfix) dol_print_error($this->db,'Failed to update line'); + $this->total_tva -= $diff; + $this->total_ttc -= $diff; + $total_tva_by_vats[$obj->vatrate] -= $diff; + $total_ttc_by_vats[$obj->vatrate] -= $diff; + + } + } + + $i++; + } + + // Add revenue stamp to total + $this->total_ttc += isset($this->revenuestamp)?$this->revenuestamp:0; + $this->multicurrency_total_ttc += isset($this->revenuestamp)?($this->revenuestamp * $multicurrency_tx):0; + + // Situations totals if ($this->situation_cycle_ref && $this->situation_counter > 1 && method_exists($this, 'get_prev_sits')) { $prev_sits = $this->get_prev_sits(); - foreach ($prev_sits as $sit) { // $sit is an object Facture loaded with a fetch. - $this->total_ht -= $sit->total_ht; - $this->total_tva -= $sit->total_tva; - $this->total_localtax1 -= $sit->total_localtax1; - $this->total_localtax2 -= $sit->total_localtax2; - $this->total_ttc -= $sit->total_ttc; - $this->multicurrency_total_ht -= $sit->multicurrency_total_ht; - $this->multicurrency_total_tva -= $sit->multicurrency_total_tva; - $this->multicurrency_total_ttc -= $sit->multicurrency_total_ttc; + foreach ($prev_sits as $sit) { // $sit is an object Facture loaded with a fetch. + $this->total_ht -= $sit->total_ht; + $this->total_tva -= $sit->total_tva; + $this->total_localtax1 -= $sit->total_localtax1; + $this->total_localtax2 -= $sit->total_localtax2; + $this->total_ttc -= $sit->total_ttc; + $this->multicurrency_total_ht -= $sit->multicurrency_total_ht; + $this->multicurrency_total_tva -= $sit->multicurrency_total_tva; + $this->multicurrency_total_ttc -= $sit->multicurrency_total_ttc; + } + } + + $this->db->free($resql); + + // Now update global field total_ht, total_ttc and tva + $fieldht='total_ht'; + $fieldtva='tva'; + $fieldlocaltax1='localtax1'; + $fieldlocaltax2='localtax2'; + $fieldttc='total_ttc'; + // Specific code for backward compatibility with old field names + if ($this->element == 'facture' || $this->element == 'facturerec') $fieldht='total'; + if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva='total_tva'; + if ($this->element == 'propal') $fieldttc='total'; + if ($this->element == 'expensereport') $fieldtva='total_tva'; + if ($this->element == 'supplier_proposal') $fieldttc='total'; + + if (empty($nodatabaseupdate)) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET'; + $sql .= " ".$fieldht."='".price2num($this->total_ht)."',"; + $sql .= " ".$fieldtva."='".price2num($this->total_tva)."',"; + $sql .= " ".$fieldlocaltax1."='".price2num($this->total_localtax1)."',"; + $sql .= " ".$fieldlocaltax2."='".price2num($this->total_localtax2)."',"; + $sql .= " ".$fieldttc."='".price2num($this->total_ttc)."'"; + $sql .= ", multicurrency_total_ht='".price2num($this->multicurrency_total_ht, 'MT', 1)."'"; + $sql .= ", multicurrency_total_tva='".price2num($this->multicurrency_total_tva, 'MT', 1)."'"; + $sql .= ", multicurrency_total_ttc='".price2num($this->multicurrency_total_ttc, 'MT', 1)."'"; + $sql .= ' WHERE rowid = '.$this->id; + + //print "xx".$sql; + dol_syslog(get_class($this)."::update_price", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error=$this->db->lasterror(); + $this->errors[]=$this->db->lasterror(); + } + } + + if (! $error) + { + return 1; + } + else + { + return -1; + } + } + else + { + dol_print_error($this->db,'Bad request in update_price'); + return -1; + } + } + + /** + * Add objects linked in llx_element_element. + * + * @param string $origin Linked element type + * @param int $origin_id Linked element id + * @return int <=0 if KO, >0 if OK + * @see fetchObjectLinked, updateObjectLinked, deleteObjectLinked + */ + function add_object_linked($origin=null, $origin_id=null) + { + $origin = (! empty($origin) ? $origin : $this->origin); + $origin_id = (! empty($origin_id) ? $origin_id : $this->origin_id); + + // Special case + if ($origin == 'order') $origin='commande'; + if ($origin == 'invoice') $origin='facture'; + + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; + $sql.= "fk_source"; + $sql.= ", sourcetype"; + $sql.= ", fk_target"; + $sql.= ", targettype"; + $sql.= ") VALUES ("; + $sql.= $origin_id; + $sql.= ", '".$this->db->escape($origin)."'"; + $sql.= ", ".$this->id; + $sql.= ", '".$this->db->escape($this->element)."'"; + $sql.= ")"; + + dol_syslog(get_class($this)."::add_object_linked", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return 0; + } + } + + /** + * Fetch array of objects linked to current object. Links are loaded into this->linkedObjects array and this->linkedObjectsIds + * Possible usage for parameters: + * - all parameters empty -> we look all link to current object (current object can be source or target) + * - source id+type -> will get target list linked to source + * - target id+type -> will get source list linked to target + * - source id+type + target type -> will get target list of the type + * - target id+type + target source -> will get source list of the type + * + * @param int $sourceid Object source id (if not defined, id of object) + * @param string $sourcetype Object source type (if not defined, element name of object) + * @param int $targetid Object target id (if not defined, id of object) + * @param string $targettype Object target type (if not defined, elemennt name of object) + * @param string $clause 'OR' or 'AND' clause used when both source id and target id are provided + * @param int $alsosametype 0=Return only links to object that differs from source. 1=Include also link to objects of same type. + * @return void + * @see add_object_linked, updateObjectLinked, deleteObjectLinked + */ + function fetchObjectLinked($sourceid=null,$sourcetype='',$targetid=null,$targettype='',$clause='OR',$alsosametype=1) + { + global $conf; + + $this->linkedObjectsIds=array(); + $this->linkedObjects=array(); + + $justsource=false; + $justtarget=false; + $withtargettype=false; + $withsourcetype=false; + + if (! empty($sourceid) && ! empty($sourcetype) && empty($targetid)) + { + $justsource=true; // the source (id and type) is a search criteria + if (! empty($targettype)) $withtargettype=true; + } + if (! empty($targetid) && ! empty($targettype) && empty($sourceid)) + { + $justtarget=true; // the target (id and type) is a search criteria + if (! empty($sourcetype)) $withsourcetype=true; + } + + $sourceid = (! empty($sourceid) ? $sourceid : $this->id); + $targetid = (! empty($targetid) ? $targetid : $this->id); + $sourcetype = (! empty($sourcetype) ? $sourcetype : $this->element); + $targettype = (! empty($targettype) ? $targettype : $this->element); + + /*if (empty($sourceid) && empty($targetid)) + { + dol_syslog('Bad usage of function. No source nor target id defined (nor as parameter nor as object id)', LOG_ERR); + return -1; + }*/ + + // Links between objects are stored in table element_element + $sql = 'SELECT rowid, fk_source, sourcetype, fk_target, targettype'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'element_element'; + $sql.= " WHERE "; + if ($justsource || $justtarget) + { + if ($justsource) + { + $sql.= "fk_source = ".$sourceid." AND sourcetype = '".$sourcetype."'"; + if ($withtargettype) $sql.= " AND targettype = '".$targettype."'"; + } + else if ($justtarget) + { + $sql.= "fk_target = ".$targetid." AND targettype = '".$targettype."'"; + if ($withsourcetype) $sql.= " AND sourcetype = '".$sourcetype."'"; + } + } + else + { + $sql.= "(fk_source = ".$sourceid." AND sourcetype = '".$sourcetype."')"; + $sql.= " ".$clause." (fk_target = ".$targetid." AND targettype = '".$targettype."')"; + } + $sql .= ' ORDER BY sourcetype'; + //print $sql; + + dol_syslog(get_class($this)."::fetchObjectLink", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + if ($justsource || $justtarget) + { + if ($justsource) + { + $this->linkedObjectsIds[$obj->targettype][$obj->rowid]=$obj->fk_target; + } + else if ($justtarget) + { + $this->linkedObjectsIds[$obj->sourcetype][$obj->rowid]=$obj->fk_source; + } + } + else + { + if ($obj->fk_source == $sourceid && $obj->sourcetype == $sourcetype) + { + $this->linkedObjectsIds[$obj->targettype][$obj->rowid]=$obj->fk_target; + } + if ($obj->fk_target == $targetid && $obj->targettype == $targettype) + { + $this->linkedObjectsIds[$obj->sourcetype][$obj->rowid]=$obj->fk_source; + } + } + $i++; + } + + if (! empty($this->linkedObjectsIds)) + { + foreach($this->linkedObjectsIds as $objecttype => $objectids) // $objecttype is a module name ('facture', 'mymodule', ...) or a module name with a suffix ('project_task', 'mymodule_myobj', ...) + { + // Parse element/subelement (ex: project_task, cabinetmed_consultation, ...) + $module = $element = $subelement = $objecttype; + if ($objecttype != 'supplier_proposal' && $objecttype != 'order_supplier' && $objecttype != 'invoice_supplier' + && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) + { + $module = $element = $regs[1]; + $subelement = $regs[2]; + } + + $classpath = $element.'/class'; + // To work with non standard classpath or module name + if ($objecttype == 'facture') { + $classpath = 'compta/facture/class'; + } + else if ($objecttype == 'facturerec') { + $classpath = 'compta/facture/class'; $module = 'facture'; + } + else if ($objecttype == 'propal') { + $classpath = 'comm/propal/class'; + } + else if ($objecttype == 'supplier_proposal') { + $classpath = 'supplier_proposal/class'; + } + else if ($objecttype == 'shipping') { + $classpath = 'expedition/class'; $subelement = 'expedition'; $module = 'expedition_bon'; + } + else if ($objecttype == 'delivery') { + $classpath = 'livraison/class'; $subelement = 'livraison'; $module = 'livraison_bon'; + } + else if ($objecttype == 'invoice_supplier' || $objecttype == 'order_supplier') { + $classpath = 'fourn/class'; $module = 'fournisseur'; + } + else if ($objecttype == 'fichinter') { + $classpath = 'fichinter/class'; $subelement = 'fichinter'; $module = 'ficheinter'; + } + else if ($objecttype == 'subscription') { + $classpath = 'adherents/class'; $module = 'adherent'; + } + + // Set classfile + $classfile = strtolower($subelement); $classname = ucfirst($subelement); + + if ($objecttype == 'order') { + $classfile = 'commande'; $classname = 'Commande'; + } + else if ($objecttype == 'invoice_supplier') { + $classfile = 'fournisseur.facture'; $classname = 'FactureFournisseur'; + } + else if ($objecttype == 'order_supplier') { + $classfile = 'fournisseur.commande'; $classname = 'CommandeFournisseur'; + } + else if ($objecttype == 'supplier_proposal') { + $classfile = 'supplier_proposal'; $classname = 'SupplierProposal'; + } + else if ($objecttype == 'facturerec') { + $classfile = 'facture-rec'; $classname = 'FactureRec'; + } + else if ($objecttype == 'subscription') { + $classfile = 'subscription'; $classname = 'Subscription'; + } + + // Here $module, $classfile and $classname are set + if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) + { + dol_include_once('/'.$classpath.'/'.$classfile.'.class.php'); + //print '/'.$classpath.'/'.$classfile.'.class.php '.class_exists($classname); + if (class_exists($classname)) + { + foreach($objectids as $i => $objectid) // $i is rowid into llx_element_element + { + $object = new $classname($this->db); + $ret = $object->fetch($objectid); + if ($ret >= 0) + { + $this->linkedObjects[$objecttype][$i] = $object; + } + } + } + } } } + } + else + { + dol_print_error($this->db); + } + } - $this->db->free($resql); + /** + * Update object linked of a current object + * + * @param int $sourceid Object source id + * @param string $sourcetype Object source type + * @param int $targetid Object target id + * @param string $targettype Object target type + * @return int >0 if OK, <0 if KO + * @see add_object_linked, fetObjectLinked, deleteObjectLinked + */ + function updateObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='') + { + $updatesource=false; + $updatetarget=false; - // Now update global field total_ht, total_ttc and tva - $fieldht='total_ht'; - $fieldtva='tva'; - $fieldlocaltax1='localtax1'; - $fieldlocaltax2='localtax2'; - $fieldttc='total_ttc'; - // Specific code for backward compatibility with old field names - if ($this->element == 'facture' || $this->element == 'facturerec') $fieldht='total'; - if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva='total_tva'; - if ($this->element == 'propal') $fieldttc='total'; - if ($this->element == 'expensereport') $fieldtva='total_tva'; - if ($this->element == 'supplier_proposal') $fieldttc='total'; + if (! empty($sourceid) && ! empty($sourcetype) && empty($targetid) && empty($targettype)) $updatesource=true; + else if (empty($sourceid) && empty($sourcetype) && ! empty($targetid) && ! empty($targettype)) $updatetarget=true; - if (empty($nodatabaseupdate)) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET'; - $sql .= " ".$fieldht."='".price2num($this->total_ht)."',"; - $sql .= " ".$fieldtva."='".price2num($this->total_tva)."',"; - $sql .= " ".$fieldlocaltax1."='".price2num($this->total_localtax1)."',"; - $sql .= " ".$fieldlocaltax2."='".price2num($this->total_localtax2)."',"; - $sql .= " ".$fieldttc."='".price2num($this->total_ttc)."'"; - $sql .= ", multicurrency_total_ht='".price2num($this->multicurrency_total_ht, 'MT', 1)."'"; - $sql .= ", multicurrency_total_tva='".price2num($this->multicurrency_total_tva, 'MT', 1)."'"; - $sql .= ", multicurrency_total_ttc='".price2num($this->multicurrency_total_ttc, 'MT', 1)."'"; - $sql .= ' WHERE rowid = '.$this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."element_element SET "; + if ($updatesource) + { + $sql.= "fk_source = ".$sourceid; + $sql.= ", sourcetype = '".$this->db->escape($sourcetype)."'"; + $sql.= " WHERE fk_target = ".$this->id; + $sql.= " AND targettype = '".$this->db->escape($this->element)."'"; + } + else if ($updatetarget) + { + $sql.= "fk_target = ".$targetid; + $sql.= ", targettype = '".$this->db->escape($targettype)."'"; + $sql.= " WHERE fk_source = ".$this->id; + $sql.= " AND sourcetype = '".$this->db->escape($this->element)."'"; + } - //print "xx".$sql; - dol_syslog(get_class($this)."::update_price", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) + dol_syslog(get_class($this)."::updateObjectLinked", LOG_DEBUG); + if ($this->db->query($sql)) + { + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Delete all links between an object $this + * + * @param int $sourceid Object source id + * @param string $sourcetype Object source type + * @param int $targetid Object target id + * @param string $targettype Object target type + * @param int $rowid Row id of line to delete. If defined, other parameters are not used. + * @return int >0 if OK, <0 if KO + * @see add_object_linked, updateObjectLinked, fetchObjectLinked + */ + function deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='') + { + $deletesource=false; + $deletetarget=false; + + if (! empty($sourceid) && ! empty($sourcetype) && empty($targetid) && empty($targettype)) $deletesource=true; + else if (empty($sourceid) && empty($sourcetype) && ! empty($targetid) && ! empty($targettype)) $deletetarget=true; + + $sourceid = (! empty($sourceid) ? $sourceid : $this->id); + $sourcetype = (! empty($sourcetype) ? $sourcetype : $this->element); + $targetid = (! empty($targetid) ? $targetid : $this->id); + $targettype = (! empty($targettype) ? $targettype : $this->element); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_element"; + $sql.= " WHERE"; + if ($rowid > 0) + { + $sql.=" rowid = ".$rowid; + } + else + { + if ($deletesource) + { + $sql.= " fk_source = ".$sourceid." AND sourcetype = '".$this->db->escape($sourcetype)."'"; + $sql.= " AND fk_target = ".$this->id." AND targettype = '".$this->db->escape($this->element)."'"; + } + else if ($deletetarget) + { + $sql.= " fk_target = ".$targetid." AND targettype = '".$this->db->escape($targettype)."'"; + $sql.= " AND fk_source = ".$this->id." AND sourcetype = '".$this->db->escape($this->element)."'"; + } + else + { + $sql.= " (fk_source = ".$this->id." AND sourcetype = '".$this->db->escape($this->element)."')"; + $sql.= " OR"; + $sql.= " (fk_target = ".$this->id." AND targettype = '".$this->db->escape($this->element)."')"; + } + } + + dol_syslog(get_class($this)."::deleteObjectLinked", LOG_DEBUG); + if ($this->db->query($sql)) + { + return 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->errors[]=$this->error; + return -1; + } + } + + /** + * Set status of an object + * + * @param int $status Status to set + * @param int $elementId Id of element to force (use this->id by default) + * @param string $elementType Type of element to force (use this->table_element by default) + * @return int <0 if KO, >0 if OK + */ + function setStatut($status,$elementId=null,$elementType='') + { + global $user,$langs,$conf; + + $savElementId=$elementId; // To be used later to know if we were using the method using the id of this or not. + + $elementId = (!empty($elementId)?$elementId:$this->id); + $elementTable = (!empty($elementType)?$elementType:$this->table_element); + + $this->db->begin(); + + $fieldstatus="fk_statut"; + if ($elementTable == 'mailing') $fieldstatus="statut"; + if ($elementTable == 'user') $fieldstatus="statut"; + if ($elementTable == 'expensereport') $fieldstatus="fk_statut"; + if ($elementTable == 'commande_fournisseur_dispatch') $fieldstatus="status"; + + $sql = "UPDATE ".MAIN_DB_PREFIX.$elementTable; + $sql.= " SET ".$fieldstatus." = ".$status; + // If status = 1 = validated, update also fk_user_valid + if ($status == 1 && $elementTable == 'expensereport') $sql.=", fk_user_valid = ".$user->id; + $sql.= " WHERE rowid=".$elementId; + + dol_syslog(get_class($this)."::setStatut", LOG_DEBUG); + if ($this->db->query($sql)) + { + $error = 0; + + $trigkey=''; + if ($this->element == 'supplier_proposal' && $status == 2) $trigkey='SUPPLIER_PROPOSAL_SIGN'; // 2 = SupplierProposal::STATUS_SIGNED. Can't use constant into this generic class + if ($this->element == 'supplier_proposal' && $status == 3) $trigkey='SUPPLIER_PROPOSAL_REFUSE'; // 3 = SupplierProposal::STATUS_REFUSED. Can't use constant into this generic class + if ($this->element == 'supplier_proposal' && $status == 4) $trigkey='SUPPLIER_PROPOSAL_CLOSE'; // 4 = SupplierProposal::STATUS_CLOSED. Can't use constant into this generic class + if ($this->element == 'fichinter' && $status == 3) $trigkey='FICHINTER_CLASSIFY_DONE'; + if ($this->element == 'fichinter' && $status == 2) $trigkey='FICHINTER_CLASSIFY_BILLED'; + if ($this->element == 'fichinter' && $status == 1) $trigkey='FICHINTER_CLASSIFY_UNBILLED'; + + if ($trigkey) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers($trigkey,$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + + if (! $error) + { + $this->db->commit(); + + if (empty($savElementId)) // If the element we update was $this (so $elementId is null) { - $error++; - $this->error=$this->db->lasterror(); - $this->errors[]=$this->db->lasterror(); + $this->statut = $status; + $this->status = $status; } - } - if (! $error) - { return 1; - } - else - { + } + else + { + $this->db->rollback(); + dol_syslog(get_class($this)."::setStatus ".$this->error,LOG_ERR); return -1; - } + } } else { - dol_print_error($this->db,'Bad request in update_price'); - return -1; - } - } - - /** - * Add objects linked in llx_element_element. - * - * @param string $origin Linked element type - * @param int $origin_id Linked element id - * @return int <=0 if KO, >0 if OK - * @see fetchObjectLinked, updateObjectLinked, deleteObjectLinked - */ - function add_object_linked($origin=null, $origin_id=null) - { - $origin = (! empty($origin) ? $origin : $this->origin); - $origin_id = (! empty($origin_id) ? $origin_id : $this->origin_id); - - // Special case - if ($origin == 'order') $origin='commande'; - if ($origin == 'invoice') $origin='facture'; - - $this->db->begin(); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; - $sql.= "fk_source"; - $sql.= ", sourcetype"; - $sql.= ", fk_target"; - $sql.= ", targettype"; - $sql.= ") VALUES ("; - $sql.= $origin_id; - $sql.= ", '".$this->db->escape($origin)."'"; - $sql.= ", ".$this->id; - $sql.= ", '".$this->db->escape($this->element)."'"; - $sql.= ")"; - - dol_syslog(get_class($this)."::add_object_linked", LOG_DEBUG); - if ($this->db->query($sql)) - { - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return 0; - } + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Load type of canvas of an object if it exists + * + * @param int $id Record id + * @param string $ref Record ref + * @return int <0 if KO, 0 if nothing done, >0 if OK + */ + function getCanvas($id=0,$ref='') + { + global $conf; + + if (empty($id) && empty($ref)) return 0; + if (! empty($conf->global->MAIN_DISABLE_CANVAS)) return 0; // To increase speed. Not enabled by default. + + // Clean parameters + $ref = trim($ref); + + $sql = "SELECT rowid, canvas"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " WHERE entity IN (".getEntity($this->element, 1).")"; + if (! empty($id)) $sql.= " AND rowid = ".$id; + if (! empty($ref)) $sql.= " AND ref = '".$this->db->escape($ref)."'"; + + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + if ($obj) + { + $this->canvas = $obj->canvas; + return 1; + } + else return 0; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + + /** + * Get special code of a line + * + * @param int $lineid Id of line + * @return int Special code + */ + function getSpecialCode($lineid) + { + $sql = 'SELECT special_code FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE rowid = '.$lineid; + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + return $row[0]; + } + } + + /** + * Function to check if an object is used by others. + * Check is done into this->childtables. There is no check into llx_element_element. + * + * @param int $id Force id of object + * @return int <0 if KO, 0 if not used, >0 if already used + */ + function isObjectUsed($id=0) + { + global $langs; + + if (empty($id)) $id=$this->id; + + // Check parameters + if (! isset($this->childtables) || ! is_array($this->childtables) || count($this->childtables) == 0) + { + dol_print_error('Called isObjectUsed on a class with property this->childtables not defined'); + return -1; + } + + $arraytoscan = $this->childtables; + // For backward compatibility, we check if array is old format array('table1', 'table2', ...) + $tmparray=array_keys($this->childtables); + if (is_numeric($tmparray[0])) + { + $arraytoscan = array_flip($this->childtables); + } + + // Test if child exists + $haschild=0; + foreach($arraytoscan as $table => $elementname) + { + //print $id.'-'.$table.'-'.$elementname.'<br>'; + // Check if third party can be deleted + $sql = "SELECT COUNT(*) as nb from ".MAIN_DB_PREFIX.$table; + $sql.= " WHERE ".$this->fk_element." = ".$id; + $resql=$this->db->query($sql); + if ($resql) + { + $obj=$this->db->fetch_object($resql); + if ($obj->nb > 0) + { + $langs->load("errors"); + //print 'Found into table '.$table.', type '.$langs->transnoentitiesnoconv($elementname).', haschild='.$haschild; + $haschild += $obj->nb; + $this->errors[]=$langs->trans("ErrorRecordHasAtLeastOneChildOfType", $langs->transnoentitiesnoconv($elementname)); + break; // We found at least one, we stop here + } + } + else + { + $this->errors[]=$this->db->lasterror(); + return -1; + } + } + if ($haschild > 0) + { + $this->errors[]="ErrorRecordHasChildren"; + return $haschild; + } + else return 0; + } + + /** + * Function to say how many lines object contains + * + * @param int $predefined -1=All, 0=Count free product/service only, 1=Count predefined product/service only, 2=Count predefined product, 3=Count predefined service + * @return int <0 if KO, 0 if no predefined products, nb of lines with predefined products if found + */ + function hasProductsOrServices($predefined=-1) + { + $nb=0; + + foreach($this->lines as $key => $val) + { + $qualified=0; + if ($predefined == -1) $qualified=1; + if ($predefined == 1 && $val->fk_product > 0) $qualified=1; + if ($predefined == 0 && $val->fk_product <= 0) $qualified=1; + if ($predefined == 2 && $val->fk_product > 0 && $val->product_type==0) $qualified=1; + if ($predefined == 3 && $val->fk_product > 0 && $val->product_type==1) $qualified=1; + if ($qualified) $nb++; + } + dol_syslog(get_class($this).'::hasProductsOrServices we found '.$nb.' qualified lines of products/servcies'); + return $nb; } - /** - * Fetch array of objects linked to current object. Links are loaded into this->linkedObjects array and this->linkedObjectsIds - * Possible usage for parameters: - * - all parameters empty -> we look all link to current object (current object can be source or target) - * - source id+type -> will get target list linked to source - * - target id+type -> will get source list linked to target - * - source id+type + target type -> will get target list of the type - * - target id+type + target source -> will get source list of the type - * - * @param int $sourceid Object source id (if not defined, id of object) - * @param string $sourcetype Object source type (if not defined, element name of object) - * @param int $targetid Object target id (if not defined, id of object) - * @param string $targettype Object target type (if not defined, elemennt name of object) - * @param string $clause 'OR' or 'AND' clause used when both source id and target id are provided - * @param int $alsosametype 0=Return only links to object that differs from source. 1=Include also link to objects of same type. - * @return void - * @see add_object_linked, updateObjectLinked, deleteObjectLinked - */ - function fetchObjectLinked($sourceid=null,$sourcetype='',$targetid=null,$targettype='',$clause='OR',$alsosametype=1) - { - global $conf; + /** + * Function that returns the total amount HT of discounts applied for all lines. + * + * @return float + */ + function getTotalDiscount() + { + $total_discount=0.00; + + $sql = "SELECT subprice as pu_ht, qty, remise_percent, total_ht"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element."det"; + $sql.= " WHERE ".$this->fk_element." = ".$this->id; - $this->linkedObjectsIds=array(); - $this->linkedObjects=array(); + dol_syslog(get_class($this).'::getTotalDiscount', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $num=$this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); - $justsource=false; - $justtarget=false; - $withtargettype=false; - $withsourcetype=false; + $pu_ht = $obj->pu_ht; + $qty= $obj->qty; + $total_ht = $obj->total_ht; - if (! empty($sourceid) && ! empty($sourcetype) && empty($targetid)) - { - $justsource=true; // the source (id and type) is a search criteria - if (! empty($targettype)) $withtargettype=true; - } - if (! empty($targetid) && ! empty($targettype) && empty($sourceid)) - { - $justtarget=true; // the target (id and type) is a search criteria - if (! empty($sourcetype)) $withsourcetype=true; - } + $total_discount_line = floatval(price2num(($pu_ht * $qty) - $total_ht, 'MT')); + $total_discount += $total_discount_line; - $sourceid = (! empty($sourceid) ? $sourceid : $this->id); - $targetid = (! empty($targetid) ? $targetid : $this->id); - $sourcetype = (! empty($sourcetype) ? $sourcetype : $this->element); - $targettype = (! empty($targettype) ? $targettype : $this->element); + $i++; + } + } - /*if (empty($sourceid) && empty($targetid)) - { - dol_syslog('Bad usage of function. No source nor target id defined (nor as parameter nor as object id)', LOG_ERR); - return -1; - }*/ + //print $total_discount; exit; + return price2num($total_discount); + } - // Links between objects are stored in table element_element - $sql = 'SELECT rowid, fk_source, sourcetype, fk_target, targettype'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'element_element'; - $sql.= " WHERE "; - if ($justsource || $justtarget) - { - if ($justsource) - { - $sql.= "fk_source = ".$sourceid." AND sourcetype = '".$sourcetype."'"; - if ($withtargettype) $sql.= " AND targettype = '".$targettype."'"; - } - else if ($justtarget) - { - $sql.= "fk_target = ".$targetid." AND targettype = '".$targettype."'"; - if ($withsourcetype) $sql.= " AND sourcetype = '".$sourcetype."'"; - } - } - else - { - $sql.= "(fk_source = ".$sourceid." AND sourcetype = '".$sourcetype."')"; - $sql.= " ".$clause." (fk_target = ".$targetid." AND targettype = '".$targettype."')"; - } - $sql .= ' ORDER BY sourcetype'; - //print $sql; - - dol_syslog(get_class($this)."::fetchObjectLink", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - if ($justsource || $justtarget) - { - if ($justsource) - { - $this->linkedObjectsIds[$obj->targettype][$obj->rowid]=$obj->fk_target; - } - else if ($justtarget) - { - $this->linkedObjectsIds[$obj->sourcetype][$obj->rowid]=$obj->fk_source; - } - } - else - { - if ($obj->fk_source == $sourceid && $obj->sourcetype == $sourcetype) - { - $this->linkedObjectsIds[$obj->targettype][$obj->rowid]=$obj->fk_target; - } - if ($obj->fk_target == $targetid && $obj->targettype == $targettype) - { - $this->linkedObjectsIds[$obj->sourcetype][$obj->rowid]=$obj->fk_source; - } - } - $i++; - } - - if (! empty($this->linkedObjectsIds)) - { - foreach($this->linkedObjectsIds as $objecttype => $objectids) // $objecttype is a module name ('facture', 'mymodule', ...) or a module name with a suffix ('project_task', 'mymodule_myobj', ...) - { - // Parse element/subelement (ex: project_task, cabinetmed_consultation, ...) - $module = $element = $subelement = $objecttype; - if ($objecttype != 'supplier_proposal' && $objecttype != 'order_supplier' && $objecttype != 'invoice_supplier' - && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) - { - $module = $element = $regs[1]; - $subelement = $regs[2]; - } - - $classpath = $element.'/class'; - // To work with non standard classpath or module name - if ($objecttype == 'facture') { - $classpath = 'compta/facture/class'; - } - else if ($objecttype == 'facturerec') { - $classpath = 'compta/facture/class'; $module = 'facture'; - } - else if ($objecttype == 'propal') { - $classpath = 'comm/propal/class'; - } - else if ($objecttype == 'supplier_proposal') { - $classpath = 'supplier_proposal/class'; - } - else if ($objecttype == 'shipping') { - $classpath = 'expedition/class'; $subelement = 'expedition'; $module = 'expedition_bon'; - } - else if ($objecttype == 'delivery') { - $classpath = 'livraison/class'; $subelement = 'livraison'; $module = 'livraison_bon'; - } - else if ($objecttype == 'invoice_supplier' || $objecttype == 'order_supplier') { - $classpath = 'fourn/class'; $module = 'fournisseur'; - } - else if ($objecttype == 'fichinter') { - $classpath = 'fichinter/class'; $subelement = 'fichinter'; $module = 'ficheinter'; - } - else if ($objecttype == 'subscription') { - $classpath = 'adherents/class'; $module = 'adherent'; - } - - // Set classfile - $classfile = strtolower($subelement); $classname = ucfirst($subelement); - - if ($objecttype == 'order') { - $classfile = 'commande'; $classname = 'Commande'; - } - else if ($objecttype == 'invoice_supplier') { - $classfile = 'fournisseur.facture'; $classname = 'FactureFournisseur'; - } - else if ($objecttype == 'order_supplier') { - $classfile = 'fournisseur.commande'; $classname = 'CommandeFournisseur'; - } - else if ($objecttype == 'supplier_proposal') { - $classfile = 'supplier_proposal'; $classname = 'SupplierProposal'; - } - else if ($objecttype == 'facturerec') { - $classfile = 'facture-rec'; $classname = 'FactureRec'; - } - else if ($objecttype == 'subscription') { - $classfile = 'subscription'; $classname = 'Subscription'; - } - - // Here $module, $classfile and $classname are set - if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) - { - dol_include_once('/'.$classpath.'/'.$classfile.'.class.php'); - //print '/'.$classpath.'/'.$classfile.'.class.php '.class_exists($classname); - if (class_exists($classname)) - { - foreach($objectids as $i => $objectid) // $i is rowid into llx_element_element - { - $object = new $classname($this->db); - $ret = $object->fetch($objectid); - if ($ret >= 0) - { - $this->linkedObjects[$objecttype][$i] = $object; - } - } - } - } - } - } - } - else - { - dol_print_error($this->db); - } - } - - /** - * Update object linked of a current object - * - * @param int $sourceid Object source id - * @param string $sourcetype Object source type - * @param int $targetid Object target id - * @param string $targettype Object target type - * @return int >0 if OK, <0 if KO - * @see add_object_linked, fetObjectLinked, deleteObjectLinked - */ - function updateObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='') - { - $updatesource=false; - $updatetarget=false; - - if (! empty($sourceid) && ! empty($sourcetype) && empty($targetid) && empty($targettype)) $updatesource=true; - else if (empty($sourceid) && empty($sourcetype) && ! empty($targetid) && ! empty($targettype)) $updatetarget=true; - - $sql = "UPDATE ".MAIN_DB_PREFIX."element_element SET "; - if ($updatesource) - { - $sql.= "fk_source = ".$sourceid; - $sql.= ", sourcetype = '".$this->db->escape($sourcetype)."'"; - $sql.= " WHERE fk_target = ".$this->id; - $sql.= " AND targettype = '".$this->db->escape($this->element)."'"; - } - else if ($updatetarget) - { - $sql.= "fk_target = ".$targetid; - $sql.= ", targettype = '".$this->db->escape($targettype)."'"; - $sql.= " WHERE fk_source = ".$this->id; - $sql.= " AND sourcetype = '".$this->db->escape($this->element)."'"; - } - - dol_syslog(get_class($this)."::updateObjectLinked", LOG_DEBUG); - if ($this->db->query($sql)) - { - return 1; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } /** - * Delete all links between an object $this + * Return into unit=0, the calculated total of weight and volume of all lines * qty + * Calculate by adding weight and volume of each product line, so properties ->volume/volume_units/weight/weight_units must be loaded on line. * - * @param int $sourceid Object source id - * @param string $sourcetype Object source type - * @param int $targetid Object target id - * @param string $targettype Object target type - * @param int $rowid Row id of line to delete. If defined, other parameters are not used. - * @return int >0 if OK, <0 if KO - * @see add_object_linked, updateObjectLinked, fetchObjectLinked + * @return array array('weight'=>...,'volume'=>...) */ - function deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='') + function getTotalWeightVolume() { - $deletesource=false; - $deletetarget=false; - - if (! empty($sourceid) && ! empty($sourcetype) && empty($targetid) && empty($targettype)) $deletesource=true; - else if (empty($sourceid) && empty($sourcetype) && ! empty($targetid) && ! empty($targettype)) $deletetarget=true; - - $sourceid = (! empty($sourceid) ? $sourceid : $this->id); - $sourcetype = (! empty($sourcetype) ? $sourcetype : $this->element); - $targetid = (! empty($targetid) ? $targetid : $this->id); - $targettype = (! empty($targettype) ? $targettype : $this->element); + $totalWeight = 0; + $totalVolume = 0; + // defined for shipment only + $totalOrdered = ''; + // defined for shipment only + $totalToShip = ''; - $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_element"; - $sql.= " WHERE"; - if ($rowid > 0) - { - $sql.=" rowid = ".$rowid; - } - else + foreach ($this->lines as $line) { - if ($deletesource) - { - $sql.= " fk_source = ".$sourceid." AND sourcetype = '".$this->db->escape($sourcetype)."'"; - $sql.= " AND fk_target = ".$this->id." AND targettype = '".$this->db->escape($this->element)."'"; - } - else if ($deletetarget) + if (isset($line->qty_asked)) { - $sql.= " fk_target = ".$targetid." AND targettype = '".$this->db->escape($targettype)."'"; - $sql.= " AND fk_source = ".$this->id." AND sourcetype = '".$this->db->escape($this->element)."'"; + if (empty($totalOrdered)) $totalOrdered=0; // Avoid warning because $totalOrdered is '' + $totalOrdered+=$line->qty_asked; // defined for shipment only } - else + if (isset($line->qty_shipped)) { - $sql.= " (fk_source = ".$this->id." AND sourcetype = '".$this->db->escape($this->element)."')"; - $sql.= " OR"; - $sql.= " (fk_target = ".$this->id." AND targettype = '".$this->db->escape($this->element)."')"; + if (empty($totalToShip)) $totalToShip=0; // Avoid warning because $totalToShip is '' + $totalToShip+=$line->qty_shipped; // defined for shipment only } - } - - dol_syslog(get_class($this)."::deleteObjectLinked", LOG_DEBUG); - if ($this->db->query($sql)) - { - return 1; - } - else - { - $this->error=$this->db->lasterror(); - $this->errors[]=$this->error; - return -1; - } - } - /** - * Set status of an object - * - * @param int $status Status to set - * @param int $elementId Id of element to force (use this->id by default) - * @param string $elementType Type of element to force (use this->table_element by default) - * @return int <0 if KO, >0 if OK - */ - function setStatut($status,$elementId=null,$elementType='') - { - global $user,$langs,$conf; - - $savElementId=$elementId; // To be used later to know if we were using the method using the id of this or not. - - $elementId = (!empty($elementId)?$elementId:$this->id); - $elementTable = (!empty($elementType)?$elementType:$this->table_element); - - $this->db->begin(); - - $fieldstatus="fk_statut"; - if ($elementTable == 'mailing') $fieldstatus="statut"; - if ($elementTable == 'user') $fieldstatus="statut"; - if ($elementTable == 'expensereport') $fieldstatus="fk_statut"; - if ($elementTable == 'commande_fournisseur_dispatch') $fieldstatus="status"; + // Define qty, weight, volume, weight_units, volume_units + if ($this->element == 'shipping') { + // for shipments + $qty = $line->qty_shipped ? $line->qty_shipped : 0; + } + else { + $qty = $line->qty ? $line->qty : 0; + } - $sql = "UPDATE ".MAIN_DB_PREFIX.$elementTable; - $sql.= " SET ".$fieldstatus." = ".$status; - // If status = 1 = validated, update also fk_user_valid - if ($status == 1 && $elementTable == 'expensereport') $sql.=", fk_user_valid = ".$user->id; - $sql.= " WHERE rowid=".$elementId; + $weight = $line->weight ? $line->weight : 0; + $volume = $line->volume ? $line->volume : 0; - dol_syslog(get_class($this)."::setStatut", LOG_DEBUG); - if ($this->db->query($sql)) - { - $error = 0; - - $trigkey=''; - if ($this->element == 'supplier_proposal' && $status == 2) $trigkey='SUPPLIER_PROPOSAL_SIGN'; // 2 = SupplierProposal::STATUS_SIGNED. Can't use constant into this generic class - if ($this->element == 'supplier_proposal' && $status == 3) $trigkey='SUPPLIER_PROPOSAL_REFUSE'; // 3 = SupplierProposal::STATUS_REFUSED. Can't use constant into this generic class - if ($this->element == 'supplier_proposal' && $status == 4) $trigkey='SUPPLIER_PROPOSAL_CLOSE'; // 4 = SupplierProposal::STATUS_CLOSED. Can't use constant into this generic class - if ($this->element == 'fichinter' && $status == 3) $trigkey='FICHINTER_CLASSIFY_DONE'; - if ($this->element == 'fichinter' && $status == 2) $trigkey='FICHINTER_CLASSIFY_BILLED'; - if ($this->element == 'fichinter' && $status == 1) $trigkey='FICHINTER_CLASSIFY_UNBILLED'; - - if ($trigkey) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers($trigkey,$this,$user,$langs,$conf); - if ($result < 0) { - $error++; $this->errors=$interface->errors; - } - // Fin appel triggers - } + $weight_units=$line->weight_units; + $volume_units=$line->volume_units; - if (! $error) - { - $this->db->commit(); + $weightUnit=0; + $volumeUnit=0; + if (! empty($weight_units)) $weightUnit = $weight_units; + if (! empty($volume_units)) $volumeUnit = $volume_units; - if (empty($savElementId)) // If the element we update was $this (so $elementId is null) - { - $this->statut = $status; - $this->status = $status; - } + if (empty($totalWeight)) $totalWeight=0; // Avoid warning because $totalWeight is '' + if (empty($totalVolume)) $totalVolume=0; // Avoid warning because $totalVolume is '' - return 1; - } - else + //var_dump($line->volume_units); + if ($weight_units < 50) // >50 means a standard unit (power of 10 of official unit), > 50 means an exotic unit (like inch) { - $this->db->rollback(); - dol_syslog(get_class($this)."::setStatus ".$this->error,LOG_ERR); - return -1; + $trueWeightUnit=pow(10, $weightUnit); + $totalWeight += $weight * $qty * $trueWeightUnit; } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - - /** - * Load type of canvas of an object if it exists - * - * @param int $id Record id - * @param string $ref Record ref - * @return int <0 if KO, 0 if nothing done, >0 if OK - */ - function getCanvas($id=0,$ref='') - { - global $conf; - - if (empty($id) && empty($ref)) return 0; - if (! empty($conf->global->MAIN_DISABLE_CANVAS)) return 0; // To increase speed. Not enabled by default. - - // Clean parameters - $ref = trim($ref); - - $sql = "SELECT rowid, canvas"; - $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " WHERE entity IN (".getEntity($this->element, 1).")"; - if (! empty($id)) $sql.= " AND rowid = ".$id; - if (! empty($ref)) $sql.= " AND ref = '".$this->db->escape($ref)."'"; - - $resql = $this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - if ($obj) - { - $this->canvas = $obj->canvas; - return 1; - } - else return 0; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - - /** - * Get special code of a line - * - * @param int $lineid Id of line - * @return int Special code - */ - function getSpecialCode($lineid) - { - $sql = 'SELECT special_code FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql.= ' WHERE rowid = '.$lineid; - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - return $row[0]; - } - } - - /** - * Function to check if an object is used by others. - * Check is done into this->childtables. There is no check into llx_element_element. - * - * @param int $id Force id of object - * @return int <0 if KO, 0 if not used, >0 if already used - */ - function isObjectUsed($id=0) - { - global $langs; - - if (empty($id)) $id=$this->id; - - // Check parameters - if (! isset($this->childtables) || ! is_array($this->childtables) || count($this->childtables) == 0) - { - dol_print_error('Called isObjectUsed on a class with property this->childtables not defined'); - return -1; - } - - $arraytoscan = $this->childtables; - // For backward compatibility, we check if array is old format array('table1', 'table2', ...) - $tmparray=array_keys($this->childtables); - if (is_numeric($tmparray[0])) - { - $arraytoscan = array_flip($this->childtables); - } - - // Test if child exists - $haschild=0; - foreach($arraytoscan as $table => $elementname) - { - //print $id.'-'.$table.'-'.$elementname.'<br>'; - // Check if third party can be deleted - $sql = "SELECT COUNT(*) as nb from ".MAIN_DB_PREFIX.$table; - $sql.= " WHERE ".$this->fk_element." = ".$id; - $resql=$this->db->query($sql); - if ($resql) - { - $obj=$this->db->fetch_object($resql); - if ($obj->nb > 0) - { - $langs->load("errors"); - //print 'Found into table '.$table.', type '.$langs->transnoentitiesnoconv($elementname).', haschild='.$haschild; - $haschild += $obj->nb; - $this->errors[]=$langs->trans("ErrorRecordHasAtLeastOneChildOfType", $langs->transnoentitiesnoconv($elementname)); - break; // We found at least one, we stop here - } - } - else - { - $this->errors[]=$this->db->lasterror(); - return -1; - } - } - if ($haschild > 0) - { - $this->errors[]="ErrorRecordHasChildren"; - return $haschild; - } - else return 0; - } - - /** - * Function to say how many lines object contains - * - * @param int $predefined -1=All, 0=Count free product/service only, 1=Count predefined product/service only, 2=Count predefined product, 3=Count predefined service - * @return int <0 if KO, 0 if no predefined products, nb of lines with predefined products if found - */ - function hasProductsOrServices($predefined=-1) - { - $nb=0; - - foreach($this->lines as $key => $val) - { - $qualified=0; - if ($predefined == -1) $qualified=1; - if ($predefined == 1 && $val->fk_product > 0) $qualified=1; - if ($predefined == 0 && $val->fk_product <= 0) $qualified=1; - if ($predefined == 2 && $val->fk_product > 0 && $val->product_type==0) $qualified=1; - if ($predefined == 3 && $val->fk_product > 0 && $val->product_type==1) $qualified=1; - if ($qualified) $nb++; - } - dol_syslog(get_class($this).'::hasProductsOrServices we found '.$nb.' qualified lines of products/servcies'); - return $nb; - } - - /** - * Function that returns the total amount HT of discounts applied for all lines. - * - * @return float - */ - function getTotalDiscount() - { - $total_discount=0.00; - - $sql = "SELECT subprice as pu_ht, qty, remise_percent, total_ht"; - $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element."det"; - $sql.= " WHERE ".$this->fk_element." = ".$this->id; - - dol_syslog(get_class($this).'::getTotalDiscount', LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $num=$this->db->num_rows($resql); - $i=0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - - $pu_ht = $obj->pu_ht; - $qty= $obj->qty; - $total_ht = $obj->total_ht; - - $total_discount_line = floatval(price2num(($pu_ht * $qty) - $total_ht, 'MT')); - $total_discount += $total_discount_line; - - $i++; - } - } - - //print $total_discount; exit; - return price2num($total_discount); - } - - - /** - * Return into unit=0, the calculated total of weight and volume of all lines * qty - * Calculate by adding weight and volume of each product line, so properties ->volume/volume_units/weight/weight_units must be loaded on line. - * - * @return array array('weight'=>...,'volume'=>...) - */ - function getTotalWeightVolume() - { - $totalWeight = 0; - $totalVolume = 0; - // defined for shipment only - $totalOrdered = ''; - // defined for shipment only - $totalToShip = ''; - - foreach ($this->lines as $line) - { - if (isset($line->qty_asked)) - { - if (empty($totalOrdered)) $totalOrdered=0; // Avoid warning because $totalOrdered is '' - $totalOrdered+=$line->qty_asked; // defined for shipment only - } - if (isset($line->qty_shipped)) - { - if (empty($totalToShip)) $totalToShip=0; // Avoid warning because $totalToShip is '' - $totalToShip+=$line->qty_shipped; // defined for shipment only - } - - // Define qty, weight, volume, weight_units, volume_units - if ($this->element == 'shipping') { - // for shipments - $qty = $line->qty_shipped ? $line->qty_shipped : 0; - } - else { - $qty = $line->qty ? $line->qty : 0; - } - - $weight = $line->weight ? $line->weight : 0; - $volume = $line->volume ? $line->volume : 0; - - $weight_units=$line->weight_units; - $volume_units=$line->volume_units; - - $weightUnit=0; - $volumeUnit=0; - if (! empty($weight_units)) $weightUnit = $weight_units; - if (! empty($volume_units)) $volumeUnit = $volume_units; - - if (empty($totalWeight)) $totalWeight=0; // Avoid warning because $totalWeight is '' - if (empty($totalVolume)) $totalVolume=0; // Avoid warning because $totalVolume is '' - - //var_dump($line->volume_units); - if ($weight_units < 50) // >50 means a standard unit (power of 10 of official unit), > 50 means an exotic unit (like inch) - { - $trueWeightUnit=pow(10, $weightUnit); - $totalWeight += $weight * $qty * $trueWeightUnit; - } - else { + else { if ($weight_units == 99) { // conversion 1 Pound = 0.45359237 KG $trueWeightUnit = 0.45359237; @@ -3177,65 +3177,65 @@ abstract class CommonObject $totalWeight += $weight * $qty * $trueWeightUnit; } else - $totalWeight += $weight * $qty; // This may be wrong if we mix different units - } - if ($volume_units < 50) // >50 means a standard unit (power of 10 of official unit), > 50 means an exotic unit (like inch) - { - //print $line->volume."x".$line->volume_units."x".($line->volume_units < 50)."x".$volumeUnit; - $trueVolumeUnit=pow(10, $volumeUnit); - //print $line->volume; - $totalVolume += $volume * $qty * $trueVolumeUnit; - } - else - { - $totalVolume += $volume * $qty; // This may be wrong if we mix different units - } - } - - return array('weight'=>$totalWeight, 'volume'=>$totalVolume, 'ordered'=>$totalOrdered, 'toship'=>$totalToShip); - } - - - /** - * Set extra parameters - * - * @return int <0 if KO, >0 if OK - */ - function setExtraParameters() - { - $this->db->begin(); - - $extraparams = (! empty($this->extraparams) ? json_encode($this->extraparams) : null); - - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET extraparams = ".(! empty($extraparams) ? "'".$this->db->escape($extraparams)."'" : "null"); - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::setExtraParameters", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - else - { - $this->db->commit(); - return 1; - } - } - - - /** - * Return incoterms informations - * TODO Use a cache for label get - * - * @return string incoterms info - */ - function display_incoterms() - { - $out = ''; + $totalWeight += $weight * $qty; // This may be wrong if we mix different units + } + if ($volume_units < 50) // >50 means a standard unit (power of 10 of official unit), > 50 means an exotic unit (like inch) + { + //print $line->volume."x".$line->volume_units."x".($line->volume_units < 50)."x".$volumeUnit; + $trueVolumeUnit=pow(10, $volumeUnit); + //print $line->volume; + $totalVolume += $volume * $qty * $trueVolumeUnit; + } + else + { + $totalVolume += $volume * $qty; // This may be wrong if we mix different units + } + } + + return array('weight'=>$totalWeight, 'volume'=>$totalVolume, 'ordered'=>$totalOrdered, 'toship'=>$totalToShip); + } + + + /** + * Set extra parameters + * + * @return int <0 if KO, >0 if OK + */ + function setExtraParameters() + { + $this->db->begin(); + + $extraparams = (! empty($this->extraparams) ? json_encode($this->extraparams) : null); + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET extraparams = ".(! empty($extraparams) ? "'".$this->db->escape($extraparams)."'" : "null"); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::setExtraParameters", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Return incoterms informations + * TODO Use a cache for label get + * + * @return string incoterms info + */ + function display_incoterms() + { + $out = ''; $this->libelle_incoterms = ''; if (!empty($this->fk_incoterms)) { @@ -3251,13 +3251,13 @@ abstract class CommonObject $out .= (($res->code && $this->location_incoterms)?' - ':'').$this->location_incoterms; return $out; - } + } /** - * Return incoterms informations for pdf display - * - * @return string incoterms info - */ + * Return incoterms informations for pdf display + * + * @return string incoterms info + */ function getIncotermsForPDF() { $sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'c_incoterms WHERE rowid = '.(int) $this->fk_incoterms; @@ -3277,31 +3277,31 @@ abstract class CommonObject } else { - $this->errors[] = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); return false; } } /** - * Define incoterms values of current object - * - * @param int $id_incoterm Id of incoterm to set or '' to remove + * Define incoterms values of current object + * + * @param int $id_incoterm Id of incoterm to set or '' to remove * @param string $location location of incoterm - * @return int <0 if KO, >0 if OK - */ - function setIncoterms($id_incoterm, $location) - { - if ($this->id && $this->table_element) - { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_incoterms = ".($id_incoterm > 0 ? $id_incoterm : "null"); + * @return int <0 if KO, >0 if OK + */ + function setIncoterms($id_incoterm, $location) + { + if ($this->id && $this->table_element) + { + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_incoterms = ".($id_incoterm > 0 ? $id_incoterm : "null"); $sql.= ", location_incoterms = ".($id_incoterm > 0 ? "'".$this->db->escape($location)."'" : "null"); - $sql.= " WHERE rowid = " . $this->id; + $sql.= " WHERE rowid = " . $this->id; dol_syslog(get_class($this).'::setIncoterms', LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->fk_incoterms = $id_incoterm; + $resql=$this->db->query($sql); + if ($resql) + { + $this->fk_incoterms = $id_incoterm; $this->location_incoterms = $location; $sql = 'SELECT libelle FROM '.MAIN_DB_PREFIX.'c_incoterms WHERE rowid = '.(int) $this->fk_incoterms; @@ -3311,45 +3311,45 @@ abstract class CommonObject $obj = $this->db->fetch_object($res); $this->libelle_incoterms = $obj->libelle; } - return 1; - } - else + return 1; + } + else { - $this->errors[] = $this->db->lasterror(); - return -1; - } - } - else return -1; - } - - - /** - * Return if a country is inside the EEC (European Economic Community) - * @deprecated - * - * @return boolean true = country inside EEC, false = country outside EEC - */ - function isInEEC() - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - return isInEEC($this); - } - - - // -------------------- - // TODO: All functions here must be redesigned and moved as they are not business functions but output functions - // -------------------- - - /* This is to show add lines */ - - /** - * Show add free and predefined products/services form - * - * @param int $dateSelector 1=Show also date range input fields - * @param Societe $seller Object thirdparty who sell - * @param Societe $buyer Object thirdparty who buy - * @return void - */ + $this->errors[] = $this->db->lasterror(); + return -1; + } + } + else return -1; + } + + + /** + * Return if a country is inside the EEC (European Economic Community) + * @deprecated + * + * @return boolean true = country inside EEC, false = country outside EEC + */ + function isInEEC() + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + return isInEEC($this); + } + + + // -------------------- + // TODO: All functions here must be redesigned and moved as they are not business functions but output functions + // -------------------- + + /* This is to show add lines */ + + /** + * Show add free and predefined products/services form + * + * @param int $dateSelector 1=Show also date range input fields + * @param Societe $seller Object thirdparty who sell + * @param Societe $buyer Object thirdparty who buy + * @return void + */ function formAddObjectLine($dateSelector,$seller,$buyer) { global $conf,$user,$langs,$object,$hookmanager; @@ -3361,7 +3361,7 @@ abstract class CommonObject $extralabelslines=$extrafieldsline->fetch_name_optionals_label($this->table_element_line); // Output template part (modules that overwrite templates must declare this into descriptor) - // Use global variables + $dateSelector + $seller and $buyer + // Use global variables + $dateSelector + $seller and $buyer $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl')); foreach($dirtpls as $reldir) { @@ -3371,13 +3371,13 @@ abstract class CommonObject } else { $res=include $tpl; // for debug } - if ($res) break; + if ($res) break; } - } + } - /* This is to show array of line of details */ + /* This is to show array of line of details */ /** @@ -3414,75 +3414,75 @@ abstract class CommonObject $reshook = $hookmanager->executeHooks('printObjectLineTitle', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { - print '<tr class="liste_titre nodrag nodrop">'; + print '<tr class="liste_titre nodrag nodrop">'; - if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) print '<td class="linecolnum" align="center" width="5"> </td>'; + if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) print '<td class="linecolnum" align="center" width="5"> </td>'; - // Description - print '<td class="linecoldescription">'.$langs->trans('Description').'</td>'; + // Description + print '<td class="linecoldescription">'.$langs->trans('Description').'</td>'; - if ($this->element == 'supplier_proposal') - { - print '<td class="linerefsupplier" align="right"><span id="title_fourn_ref">'.$langs->trans("SupplierProposalRefFourn").'</span></td>'; - } + if ($this->element == 'supplier_proposal') + { + print '<td class="linerefsupplier" align="right"><span id="title_fourn_ref">'.$langs->trans("SupplierProposalRefFourn").'</span></td>'; + } - // VAT - print '<td class="linecolvat" align="right" width="80">'.$langs->trans('VAT').'</td>'; + // VAT + print '<td class="linecolvat" align="right" width="80">'.$langs->trans('VAT').'</td>'; - // Price HT - print '<td class="linecoluht" align="right" width="80">'.$langs->trans('PriceUHT').'</td>'; + // Price HT + print '<td class="linecoluht" align="right" width="80">'.$langs->trans('PriceUHT').'</td>'; - // Multicurrency - if (!empty($conf->multicurrency->enabled)) print '<td class="linecoluht_currency" align="right" width="80">'.$langs->trans('PriceUHTCurrency', $this->multicurrency_code).'</td>'; + // Multicurrency + if (!empty($conf->multicurrency->enabled)) print '<td class="linecoluht_currency" align="right" width="80">'.$langs->trans('PriceUHTCurrency', $this->multicurrency_code).'</td>'; - if ($inputalsopricewithtax) print '<td align="right" width="80">'.$langs->trans('PriceUTTC').'</td>'; + if ($inputalsopricewithtax) print '<td align="right" width="80">'.$langs->trans('PriceUTTC').'</td>'; - // Qty - print '<td class="linecolqty" align="right">'.$langs->trans('Qty').'</td>'; + // Qty + print '<td class="linecolqty" align="right">'.$langs->trans('Qty').'</td>'; - if($conf->global->PRODUCT_USE_UNITS) - { - print '<td class="linecoluseunit" align="left">'.$langs->trans('Unit').'</td>'; - } + if($conf->global->PRODUCT_USE_UNITS) + { + print '<td class="linecoluseunit" align="left">'.$langs->trans('Unit').'</td>'; + } - // Reduction short - print '<td class="linecoldiscount" align="right">'.$langs->trans('ReductionShort').'</td>'; + // Reduction short + print '<td class="linecoldiscount" align="right">'.$langs->trans('ReductionShort').'</td>'; - if ($this->situation_cycle_ref) { - print '<td class="linecolcycleref" align="right">' . $langs->trans('Progress') . '</td>'; - } + if ($this->situation_cycle_ref) { + print '<td class="linecolcycleref" align="right">' . $langs->trans('Progress') . '</td>'; + } - if ($usemargins && ! empty($conf->margin->enabled) && empty($user->societe_id)) - { - if (!empty($user->rights->margins->creer)) - { - if ($conf->global->MARGIN_TYPE == "1") - print '<td class="linecolmargin1 margininfos" align="right" width="80">'.$langs->trans('BuyingPrice').'</td>'; - else - print '<td class="linecolmargin1 margininfos" align="right" width="80">'.$langs->trans('CostPrice').'</td>'; - } + if ($usemargins && ! empty($conf->margin->enabled) && empty($user->societe_id)) + { + if (!empty($user->rights->margins->creer)) + { + if ($conf->global->MARGIN_TYPE == "1") + print '<td class="linecolmargin1 margininfos" align="right" width="80">'.$langs->trans('BuyingPrice').'</td>'; + else + print '<td class="linecolmargin1 margininfos" align="right" width="80">'.$langs->trans('CostPrice').'</td>'; + } - if (! empty($conf->global->DISPLAY_MARGIN_RATES) && $user->rights->margins->liretous) - print '<td class="linecolmargin2 margininfos" align="right" width="50">'.$langs->trans('MarginRate').'</td>'; - if (! empty($conf->global->DISPLAY_MARK_RATES) && $user->rights->margins->liretous) - print '<td class="linecolmargin2 margininfos" align="right" width="50">'.$langs->trans('MarkRate').'</td>'; - } + if (! empty($conf->global->DISPLAY_MARGIN_RATES) && $user->rights->margins->liretous) + print '<td class="linecolmargin2 margininfos" align="right" width="50">'.$langs->trans('MarginRate').'</td>'; + if (! empty($conf->global->DISPLAY_MARK_RATES) && $user->rights->margins->liretous) + print '<td class="linecolmargin2 margininfos" align="right" width="50">'.$langs->trans('MarkRate').'</td>'; + } - // Total HT - print '<td class="linecolht" align="right">'.$langs->trans('TotalHTShort').'</td>'; + // Total HT + print '<td class="linecolht" align="right">'.$langs->trans('TotalHTShort').'</td>'; - // Multicurrency - if (!empty($conf->multicurrency->enabled)) print '<td class="linecoltotalht_currency" align="right">'.$langs->trans('TotalHTShortCurrency', $this->multicurrency_code).'</td>'; + // Multicurrency + if (!empty($conf->multicurrency->enabled)) print '<td class="linecoltotalht_currency" align="right">'.$langs->trans('TotalHTShortCurrency', $this->multicurrency_code).'</td>'; - if ($outputalsopricetotalwithtax) print '<td align="right" width="80">'.$langs->trans('TotalTTCShort').'</td>'; + if ($outputalsopricetotalwithtax) print '<td align="right" width="80">'.$langs->trans('TotalTTCShort').'</td>'; - print '<td class="linecoledit"></td>'; // No width to allow autodim + print '<td class="linecoledit"></td>'; // No width to allow autodim - print '<td class="linecoldelete" width="10"></td>'; + print '<td class="linecoldelete" width="10"></td>'; - print '<td class="linecolmove" width="10"></td>'; + print '<td class="linecolmove" width="10"></td>'; - print "</tr>\n"; + print "</tr>\n"; } $var = true; @@ -3496,20 +3496,20 @@ abstract class CommonObject //if (is_object($hookmanager) && (($line->product_type == 9 && ! empty($line->special_code)) || ! empty($line->fk_parent_line))) - if (is_object($hookmanager)) // Old code is commented on preceding line. + if (is_object($hookmanager)) // Old code is commented on preceding line. { if (empty($line->fk_parent_line)) { $parameters = array('line'=>$line,'var'=>$var,'num'=>$num,'i'=>$i,'dateSelector'=>$dateSelector,'seller'=>$seller,'buyer'=>$buyer,'selected'=>$selected, 'extrafieldsline'=>$extrafieldsline); - $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks } else { $parameters = array('line'=>$line,'var'=>$var,'num'=>$num,'i'=>$i,'dateSelector'=>$dateSelector,'seller'=>$seller,'buyer'=>$buyer,'selected'=>$selected, 'extrafieldsline'=>$extrafieldsline, 'fk_parent_line'=>$line->fk_parent_line); - $reshook = $hookmanager->executeHooks('printObjectSubLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + $reshook = $hookmanager->executeHooks('printObjectSubLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks } } - if (empty($reshook)) + if (empty($reshook)) { $this->printObjectLine($action,$line,$var,$num,$i,$dateSelector,$seller,$buyer,$selected,$extrafieldsline); } @@ -3561,8 +3561,8 @@ abstract class CommonObject $product_static = new Product($this->db); $product_static->fetch($line->fk_product); - $product_static->ref = $line->ref; //can change ref in hook - $product_static->label = $line->label; //can change label in hook + $product_static->ref = $line->ref; //can change ref in hook + $product_static->label = $line->label; //can change label in hook $text=$product_static->getNomUrl(1); // Define output language and label @@ -3641,74 +3641,74 @@ abstract class CommonObject } - /* This is to show array of line of details of source object */ + /* This is to show array of line of details of source object */ - /** - * Return HTML table table of source object lines - * TODO Move this and previous function into output html class file (htmlline.class.php). - * If lines are into a template, title must also be into a template - * But for the moment we don't know if it's possible as we keep a method available on overloaded objects. - * - * @return void - */ - function printOriginLinesList() - { - global $langs, $hookmanager, $conf; + /** + * Return HTML table table of source object lines + * TODO Move this and previous function into output html class file (htmlline.class.php). + * If lines are into a template, title must also be into a template + * But for the moment we don't know if it's possible as we keep a method available on overloaded objects. + * + * @return void + */ + function printOriginLinesList() + { + global $langs, $hookmanager, $conf; - print '<tr class="liste_titre">'; - print '<td>'.$langs->trans('Ref').'</td>'; - print '<td>'.$langs->trans('Description').'</td>'; - print '<td align="right">'.$langs->trans('VATRate').'</td>'; - print '<td align="right">'.$langs->trans('PriceUHT').'</td>'; + print '<tr class="liste_titre">'; + print '<td>'.$langs->trans('Ref').'</td>'; + print '<td>'.$langs->trans('Description').'</td>'; + print '<td align="right">'.$langs->trans('VATRate').'</td>'; + print '<td align="right">'.$langs->trans('PriceUHT').'</td>'; if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('PriceUHTCurrency').'</td>'; - print '<td align="right">'.$langs->trans('Qty').'</td>'; - if($conf->global->PRODUCT_USE_UNITS) - { - print '<td align="left">'.$langs->trans('Unit').'</td>'; - } - print '<td align="right">'.$langs->trans('ReductionShort').'</td></tr>'; + print '<td align="right">'.$langs->trans('Qty').'</td>'; + if($conf->global->PRODUCT_USE_UNITS) + { + print '<td align="left">'.$langs->trans('Unit').'</td>'; + } + print '<td align="right">'.$langs->trans('ReductionShort').'</td></tr>'; + + $var = true; + $i = 0; + + foreach ($this->lines as $line) + { - $var = true; - $i = 0; - foreach ($this->lines as $line) - { + if (is_object($hookmanager) && (($line->product_type == 9 && ! empty($line->special_code)) || ! empty($line->fk_parent_line))) + { + if (empty($line->fk_parent_line)) + { + $parameters=array('line'=>$line,'var'=>$var,'i'=>$i); + $action=''; + $hookmanager->executeHooks('printOriginObjectLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + } + } + else + { + $this->printOriginLine($line,$var); + } + + $i++; + } + } + /** + * Return HTML with a line of table array of source object lines + * TODO Move this and previous function into output html class file (htmlline.class.php). + * If lines are into a template, title must also be into a template + * But for the moment we don't know if it's possible as we keep a method available on overloaded objects. + * + * @param CommonObjectLine $line Line + * @param string $var Var + * @return void + */ + function printOriginLine($line,$var) + { + global $langs, $conf; - if (is_object($hookmanager) && (($line->product_type == 9 && ! empty($line->special_code)) || ! empty($line->fk_parent_line))) - { - if (empty($line->fk_parent_line)) - { - $parameters=array('line'=>$line,'var'=>$var,'i'=>$i); - $action=''; - $hookmanager->executeHooks('printOriginObjectLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - } - } - else - { - $this->printOriginLine($line,$var); - } - - $i++; - } - } - - /** - * Return HTML with a line of table array of source object lines - * TODO Move this and previous function into output html class file (htmlline.class.php). - * If lines are into a template, title must also be into a template - * But for the moment we don't know if it's possible as we keep a method available on overloaded objects. - * - * @param CommonObjectLine $line Line - * @param string $var Var - * @return void - */ - function printOriginLine($line,$var) - { - global $langs, $conf; - - //var_dump($line); + //var_dump($line); if (!empty($line->date_start)) { $date_start=$line->date_start; @@ -3728,98 +3728,98 @@ abstract class CommonObject if ($line->date_fin_reel) $date_end=$line->date_fin_reel; } - $this->tpl['label'] = ''; - if (! empty($line->fk_parent_line)) $this->tpl['label'].= img_picto('', 'rightarrow'); + $this->tpl['label'] = ''; + if (! empty($line->fk_parent_line)) $this->tpl['label'].= img_picto('', 'rightarrow'); - if (($line->info_bits & 2) == 2) // TODO Not sure this is used for source object - { - $discount=new DiscountAbsolute($this->db); - $discount->fk_soc = $this->socid; - $this->tpl['label'].= $discount->getNomUrl(0,'discount'); - } - else if (! empty($line->fk_product)) - { - $productstatic = new Product($this->db); - $productstatic->id = $line->fk_product; - $productstatic->ref = $line->ref; - $productstatic->type = $line->fk_product_type; - $this->tpl['label'].= $productstatic->getNomUrl(1); - $this->tpl['label'].= ' - '.(! empty($line->label)?$line->label:$line->product_label); - // Dates - if ($line->product_type == 1 && ($date_start || $date_end)) - { - $this->tpl['label'].= get_date_range($date_start,$date_end); - } - } - else - { - $this->tpl['label'].= ($line->product_type == -1 ? ' ' : ($line->product_type == 1 ? img_object($langs->trans(''),'service') : img_object($langs->trans(''),'product'))); - if (!empty($line->desc)) { - $this->tpl['label'].=$line->desc; - }else { - $this->tpl['label'].= ($line->label ? ' '.$line->label : ''); - } - // Dates - if ($line->product_type == 1 && ($date_start || $date_end)) - { - $this->tpl['label'].= get_date_range($date_start,$date_end); - } - } - - if (! empty($line->desc)) - { - if ($line->desc == '(CREDIT_NOTE)') // TODO Not sure this is used for source object - { - $discount=new DiscountAbsolute($this->db); - $discount->fetch($line->fk_remise_except); - $this->tpl['description'] = $langs->transnoentities("DiscountFromCreditNote",$discount->getNomUrl(0)); - } - elseif ($line->desc == '(DEPOSIT)') // TODO Not sure this is used for source object - { - $discount=new DiscountAbsolute($this->db); - $discount->fetch($line->fk_remise_except); - $this->tpl['description'] = $langs->transnoentities("DiscountFromDeposit",$discount->getNomUrl(0)); - } - elseif ($line->desc == '(EXCESS RECEIVED)') - { - $discount=new DiscountAbsolute($this->db); - $discount->fetch($line->fk_remise_except); - $this->tpl['description'] = $langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0)); - } - else - { - $this->tpl['description'] = dol_trunc($line->desc,60); - } - } - else - { - $this->tpl['description'] = ' '; - } + if (($line->info_bits & 2) == 2) // TODO Not sure this is used for source object + { + $discount=new DiscountAbsolute($this->db); + $discount->fk_soc = $this->socid; + $this->tpl['label'].= $discount->getNomUrl(0,'discount'); + } + else if (! empty($line->fk_product)) + { + $productstatic = new Product($this->db); + $productstatic->id = $line->fk_product; + $productstatic->ref = $line->ref; + $productstatic->type = $line->fk_product_type; + $this->tpl['label'].= $productstatic->getNomUrl(1); + $this->tpl['label'].= ' - '.(! empty($line->label)?$line->label:$line->product_label); + // Dates + if ($line->product_type == 1 && ($date_start || $date_end)) + { + $this->tpl['label'].= get_date_range($date_start,$date_end); + } + } + else + { + $this->tpl['label'].= ($line->product_type == -1 ? ' ' : ($line->product_type == 1 ? img_object($langs->trans(''),'service') : img_object($langs->trans(''),'product'))); + if (!empty($line->desc)) { + $this->tpl['label'].=$line->desc; + }else { + $this->tpl['label'].= ($line->label ? ' '.$line->label : ''); + } + // Dates + if ($line->product_type == 1 && ($date_start || $date_end)) + { + $this->tpl['label'].= get_date_range($date_start,$date_end); + } + } - // VAT Rate - $this->tpl['vat_rate'] = vatrate($line->tva_tx, true); - if (! empty($line->vat_src_code) && ! preg_match('/\(/', $this->tpl['vat_rate'])) $this->tpl['vat_rate'].=' ('.$line->vat_src_code.')'; + if (! empty($line->desc)) + { + if ($line->desc == '(CREDIT_NOTE)') // TODO Not sure this is used for source object + { + $discount=new DiscountAbsolute($this->db); + $discount->fetch($line->fk_remise_except); + $this->tpl['description'] = $langs->transnoentities("DiscountFromCreditNote",$discount->getNomUrl(0)); + } + elseif ($line->desc == '(DEPOSIT)') // TODO Not sure this is used for source object + { + $discount=new DiscountAbsolute($this->db); + $discount->fetch($line->fk_remise_except); + $this->tpl['description'] = $langs->transnoentities("DiscountFromDeposit",$discount->getNomUrl(0)); + } + elseif ($line->desc == '(EXCESS RECEIVED)') + { + $discount=new DiscountAbsolute($this->db); + $discount->fetch($line->fk_remise_except); + $this->tpl['description'] = $langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0)); + } + else + { + $this->tpl['description'] = dol_trunc($line->desc,60); + } + } + else + { + $this->tpl['description'] = ' '; + } - $this->tpl['price'] = price($line->subprice); + // VAT Rate + $this->tpl['vat_rate'] = vatrate($line->tva_tx, true); + if (! empty($line->vat_src_code) && ! preg_match('/\(/', $this->tpl['vat_rate'])) $this->tpl['vat_rate'].=' ('.$line->vat_src_code.')'; + + $this->tpl['price'] = price($line->subprice); $this->tpl['multicurrency_price'] = price($line->multicurrency_subprice); - $this->tpl['qty'] = (($line->info_bits & 2) != 2) ? $line->qty : ' '; - if($conf->global->PRODUCT_USE_UNITS) $this->tpl['unit'] = $line->getLabelOfUnit('long'); - $this->tpl['remise_percent'] = (($line->info_bits & 2) != 2) ? vatrate($line->remise_percent, true) : ' '; - - // Output template part (modules that overwrite templates must declare this into descriptor) - // Use global variables + $dateSelector + $seller and $buyer - $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl')); - foreach($dirtpls as $reldir) - { - $tpl = dol_buildpath($reldir.'/originproductline.tpl.php'); - if (empty($conf->file->strict_mode)) { - $res=@include $tpl; - } else { - $res=include $tpl; // for debug - } - if ($res) break; - } - } + $this->tpl['qty'] = (($line->info_bits & 2) != 2) ? $line->qty : ' '; + if($conf->global->PRODUCT_USE_UNITS) $this->tpl['unit'] = $line->getLabelOfUnit('long'); + $this->tpl['remise_percent'] = (($line->info_bits & 2) != 2) ? vatrate($line->remise_percent, true) : ' '; + + // Output template part (modules that overwrite templates must declare this into descriptor) + // Use global variables + $dateSelector + $seller and $buyer + $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl')); + foreach($dirtpls as $reldir) + { + $tpl = dol_buildpath($reldir.'/originproductline.tpl.php'); + if (empty($conf->file->strict_mode)) { + $res=@include $tpl; + } else { + $res=include $tpl; // for debug + } + if ($res) break; + } + } /** @@ -3876,32 +3876,32 @@ abstract class CommonObject */ function delete_resource($rowid, $element, $notrigger=0) { - global $user; + global $user; - $this->db->begin(); + $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_resources"; - $sql.= " WHERE rowid=".$rowid; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_resources"; + $sql.= " WHERE rowid=".$rowid; - dol_syslog(get_class($this)."::delete_resource", LOG_DEBUG); + dol_syslog(get_class($this)."::delete_resource", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - else - { - if (! $notrigger) - { - $result=$this->call_trigger(strtoupper($element).'_DELETE_RESOURCE', $user); - if ($result < 0) { $this->db->rollback(); return -1; } - } - $this->db->commit(); - return 1; - } + $resql=$this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + else + { + if (! $notrigger) + { + $result=$this->call_trigger(strtoupper($element).'_DELETE_RESOURCE', $user); + if ($result < 0) { $this->db->rollback(); return -1; } + } + $this->db->commit(); + return 1; + } } @@ -3911,17 +3911,17 @@ abstract class CommonObject * @return void */ function __clone() - { - // Force a copy of this->lines, otherwise it will point to same object. - if (isset($this->lines) && is_array($this->lines)) - { - $nboflines=count($this->lines); - for($i=0; $i < $nboflines; $i++) - { - $this->lines[$i] = clone $this->lines[$i]; - } - } - } + { + // Force a copy of this->lines, otherwise it will point to same object. + if (isset($this->lines) && is_array($this->lines)) + { + $nboflines=count($this->lines); + for($i=0; $i < $nboflines; $i++) + { + $this->lines[$i] = clone $this->lines[$i]; + } + } + } /** * Common function for all objects extending CommonObject for generating documents @@ -3963,7 +3963,7 @@ abstract class CommonObject { foreach(array('doc','pdf') as $prefix) { - if (in_array(get_class($this), array('Adherent'))) $file = $prefix."_".$modele.".class.php"; // Member module use prefix_module.class.php + if (in_array(get_class($this), array('Adherent'))) $file = $prefix."_".$modele.".class.php"; // Member module use prefix_module.class.php else $file = $prefix."_".$modele.".modules.php"; // On verifie l'emplacement du modele @@ -3998,27 +3998,27 @@ abstract class CommonObject $listoffiles=array(); // Now we add first model found in directories scanned - $listofdir=explode(',',$dirtoscan); - foreach($listofdir as $key => $tmpdir) - { - $tmpdir=trim($tmpdir); - $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); - if (! $tmpdir) { unset($listofdir[$key]); continue; } - if (is_dir($tmpdir)) - { - $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0); - if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); - } - } - - if (count($listoffiles)) - { - foreach($listoffiles as $record) - { - $srctemplatepath=$record['fullname']; - break; - } - } + $listofdir=explode(',',$dirtoscan); + foreach($listofdir as $key => $tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { unset($listofdir[$key]); continue; } + if (is_dir($tmpdir)) + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + + if (count($listoffiles)) + { + foreach($listoffiles as $record) + { + $srctemplatepath=$record['fullname']; + break; + } + } } if (empty($srctemplatepath)) @@ -4028,14 +4028,14 @@ abstract class CommonObject } } - if ($obj->type == 'odt' && ! empty($srctemplatepath)) - { - if (! dol_is_file($srctemplatepath)) - { - $this->error='ErrorGenerationAskedForOdtTemplateWithSrcFileNotFound'; - return -1; - } - } + if ($obj->type == 'odt' && ! empty($srctemplatepath)) + { + if (! dol_is_file($srctemplatepath)) + { + $this->error='ErrorGenerationAskedForOdtTemplateWithSrcFileNotFound'; + return -1; + } + } // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. @@ -4043,8 +4043,8 @@ abstract class CommonObject if (in_array(get_class($this), array('Adherent'))) { - $arrayofrecords = array(); // The write_file of templates of adherent class need this - $resultwritefile = $obj->write_file($this, $outputlangs, $srctemplatepath, 'member', 1, $moreparams); + $arrayofrecords = array(); // The write_file of templates of adherent class need this + $resultwritefile = $obj->write_file($this, $outputlangs, $srctemplatepath, 'member', 1, $moreparams); } else { @@ -4148,190 +4148,190 @@ abstract class CommonObject if (file_exists($file_osencoded)) { // Create small thumbs for company (Ratio is near 16/9) - // Used on logon for example - vignette($file_osencoded, $maxwidthsmall, $maxheightsmall, '_small', $quality); + // Used on logon for example + vignette($file_osencoded, $maxwidthsmall, $maxheightsmall, '_small', $quality); - // Create mini thumbs for company (Ratio is near 16/9) - // Used on menu or for setup page for example - vignette($file_osencoded, $maxwidthmini, $maxheightmini, '_mini', $quality); + // Create mini thumbs for company (Ratio is near 16/9) + // Used on menu or for setup page for example + vignette($file_osencoded, $maxwidthmini, $maxheightmini, '_mini', $quality); } } /* Functions common to commonobject and commonobjectline */ - /* For default values */ - - /** - * Return the default value to use for a field when showing the create form of object. - * Return values in this order: - * 1) If parameter is available into POST, we return it first. - * 2) If not but an alternate value was provided as parameter of function, we return it. - * 3) If not but a constant $conf->global->OBJECTELEMENT_FIELDNAME is set, we return it (It is better to use the dedicated table). - * 4) Return value found into database (TODO No yet implemented) - * - * @param string $fieldname Name of field - * @param string $alternatevalue Alternate value to use - * @return string|string[] Default value (can be an array if the GETPOST return an array) - **/ + /* For default values */ + + /** + * Return the default value to use for a field when showing the create form of object. + * Return values in this order: + * 1) If parameter is available into POST, we return it first. + * 2) If not but an alternate value was provided as parameter of function, we return it. + * 3) If not but a constant $conf->global->OBJECTELEMENT_FIELDNAME is set, we return it (It is better to use the dedicated table). + * 4) Return value found into database (TODO No yet implemented) + * + * @param string $fieldname Name of field + * @param string $alternatevalue Alternate value to use + * @return string|string[] Default value (can be an array if the GETPOST return an array) + **/ function getDefaultCreateValueFor($fieldname, $alternatevalue=null) - { - global $conf, $_POST; + { + global $conf, $_POST; - // If param here has been posted, we use this value first. - if (isset($_POST[$fieldname])) return GETPOST($fieldname, 2); + // If param here has been posted, we use this value first. + if (isset($_POST[$fieldname])) return GETPOST($fieldname, 2); - if (isset($alternatevalue)) return $alternatevalue; + if (isset($alternatevalue)) return $alternatevalue; - $newelement=$this->element; - if ($newelement == 'facture') $newelement='invoice'; - if ($newelement == 'commande') $newelement='order'; - if (empty($newelement)) - { - dol_syslog("Ask a default value using common method getDefaultCreateValueForField on an object with no property ->element defined. Return empty string.", LOG_WARNING); - return ''; - } + $newelement=$this->element; + if ($newelement == 'facture') $newelement='invoice'; + if ($newelement == 'commande') $newelement='order'; + if (empty($newelement)) + { + dol_syslog("Ask a default value using common method getDefaultCreateValueForField on an object with no property ->element defined. Return empty string.", LOG_WARNING); + return ''; + } - $keyforfieldname=strtoupper($newelement.'_DEFAULT_'.$fieldname); - //var_dump($keyforfieldname); - if (isset($conf->global->$keyforfieldname)) return $conf->global->$keyforfieldname; + $keyforfieldname=strtoupper($newelement.'_DEFAULT_'.$fieldname); + //var_dump($keyforfieldname); + if (isset($conf->global->$keyforfieldname)) return $conf->global->$keyforfieldname; - // TODO Ad here a scan into table llx_overwrite_default with a filter on $this->element and $fieldname + // TODO Ad here a scan into table llx_overwrite_default with a filter on $this->element and $fieldname - } + } /* For triggers */ - /** - * Call trigger based on this instance. - * Some context information may also be provided into array property this->context. - * NB: Error from trigger are stacked in interface->errors - * NB2: If return code of triggers are < 0, action calling trigger should cancel all transaction. - * - * @param string $trigger_name trigger's name to execute - * @param User $user Object user - * @return int Result of run_triggers - */ - function call_trigger($trigger_name, $user) - { - global $langs,$conf; - - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers($trigger_name,$this,$user,$langs,$conf); - - if ($result < 0) - { - if (!empty($this->errors)) - { - $this->errors=array_unique(array_merge($this->errors,$interface->errors)); // We use array_unique because when a trigger call another trigger on same object, this->errors is added twice. - } - else - { - $this->errors=$interface->errors; - } - } - return $result; - } - - - /* Functions for extrafields */ - - - /** - * Function to get extra fields of a member into $this->array_options - * This method is in most cases called by method fetch of objects but you can call it separately. - * - * @param int $rowid Id of line. Use the id of object if not defined. Deprecated. Function must be called without parameters. - * @param array $optionsArray Array resulting of call of extrafields->fetch_name_optionals_label(). Deprecated. Function must be called without parameters. - * @return int <0 if error, 0 if no values of extrafield to find nor found, 1 if an attribute is found and value loaded - */ - function fetch_optionals($rowid=null,$optionsArray=null) - { - if (empty($rowid)) $rowid=$this->id; - - // To avoid SQL errors. Probably not the better solution though - if (!$this->table_element) { - return 0; - } - - if (! is_array($optionsArray)) - { - // If $extrafields is not a known object, we initialize it. Best practice is to have $extrafields defined into card.php or list.php page. - // TODO Use of existing extrafield is not yet ready (must mutualize code that use extrafields in form first) - // global $extrafields; - //if (! is_object($extrafields)) - //{ - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields = new ExtraFields($this->db); - //} - - // Load array of extrafields for elementype = $this->table_element - if (empty($extrafields->attributes[$this->table_element]['loaded'])) - { - $extrafields->fetch_name_optionals_label($this->table_element); - } - $optionsArray = $extrafields->attributes[$this->table_element]['label']; - } - - $table_element = $this->table_element; - if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility - - // Request to get complementary values - if (is_array($optionsArray) && count($optionsArray) > 0) - { - $sql = "SELECT rowid"; - foreach ($optionsArray as $name => $label) - { - if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] != 'separate') - { - $sql.= ", ".$name; - } - } - $sql.= " FROM ".MAIN_DB_PREFIX.$table_element."_extrafields"; - $sql.= " WHERE fk_object = ".$rowid; - - dol_syslog(get_class($this)."::fetch_optionals get extrafields data for ".$this->table_element, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $numrows=$this->db->num_rows($resql); - if ($numrows) - { - $tab = $this->db->fetch_array($resql); - - foreach ($tab as $key => $value) - { - // Test fetch_array ! is_int($key) because fetch_array result is a mix table with Key as alpha and Key as int (depend db engine) - if ($key != 'rowid' && $key != 'tms' && $key != 'fk_member' && ! is_int($key)) - { - // we can add this attribute to object - $this->array_options["options_".$key]=$value; - } - } - } - - $this->db->free($resql); - - if ($numrows) return $numrows; - else return 0; - } - else - { - dol_print_error($this->db); - return -1; - } - } - return 0; - } - - /** - * Delete all extra fields values for the current object. - * - * @return int <0 if KO, >0 if OK - */ + /** + * Call trigger based on this instance. + * Some context information may also be provided into array property this->context. + * NB: Error from trigger are stacked in interface->errors + * NB2: If return code of triggers are < 0, action calling trigger should cancel all transaction. + * + * @param string $trigger_name trigger's name to execute + * @param User $user Object user + * @return int Result of run_triggers + */ + function call_trigger($trigger_name, $user) + { + global $langs,$conf; + + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers($trigger_name,$this,$user,$langs,$conf); + + if ($result < 0) + { + if (!empty($this->errors)) + { + $this->errors=array_unique(array_merge($this->errors,$interface->errors)); // We use array_unique because when a trigger call another trigger on same object, this->errors is added twice. + } + else + { + $this->errors=$interface->errors; + } + } + return $result; + } + + + /* Functions for extrafields */ + + + /** + * Function to get extra fields of a member into $this->array_options + * This method is in most cases called by method fetch of objects but you can call it separately. + * + * @param int $rowid Id of line. Use the id of object if not defined. Deprecated. Function must be called without parameters. + * @param array $optionsArray Array resulting of call of extrafields->fetch_name_optionals_label(). Deprecated. Function must be called without parameters. + * @return int <0 if error, 0 if no values of extrafield to find nor found, 1 if an attribute is found and value loaded + */ + function fetch_optionals($rowid=null,$optionsArray=null) + { + if (empty($rowid)) $rowid=$this->id; + + // To avoid SQL errors. Probably not the better solution though + if (!$this->table_element) { + return 0; + } + + if (! is_array($optionsArray)) + { + // If $extrafields is not a known object, we initialize it. Best practice is to have $extrafields defined into card.php or list.php page. + // TODO Use of existing extrafield is not yet ready (must mutualize code that use extrafields in form first) + // global $extrafields; + //if (! is_object($extrafields)) + //{ + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields = new ExtraFields($this->db); + //} + + // Load array of extrafields for elementype = $this->table_element + if (empty($extrafields->attributes[$this->table_element]['loaded'])) + { + $extrafields->fetch_name_optionals_label($this->table_element); + } + $optionsArray = $extrafields->attributes[$this->table_element]['label']; + } + + $table_element = $this->table_element; + if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility + + // Request to get complementary values + if (is_array($optionsArray) && count($optionsArray) > 0) + { + $sql = "SELECT rowid"; + foreach ($optionsArray as $name => $label) + { + if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] != 'separate') + { + $sql.= ", ".$name; + } + } + $sql.= " FROM ".MAIN_DB_PREFIX.$table_element."_extrafields"; + $sql.= " WHERE fk_object = ".$rowid; + + dol_syslog(get_class($this)."::fetch_optionals get extrafields data for ".$this->table_element, LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $numrows=$this->db->num_rows($resql); + if ($numrows) + { + $tab = $this->db->fetch_array($resql); + + foreach ($tab as $key => $value) + { + // Test fetch_array ! is_int($key) because fetch_array result is a mix table with Key as alpha and Key as int (depend db engine) + if ($key != 'rowid' && $key != 'tms' && $key != 'fk_member' && ! is_int($key)) + { + // we can add this attribute to object + $this->array_options["options_".$key]=$value; + } + } + } + + $this->db->free($resql); + + if ($numrows) return $numrows; + else return 0; + } + else + { + dol_print_error($this->db); + return -1; + } + } + return 0; + } + + /** + * Delete all extra fields values for the current object. + * + * @return int <0 if KO, >0 if OK + */ function deleteExtraFields() { $this->db->begin(); @@ -4355,255 +4355,255 @@ abstract class CommonObject } } - /** - * Add/Update all extra fields values for the current object. - * Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) - * This function delete record with all extrafields and insert them again from the array $this->array_options. - * - * @return int -1=error, O=did nothing, 1=OK - */ - function insertExtraFields() - { - global $conf,$langs; + /** + * Add/Update all extra fields values for the current object. + * Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) + * This function delete record with all extrafields and insert them again from the array $this->array_options. + * + * @return int -1=error, O=did nothing, 1=OK + */ + function insertExtraFields() + { + global $conf,$langs; $error=0; if (! empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return 0; // For avoid conflicts if trigger used - if (! empty($this->array_options)) - { - // Check parameters - $langs->load('admin'); - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields = new ExtraFields($this->db); - $target_extrafields=$extrafields->fetch_name_optionals_label($this->table_element); - - //Eliminate copied source object extra_fields that do not exist in target object - $new_array_options=array(); - foreach ($this->array_options as $key => $value) { - if (in_array(substr($key,8), array_keys($target_extrafields))) - $new_array_options[$key] = $value; - } - - foreach($new_array_options as $key => $value) - { - $attributeKey = substr($key,8); // Remove 'options_' prefix - $attributeType = $extrafields->attribute_type[$attributeKey]; - $attributeLabel = $extrafields->attribute_label[$attributeKey]; - $attributeParam = $extrafields->attribute_param[$attributeKey]; - switch ($attributeType) - { - case 'int': - if (!is_numeric($value) && $value!='') - { - $this->errors[]=$langs->trans("ExtraFieldHasWrongValue",$attributeLabel); - return -1; - } - elseif ($value=='') - { - $new_array_options[$key] = null; - } - break; - /*case 'select': // Not required, we chosed value='0' for undefined values + if (! empty($this->array_options)) + { + // Check parameters + $langs->load('admin'); + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields = new ExtraFields($this->db); + $target_extrafields=$extrafields->fetch_name_optionals_label($this->table_element); + + //Eliminate copied source object extra_fields that do not exist in target object + $new_array_options=array(); + foreach ($this->array_options as $key => $value) { + if (in_array(substr($key,8), array_keys($target_extrafields))) + $new_array_options[$key] = $value; + } + + foreach($new_array_options as $key => $value) + { + $attributeKey = substr($key,8); // Remove 'options_' prefix + $attributeType = $extrafields->attribute_type[$attributeKey]; + $attributeLabel = $extrafields->attribute_label[$attributeKey]; + $attributeParam = $extrafields->attribute_param[$attributeKey]; + switch ($attributeType) + { + case 'int': + if (!is_numeric($value) && $value!='') + { + $this->errors[]=$langs->trans("ExtraFieldHasWrongValue",$attributeLabel); + return -1; + } + elseif ($value=='') + { + $new_array_options[$key] = null; + } + break; + /*case 'select': // Not required, we chosed value='0' for undefined values if ($value=='-1') { $this->array_options[$key] = null; } break;*/ - case 'price': - $new_array_options[$key] = price2num($this->array_options[$key]); - break; - case 'date': - $new_array_options[$key] = $this->db->idate($this->array_options[$key]); - break; - case 'datetime': - $new_array_options[$key] = $this->db->idate($this->array_options[$key]); - break; - case 'link': + case 'price': + $new_array_options[$key] = price2num($this->array_options[$key]); + break; + case 'date': + $new_array_options[$key] = $this->db->idate($this->array_options[$key]); + break; + case 'datetime': + $new_array_options[$key] = $this->db->idate($this->array_options[$key]); + break; + case 'link': $param_list=array_keys($attributeParam ['options']); // 0 : ObjectName // 1 : classPath $InfoFieldList = explode(":", $param_list[0]); dol_include_once($InfoFieldList[1]); - if ($InfoFieldList[0] && class_exists($InfoFieldList[0])) - { - $object = new $InfoFieldList[0]($this->db); - if ($value) - { - if (is_numeric($value)) $res=$object->fetch($value); + if ($InfoFieldList[0] && class_exists($InfoFieldList[0])) + { + $object = new $InfoFieldList[0]($this->db); + if ($value) + { + if (is_numeric($value)) $res=$object->fetch($value); else $res=$object->fetch('',$value); - if ($res > 0) $new_array_options[$key]=$object->id; - else - { - $this->error="Ref '".$value."' for object '".$object->element."' not found"; - $this->db->rollback(); - return -1; - } - } - } - else - { - dol_syslog('Error bad setup of extrafield', LOG_WARNING); - } + if ($res > 0) $new_array_options[$key]=$object->id; + else + { + $this->error="Ref '".$value."' for object '".$object->element."' not found"; + $this->db->rollback(); + return -1; + } + } + } + else + { + dol_syslog('Error bad setup of extrafield', LOG_WARNING); + } break; - } - } - $this->db->begin(); - - $table_element = $this->table_element; - if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility - - $sql_del = "DELETE FROM ".MAIN_DB_PREFIX.$table_element."_extrafields WHERE fk_object = ".$this->id; - dol_syslog(get_class($this)."::insertExtraFields delete", LOG_DEBUG); - $this->db->query($sql_del); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX.$table_element."_extrafields (fk_object"; - foreach($new_array_options as $key => $value) - { - $attributeKey = substr($key,8); // Remove 'options_' prefix - // Add field of attribut - if ($extrafields->attribute_type[$attributeKey] != 'separate') // Only for other type of separate - $sql.=",".$attributeKey; - } - $sql .= ") VALUES (".$this->id; - foreach($new_array_options as $key => $value) - { - $attributeKey = substr($key,8); // Remove 'options_' prefix - // Add field o fattribut - if($extrafields->attribute_type[$attributeKey] != 'separate') // Only for other type of separate) - { - if ($new_array_options[$key] != '') - { - $sql.=",'".$this->db->escape($new_array_options[$key])."'"; - } - else - { - $sql.=",null"; - } - } - } - $sql.=")"; - - dol_syslog(get_class($this)."::insertExtraFields insert", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - else - { - $this->db->commit(); - return 1; - } - } - else return 0; - } - - /** - * Update an exta field value for the current object. - * Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) - * This function delte record with all extrafields and insert them again from the array $this->array_options. - * - * @param string $key Key of the extrafield - * @return int -1=error, O=did nothing, 1=OK - */ - function updateExtraField($key) - { - global $conf,$langs; + } + } + $this->db->begin(); + + $table_element = $this->table_element; + if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility + + $sql_del = "DELETE FROM ".MAIN_DB_PREFIX.$table_element."_extrafields WHERE fk_object = ".$this->id; + dol_syslog(get_class($this)."::insertExtraFields delete", LOG_DEBUG); + $this->db->query($sql_del); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX.$table_element."_extrafields (fk_object"; + foreach($new_array_options as $key => $value) + { + $attributeKey = substr($key,8); // Remove 'options_' prefix + // Add field of attribut + if ($extrafields->attribute_type[$attributeKey] != 'separate') // Only for other type of separate + $sql.=",".$attributeKey; + } + $sql .= ") VALUES (".$this->id; + foreach($new_array_options as $key => $value) + { + $attributeKey = substr($key,8); // Remove 'options_' prefix + // Add field o fattribut + if($extrafields->attribute_type[$attributeKey] != 'separate') // Only for other type of separate) + { + if ($new_array_options[$key] != '') + { + $sql.=",'".$this->db->escape($new_array_options[$key])."'"; + } + else + { + $sql.=",null"; + } + } + } + $sql.=")"; + + dol_syslog(get_class($this)."::insertExtraFields insert", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + else + { + $this->db->commit(); + return 1; + } + } + else return 0; + } + + /** + * Update an exta field value for the current object. + * Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) + * This function delte record with all extrafields and insert them again from the array $this->array_options. + * + * @param string $key Key of the extrafield + * @return int -1=error, O=did nothing, 1=OK + */ + function updateExtraField($key) + { + global $conf,$langs; $error=0; if (! empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return 0; // For avoid conflicts if trigger used - if (! empty($this->array_options) && isset($this->array_options["options_".$key])) - { - // Check parameters - $langs->load('admin'); - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields = new ExtraFields($this->db); - $target_extrafields=$extrafields->fetch_name_optionals_label($this->table_element); - - $value=$this->array_options["options_".$key]; - $attributeType = $extrafields->attribute_type[$key]; - $attributeLabel = $extrafields->attribute_label[$key]; - $attributeParam = $extrafields->attribute_param[$key]; - switch ($attributeType) - { - case 'int': - if (!is_numeric($value) && $value!='') - { - $this->errors[]=$langs->trans("ExtraFieldHasWrongValue",$attributeLabel); - return -1; - } - elseif ($value=='') - { - $this->array_options["options_".$key] = null; - } - break; - /*case 'select': // Not required, we chosed value='0' for undefined values + if (! empty($this->array_options) && isset($this->array_options["options_".$key])) + { + // Check parameters + $langs->load('admin'); + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields = new ExtraFields($this->db); + $target_extrafields=$extrafields->fetch_name_optionals_label($this->table_element); + + $value=$this->array_options["options_".$key]; + $attributeType = $extrafields->attribute_type[$key]; + $attributeLabel = $extrafields->attribute_label[$key]; + $attributeParam = $extrafields->attribute_param[$key]; + switch ($attributeType) + { + case 'int': + if (!is_numeric($value) && $value!='') + { + $this->errors[]=$langs->trans("ExtraFieldHasWrongValue",$attributeLabel); + return -1; + } + elseif ($value=='') + { + $this->array_options["options_".$key] = null; + } + break; + /*case 'select': // Not required, we chosed value='0' for undefined values if ($value=='-1') { $this->array_options[$key] = null; } break;*/ - case 'price': - $this->array_options["options_".$key] = price2num($this->array_options["options_".$key]); - break; - case 'date': - $this->array_options["options_".$key]=$this->db->idate($this->array_options["options_".$key]); - break; - case 'datetime': - $this->array_options["options_".$key]=$this->db->idate($this->array_options["options_".$key]); - break; - case 'link': - $param_list=array_keys($attributeParam ['options']); - // 0 : ObjectName - // 1 : classPath - $InfoFieldList = explode(":", $param_list[0]); - dol_include_once($InfoFieldList[1]); - $object = new $InfoFieldList[0]($this->db); - if ($value) - { - $object->fetch(0,$value); - $this->array_options["options_".$key]=$object->id; - } - break; - } - - $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element."_extrafields SET ".$key."='".$this->db->escape($this->array_options["options_".$key])."'"; - $sql .= " WHERE fk_object = ".$this->id; - $resql = $this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - else - { - $this->db->commit(); - return 1; - } - } - else return 0; - } + case 'price': + $this->array_options["options_".$key] = price2num($this->array_options["options_".$key]); + break; + case 'date': + $this->array_options["options_".$key]=$this->db->idate($this->array_options["options_".$key]); + break; + case 'datetime': + $this->array_options["options_".$key]=$this->db->idate($this->array_options["options_".$key]); + break; + case 'link': + $param_list=array_keys($attributeParam ['options']); + // 0 : ObjectName + // 1 : classPath + $InfoFieldList = explode(":", $param_list[0]); + dol_include_once($InfoFieldList[1]); + $object = new $InfoFieldList[0]($this->db); + if ($value) + { + $object->fetch(0,$value); + $this->array_options["options_".$key]=$object->id; + } + break; + } + + $this->db->begin(); + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element."_extrafields SET ".$key."='".$this->db->escape($this->array_options["options_".$key])."'"; + $sql .= " WHERE fk_object = ".$this->id; + $resql = $this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + else + { + $this->db->commit(); + return 1; + } + } + else return 0; + } /** - * Function to show lines of extrafields with output datas - * - * @param Extrafields $extrafields Extrafield Object - * @param string $mode Show output (view) or input (edit) for extrafield - * @param array $params Optional parameters - * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) - * - * @return string - */ - function showOptionals($extrafields, $mode='view', $params=null, $keyprefix='') - { + * Function to show lines of extrafields with output datas + * + * @param Extrafields $extrafields Extrafield Object + * @param string $mode Show output (view) or input (edit) for extrafield + * @param array $params Optional parameters + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * + * @return string + */ + function showOptionals($extrafields, $mode='view', $params=null, $keyprefix='') + { global $_POST, $conf, $langs; $out = ''; @@ -4694,12 +4694,12 @@ abstract class CommonObject $out .='<td id="'.$html_id.'" class="'.$this->element.'_extras_'.$key.'" '.($colspan?' colspan="'.$colspan.'"':'').'>'; switch($mode) { - case "view": - $out .= $extrafields->showOutputField($key, $value); - break; - case "edit": - $out .= $extrafields->showInputField($key, $value, '', $keyprefix, '', 0, $this->id); - break; + case "view": + $out .= $extrafields->showOutputField($key, $value); + break; + case "edit": + $out .= $extrafields->showInputField($key, $value, '', $keyprefix, '', 0, $this->id); + break; } $out .= '</td>'; @@ -4780,9 +4780,9 @@ abstract class CommonObject if (! $db->query($sql)) { - if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B. + if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B. //$this->errors = $db->lasterror(); - return false; + return false; } } @@ -5043,40 +5043,40 @@ abstract class CommonObject */ private function setVarsFromFetchObj(&$obj) { - foreach ($this->fields as $field => $info) - { - if($this->isDate($info)) - { - if(empty($obj->{$field}) || $obj->{$field} === '0000-00-00 00:00:00' || $obj->{$field} === '1000-01-01 00:00:00') $this->{$field} = 0; - else $this->{$field} = strtotime($obj->{$field}); - } - elseif($this->isArray($info)) - { - $this->{$field} = @unserialize($obj->{$field}); - // Hack for data not in UTF8 - if($this->{$field } === FALSE) @unserialize(utf8_decode($obj->{$field})); - } - elseif($this->isInt($info)) - { - if ($field == 'rowid') $this->id = (int) $obj->{$field}; - else $this->{$field} = (int) $obj->{$field}; - } - elseif($this->isFloat($info)) - { - $this->{$field} = (double) $obj->{$field}; - } - elseif($this->isNull($info)) - { - $val = $obj->{$field}; - // zero is not null - $this->{$field} = (is_null($val) || (empty($val) && $val!==0 && $val!=='0') ? null : $val); - } - else - { - $this->{$field} = $obj->{$field}; - } - - } + foreach ($this->fields as $field => $info) + { + if($this->isDate($info)) + { + if(empty($obj->{$field}) || $obj->{$field} === '0000-00-00 00:00:00' || $obj->{$field} === '1000-01-01 00:00:00') $this->{$field} = 0; + else $this->{$field} = strtotime($obj->{$field}); + } + elseif($this->isArray($info)) + { + $this->{$field} = @unserialize($obj->{$field}); + // Hack for data not in UTF8 + if($this->{$field } === FALSE) @unserialize(utf8_decode($obj->{$field})); + } + elseif($this->isInt($info)) + { + if ($field == 'rowid') $this->id = (int) $obj->{$field}; + else $this->{$field} = (int) $obj->{$field}; + } + elseif($this->isFloat($info)) + { + $this->{$field} = (double) $obj->{$field}; + } + elseif($this->isNull($info)) + { + $val = $obj->{$field}; + // zero is not null + $this->{$field} = (is_null($val) || (empty($val) && $val!==0 && $val!=='0') ? null : $val); + } + else + { + $this->{$field} = $obj->{$field}; + } + + } } /** @@ -5086,8 +5086,8 @@ abstract class CommonObject */ private function get_field_list() { - $keys = array_keys($this->fields); - return implode(',', $keys); + $keys = array_keys($this->fields); + return implode(',', $keys); } /** @@ -5098,9 +5098,9 @@ abstract class CommonObject * @return string */ protected function quote($value, $fieldsentry) { - if (is_null($value)) return 'NULL'; - else if (preg_match('/^(int|double|real)/i', $fieldsentry['type'])) return $this->db->escape("$value"); - else return "'".$this->db->escape($value)."'"; + if (is_null($value)) return 'NULL'; + else if (preg_match('/^(int|double|real)/i', $fieldsentry['type'])) return $this->db->escape("$value"); + else return "'".$this->db->escape($value)."'"; } @@ -5113,47 +5113,47 @@ abstract class CommonObject */ public function createCommon(User $user, $notrigger = false) { - $error = 0; + $error = 0; - $now=dol_now(); + $now=dol_now(); - $fieldvalues = $this->set_save_query(); + $fieldvalues = $this->set_save_query(); if (array_key_exists('date_creation', $fieldvalues) && empty($fieldvalues['date_creation'])) $fieldvalues['date_creation']=$this->db->idate($now); if (array_key_exists('fk_user_creat', $fieldvalues) && ! ($fieldvalues['fk_user_creat'] > 0)) $fieldvalues['fk_user_creat']=$user->id; unset($fieldvalues['rowid']); // The field 'rowid' is reserved field name for autoincrement field so we don't need it into insert. - $keys=array(); - $values = array(); - foreach ($fieldvalues as $k => $v) { - $keys[] = $k; - $values[] = $this->quote($v, $this->fields[$k]); - } + $keys=array(); + $values = array(); + foreach ($fieldvalues as $k => $v) { + $keys[] = $k; + $values[] = $this->quote($v, $this->fields[$k]); + } - $this->db->begin(); + $this->db->begin(); - if (! $error) - { - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element; - $sql.= ' ('.implode( ", ", $keys ).')'; - $sql.= ' VALUES ('.implode( ", ", $values ).')'; + if (! $error) + { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element; + $sql.= ' ('.implode( ", ", $keys ).')'; + $sql.= ' VALUES ('.implode( ", ", $values ).')'; $res = $this->db->query($sql); - if ($res===false) { - $error++; - $this->errors[] = $this->db->lasterror(); - } - } - - if (! $error && ! $notrigger) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); - - if (!$notrigger) { - // Call triggers - $result=$this->call_trigger(strtoupper(get_class($this)).'_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } + if ($res===false) { + $error++; + $this->errors[] = $this->db->lasterror(); + } + } + + if (! $error && ! $notrigger) { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); + + if (!$notrigger) { + // Call triggers + $result=$this->call_trigger(strtoupper(get_class($this)).'_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } // Commit or rollback if ($error) { @@ -5186,30 +5186,30 @@ abstract class CommonObject $res = $this->db->query($sql); if ($res) { - if ($obj = $this->db->fetch_object($res)) - { - if ($obj) - { - $this->setVarsFromFetchObj($obj); - return $this->id; - } - else - { - return 0; - } - } - else - { - $this->error = $this->db->lasterror(); - $this->errors[] = $this->error; - return -1; - } + if ($obj = $this->db->fetch_object($res)) + { + if ($obj) + { + $this->setVarsFromFetchObj($obj); + return $this->id; + } + else + { + return 0; + } + } + else + { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->error; + return -1; + } } else { - $this->error = $this->db->lasterror(); - $this->errors[] = $this->error; - return -1; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->error; + return -1; } } @@ -5222,7 +5222,7 @@ abstract class CommonObject */ public function updateCommon(User $user, $notrigger = false) { - $error = 0; + $error = 0; $fieldvalues = $this->set_save_query(); unset($fieldvalues['rowid']); // We don't update this field, it is the key to define which record to update. @@ -5247,28 +5247,28 @@ abstract class CommonObject $this->db->begin(); if (! $error) { - $res = $this->db->query($sql); - if ($res===false) - { - $error++; - $this->errors[] = $this->db->lasterror(); - } + $res = $this->db->query($sql); + if ($res===false) + { + $error++; + $this->errors[] = $this->db->lasterror(); + } } if (! $error && ! $notrigger) { - // Call triggers - $result=$this->call_trigger(strtoupper(get_class($this)).'_MODIFY',$user); - if ($result < 0) { $error++; } //Do also here what you must do to rollback action if trigger fail - // End call triggers + // Call triggers + $result=$this->call_trigger(strtoupper(get_class($this)).'_MODIFY',$user); + if ($result < 0) { $error++; } //Do also here what you must do to rollback action if trigger fail + // End call triggers } // Commit or rollback if ($error) { - $this->db->rollback(); - return -1; + $this->db->rollback(); + return -1; } else { - $this->db->commit(); - return $this->id; + $this->db->commit(); + return $this->id; } } @@ -5281,37 +5281,37 @@ abstract class CommonObject */ public function deleteCommon(User $user, $notrigger = false) { - $error=0; - - $this->db->begin(); - - if (! $error) { - if (! $notrigger) { - // Call triggers - $result=$this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user); - if ($result < 0) { $error++; } // Do also here what you must do to rollback action if trigger fail - // End call triggers - } - } - - if (! $error) - { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid='.$this->id; - - $res = $this->db->query($sql); - if($res===false) { - $error++; - $this->errors[] = $this->db->lasterror(); - } - } - - // Commit or rollback + $error=0; + + $this->db->begin(); + + if (! $error) { + if (! $notrigger) { + // Call triggers + $result=$this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user); + if ($result < 0) { $error++; } // Do also here what you must do to rollback action if trigger fail + // End call triggers + } + } + + if (! $error) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid='.$this->id; + + $res = $this->db->query($sql); + if($res===false) { + $error++; + $this->errors[] = $this->db->lasterror(); + } + } + + // Commit or rollback if ($error) { - $this->db->rollback(); - return -1; + $this->db->rollback(); + return -1; } else { - $this->db->commit(); - return 1; + $this->db->commit(); + return 1; } } @@ -5323,9 +5323,9 @@ abstract class CommonObject */ public function initAsSpecimenCommon() { - $this->id = 0; + $this->id = 0; - // TODO... + // TODO... } /** diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9cb120fa61d397000fe0330d8503ecf7d326578c..dd8a0b967debef6f54e10041b39e909e2f060e3d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -46,527 +46,527 @@ */ class Form { - var $db; - var $error; - var $num; - - // Cache arrays - var $cache_types_paiements=array(); - var $cache_conditions_paiements=array(); - var $cache_availability=array(); - var $cache_demand_reason=array(); - var $cache_types_fees=array(); - var $cache_vatrates=array(); - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - $this->db = $db; - } - - /** - * Output key field for an editable field - * - * @param string $text Text of label or key to translate - * @param string $htmlname Name of select field ('edit' prefix will be added) - * @param string $preselected Value to show/edit (not used in this function) - * @param object $object Object - * @param boolean $perm Permission to allow button to edit parameter. Set it to 0 to have a not edited field. - * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...) - * @param string $moreparam More param to add on a href URL. - * @param int $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. - * @param int $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' - * @return string HTML edit field - */ - function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata='string', $moreparam='', $fieldrequired=0, $notabletag=0) - { - global $conf,$langs; - - $ret=''; - - // TODO change for compatibility - if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;/',$typeofdata)) - { - if (! empty($perm)) - { - $tmp=explode(':',$typeofdata); - $ret.= '<div class="editkey_'.$tmp[0].(! empty($tmp[1]) ? ' '.$tmp[1] : '').'" id="'.$htmlname.'">'; - if ($fieldrequired) $ret.='<span class="fieldrequired">'; - $ret.= $langs->trans($text); - if ($fieldrequired) $ret.='</span>'; - $ret.= '</div>'."\n"; - } - else - { - if ($fieldrequired) $ret.='<span class="fieldrequired">'; - $ret.= $langs->trans($text); - if ($fieldrequired) $ret.='</span>'; - } - } - else - { - if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<table class="nobordernopadding" width="100%"><tr><td class="nowrap">'; - if ($fieldrequired) $ret.='<span class="fieldrequired">'; - $ret.=$langs->trans($text); - if ($fieldrequired) $ret.='</span>'; - if (! empty($notabletag)) $ret.=' '; - if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</td>'; - if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<td align="right">'; - if ($htmlname && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<a href="'.$_SERVER["PHP_SELF"].'?action=edit'.$htmlname.'&id='.$object->id.$moreparam.'">'.img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1)).'</a>'; - if (! empty($notabletag) && $notabletag == 1) $ret.=' : '; - if (! empty($notabletag) && $notabletag == 3) $ret.=' '; - if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</td>'; - if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</tr></table>'; - } - - return $ret; - } - - /** - * Output val field for an editable field - * - * @param string $text Text of label (not used in this function) - * @param string $htmlname Name of select field - * @param string $value Value to show/edit - * @param object $object Object - * @param boolean $perm Permission to allow button to edit parameter - * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datepickerhour', 'ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols', 'select:xxx'...) - * @param string $editvalue When in edit mode, use this value as $value instead of value (for example, you can provide here a formated price instead of value). Use '' to use same than $value - * @param object $extObject External object - * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') - * @param string $moreparam More param to add on a href URL - * @param int $notabletag Do no output table tags - * @return string HTML edit field - */ - function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata='string', $editvalue='', $extObject=null, $custommsg=null, $moreparam='', $notabletag=0) - { - global $conf,$langs,$db; - - $ret=''; - - // Check parameters - if (empty($typeofdata)) return 'ErrorBadParameter'; - - // When option to edit inline is activated - if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;|datehourpicker/',$typeofdata)) // TODO add jquery timepicker - { - $ret.=$this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg); - } - else - { - if (GETPOST('action','aZ09') == 'edit'.$htmlname) - { - $ret.="\n"; - $ret.='<form method="post" action="'.$_SERVER["PHP_SELF"].($moreparam?'?'.$moreparam:'').'">'; - $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">'; - $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $ret.='<input type="hidden" name="id" value="'.$object->id.'">'; - if (empty($notabletag)) $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">'; - if (empty($notabletag)) $ret.='<tr><td>'; - if (preg_match('/^(string|email)/',$typeofdata)) - { - $tmp=explode(':',$typeofdata); - $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($editvalue?$editvalue:$value).'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>'; - } - else if (preg_match('/^(numeric|amount)/',$typeofdata)) - { - $tmp=explode(':',$typeofdata); - $valuetoshow=price2num($editvalue?$editvalue:$value); - $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($valuetoshow!=''?price($valuetoshow):'').'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>'; - } - else if (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata)) - { - $tmp=explode(':',$typeofdata); - $cols=$tmp[2]; - $morealt=''; - if (preg_match('/%/',$cols)) - { - $morealt=' style="width: '.$cols.'"'; - $cols=''; - } - $ret.='<textarea id="'.$htmlname.'" name="'.$htmlname.'" wrap="soft" rows="'.($tmp[1]?$tmp[1]:'20').'"'.($cols?' cols="'.$cols.'"':'').$morealt.'">'.($editvalue?$editvalue:$value).'</textarea>'; - } - else if ($typeofdata == 'day' || $typeofdata == 'datepicker') - { - $ret.=$this->select_date($value,$htmlname,0,0,1,'form'.$htmlname,1,0,1); - } - else if ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') - { - $ret.=$this->select_date($value,$htmlname,1,1,1,'form'.$htmlname,1,0,1); - } - else if (preg_match('/^select;/',$typeofdata)) - { - $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata)); - foreach($arraydata as $val) - { - $tmp=explode(':',$val); - $arraylist[$tmp[0]]=$tmp[1]; - } - $ret.=$this->selectarray($htmlname,$arraylist,$value); - } - else if (preg_match('/^ckeditor/',$typeofdata)) - { - $tmp=explode(':',$typeofdata); - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor($htmlname, ($editvalue?$editvalue:$value), ($tmp[2]?$tmp[2]:''), ($tmp[3]?$tmp[3]:'100'), ($tmp[1]?$tmp[1]:'dolibarr_notes'), 'In', ($tmp[5]?$tmp[5]:0), true, true, ($tmp[6]?$tmp[6]:'20'), ($tmp[7]?$tmp[7]:'100')); - $ret.=$doleditor->Create(1); - } - if (empty($notabletag)) $ret.='</td>'; + var $db; + var $error; + var $num; - if (empty($notabletag)) $ret.='<td align="left">'; - //else $ret.='<div class="clearboth"></div>'; - $ret.='<input type="submit" class="button'.(empty($notabletag)?'':' ').'" name="modify" value="'.$langs->trans("Modify").'">'; - if (preg_match('/ckeditor|textarea/',$typeofdata) && empty($notabletag)) $ret.='<br>'."\n"; - $ret.='<input type="submit" class="button'.(empty($notabletag)?'':' ').'" name="cancel" value="'.$langs->trans("Cancel").'">'; - if (empty($notabletag)) $ret.='</td>'; + // Cache arrays + var $cache_types_paiements=array(); + var $cache_conditions_paiements=array(); + var $cache_availability=array(); + var $cache_demand_reason=array(); + var $cache_types_fees=array(); + var $cache_vatrates=array(); - if (empty($notabletag)) $ret.='</tr></table>'."\n"; - $ret.='</form>'."\n"; - } - else + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + $this->db = $db; + } + + /** + * Output key field for an editable field + * + * @param string $text Text of label or key to translate + * @param string $htmlname Name of select field ('edit' prefix will be added) + * @param string $preselected Value to show/edit (not used in this function) + * @param object $object Object + * @param boolean $perm Permission to allow button to edit parameter. Set it to 0 to have a not edited field. + * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...) + * @param string $moreparam More param to add on a href URL. + * @param int $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. + * @param int $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' + * @return string HTML edit field + */ + function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata='string', $moreparam='', $fieldrequired=0, $notabletag=0) + { + global $conf,$langs; + + $ret=''; + + // TODO change for compatibility + if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;/',$typeofdata)) + { + if (! empty($perm)) + { + $tmp=explode(':',$typeofdata); + $ret.= '<div class="editkey_'.$tmp[0].(! empty($tmp[1]) ? ' '.$tmp[1] : '').'" id="'.$htmlname.'">'; + if ($fieldrequired) $ret.='<span class="fieldrequired">'; + $ret.= $langs->trans($text); + if ($fieldrequired) $ret.='</span>'; + $ret.= '</div>'."\n"; + } + else + { + if ($fieldrequired) $ret.='<span class="fieldrequired">'; + $ret.= $langs->trans($text); + if ($fieldrequired) $ret.='</span>'; + } + } + else + { + if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<table class="nobordernopadding" width="100%"><tr><td class="nowrap">'; + if ($fieldrequired) $ret.='<span class="fieldrequired">'; + $ret.=$langs->trans($text); + if ($fieldrequired) $ret.='</span>'; + if (! empty($notabletag)) $ret.=' '; + if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</td>'; + if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<td align="right">'; + if ($htmlname && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='<a href="'.$_SERVER["PHP_SELF"].'?action=edit'.$htmlname.'&id='.$object->id.$moreparam.'">'.img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1)).'</a>'; + if (! empty($notabletag) && $notabletag == 1) $ret.=' : '; + if (! empty($notabletag) && $notabletag == 3) $ret.=' '; + if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</td>'; + if (empty($notabletag) && GETPOST('action','aZ09') != 'edit'.$htmlname && $perm) $ret.='</tr></table>'; + } + + return $ret; + } + + /** + * Output val field for an editable field + * + * @param string $text Text of label (not used in this function) + * @param string $htmlname Name of select field + * @param string $value Value to show/edit + * @param object $object Object + * @param boolean $perm Permission to allow button to edit parameter + * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datepickerhour', 'ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols', 'select:xxx'...) + * @param string $editvalue When in edit mode, use this value as $value instead of value (for example, you can provide here a formated price instead of value). Use '' to use same than $value + * @param object $extObject External object + * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') + * @param string $moreparam More param to add on a href URL + * @param int $notabletag Do no output table tags + * @return string HTML edit field + */ + function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata='string', $editvalue='', $extObject=null, $custommsg=null, $moreparam='', $notabletag=0) + { + global $conf,$langs,$db; + + $ret=''; + + // Check parameters + if (empty($typeofdata)) return 'ErrorBadParameter'; + + // When option to edit inline is activated + if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;|datehourpicker/',$typeofdata)) // TODO add jquery timepicker + { + $ret.=$this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg); + } + else + { + if (GETPOST('action','aZ09') == 'edit'.$htmlname) + { + $ret.="\n"; + $ret.='<form method="post" action="'.$_SERVER["PHP_SELF"].($moreparam?'?'.$moreparam:'').'">'; + $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">'; + $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $ret.='<input type="hidden" name="id" value="'.$object->id.'">'; + if (empty($notabletag)) $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">'; + if (empty($notabletag)) $ret.='<tr><td>'; + if (preg_match('/^(string|email)/',$typeofdata)) + { + $tmp=explode(':',$typeofdata); + $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($editvalue?$editvalue:$value).'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>'; + } + else if (preg_match('/^(numeric|amount)/',$typeofdata)) + { + $tmp=explode(':',$typeofdata); + $valuetoshow=price2num($editvalue?$editvalue:$value); + $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($valuetoshow!=''?price($valuetoshow):'').'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>'; + } + else if (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata)) + { + $tmp=explode(':',$typeofdata); + $cols=$tmp[2]; + $morealt=''; + if (preg_match('/%/',$cols)) + { + $morealt=' style="width: '.$cols.'"'; + $cols=''; + } + $ret.='<textarea id="'.$htmlname.'" name="'.$htmlname.'" wrap="soft" rows="'.($tmp[1]?$tmp[1]:'20').'"'.($cols?' cols="'.$cols.'"':'').$morealt.'">'.($editvalue?$editvalue:$value).'</textarea>'; + } + else if ($typeofdata == 'day' || $typeofdata == 'datepicker') + { + $ret.=$this->select_date($value,$htmlname,0,0,1,'form'.$htmlname,1,0,1); + } + else if ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') + { + $ret.=$this->select_date($value,$htmlname,1,1,1,'form'.$htmlname,1,0,1); + } + else if (preg_match('/^select;/',$typeofdata)) + { + $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata)); + foreach($arraydata as $val) + { + $tmp=explode(':',$val); + $arraylist[$tmp[0]]=$tmp[1]; + } + $ret.=$this->selectarray($htmlname,$arraylist,$value); + } + else if (preg_match('/^ckeditor/',$typeofdata)) + { + $tmp=explode(':',$typeofdata); + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor($htmlname, ($editvalue?$editvalue:$value), ($tmp[2]?$tmp[2]:''), ($tmp[3]?$tmp[3]:'100'), ($tmp[1]?$tmp[1]:'dolibarr_notes'), 'In', ($tmp[5]?$tmp[5]:0), true, true, ($tmp[6]?$tmp[6]:'20'), ($tmp[7]?$tmp[7]:'100')); + $ret.=$doleditor->Create(1); + } + if (empty($notabletag)) $ret.='</td>'; + + if (empty($notabletag)) $ret.='<td align="left">'; + //else $ret.='<div class="clearboth"></div>'; + $ret.='<input type="submit" class="button'.(empty($notabletag)?'':' ').'" name="modify" value="'.$langs->trans("Modify").'">'; + if (preg_match('/ckeditor|textarea/',$typeofdata) && empty($notabletag)) $ret.='<br>'."\n"; + $ret.='<input type="submit" class="button'.(empty($notabletag)?'':' ').'" name="cancel" value="'.$langs->trans("Cancel").'">'; + if (empty($notabletag)) $ret.='</td>'; + + if (empty($notabletag)) $ret.='</tr></table>'."\n"; + $ret.='</form>'."\n"; + } + else { if (preg_match('/^(email)/',$typeofdata)) $ret.=dol_print_email($value,0,0,0,0,1); - elseif (preg_match('/^(amount|numeric)/',$typeofdata)) $ret.=($value != '' ? price($value,'',$langs,0,-1,-1,$conf->currency) : ''); - elseif (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata)) $ret.=dol_htmlentitiesbr($value); - elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') $ret.=dol_print_date($value,'day'); - elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') $ret.=dol_print_date($value,'dayhour'); - else if (preg_match('/^select;/',$typeofdata)) - { - $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata)); - foreach($arraydata as $val) - { - $tmp=explode(':',$val); - $arraylist[$tmp[0]]=$tmp[1]; - } - $ret.=$arraylist[$value]; - } - else if (preg_match('/^ckeditor/',$typeofdata)) - { - $tmpcontent=dol_htmlentitiesbr($value); - if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) - { - $firstline=preg_replace('/<br>.*/','',$tmpcontent); - $firstline=preg_replace('/[\n\r].*/','',$firstline); - $tmpcontent=$firstline.((strlen($firstline) != strlen($tmpcontent))?'...':''); - } - $ret.=$tmpcontent; - } - else $ret.=$value; - } - } - return $ret; - } - - /** - * Output edit in place form - * - * @param object $object Object - * @param string $value Value to show/edit - * @param string $htmlname DIV ID (field name) - * @param int $condition Condition to edit - * @param string $inputType Type of input ('string', 'numeric', 'datepicker' ('day' do not work, don't know why), 'textarea:rows:cols', 'ckeditor:dolibarr_zzz:width:height:?:1:rows:cols', 'select:xxx') - * @param string $editvalue When in edit mode, use this value as $value instead of value - * @param object $extObject External object - * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') - * @return string HTML edit in place - */ - private function editInPlace($object, $value, $htmlname, $condition, $inputType='textarea', $editvalue=null, $extObject=null, $custommsg=null) - { - global $conf; - - $out=''; - - // Check parameters - if ($inputType == 'textarea') $value = dol_nl2br($value); - else if (preg_match('/^numeric/',$inputType)) $value = price($value); - else if ($inputType == 'day' || $inputType == 'datepicker') $value = dol_print_date($value, 'day'); - - if ($condition) - { - $element = false; - $table_element = false; - $fk_element = false; - $loadmethod = false; - $savemethod = false; - $ext_element = false; - $button_only = false; - $inputOption = ''; - - if (is_object($object)) - { - $element = $object->element; - $table_element = $object->table_element; - $fk_element = $object->id; - } + elseif (preg_match('/^(amount|numeric)/',$typeofdata)) $ret.=($value != '' ? price($value,'',$langs,0,-1,-1,$conf->currency) : ''); + elseif (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata)) $ret.=dol_htmlentitiesbr($value); + elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') $ret.=dol_print_date($value,'day'); + elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') $ret.=dol_print_date($value,'dayhour'); + else if (preg_match('/^select;/',$typeofdata)) + { + $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata)); + foreach($arraydata as $val) + { + $tmp=explode(':',$val); + $arraylist[$tmp[0]]=$tmp[1]; + } + $ret.=$arraylist[$value]; + } + else if (preg_match('/^ckeditor/',$typeofdata)) + { + $tmpcontent=dol_htmlentitiesbr($value); + if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) + { + $firstline=preg_replace('/<br>.*/','',$tmpcontent); + $firstline=preg_replace('/[\n\r].*/','',$firstline); + $tmpcontent=$firstline.((strlen($firstline) != strlen($tmpcontent))?'...':''); + } + $ret.=$tmpcontent; + } + else $ret.=$value; + } + } + return $ret; + } - if (is_object($extObject)) - { - $ext_element = $extObject->element; - } + /** + * Output edit in place form + * + * @param object $object Object + * @param string $value Value to show/edit + * @param string $htmlname DIV ID (field name) + * @param int $condition Condition to edit + * @param string $inputType Type of input ('string', 'numeric', 'datepicker' ('day' do not work, don't know why), 'textarea:rows:cols', 'ckeditor:dolibarr_zzz:width:height:?:1:rows:cols', 'select:xxx') + * @param string $editvalue When in edit mode, use this value as $value instead of value + * @param object $extObject External object + * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') + * @return string HTML edit in place + */ + private function editInPlace($object, $value, $htmlname, $condition, $inputType='textarea', $editvalue=null, $extObject=null, $custommsg=null) + { + global $conf; - if (preg_match('/^(string|email|numeric)/',$inputType)) - { - $tmp=explode(':',$inputType); - $inputType=$tmp[0]; - if (! empty($tmp[1])) $inputOption=$tmp[1]; - if (! empty($tmp[2])) $savemethod=$tmp[2]; + $out=''; + + // Check parameters + if ($inputType == 'textarea') $value = dol_nl2br($value); + else if (preg_match('/^numeric/',$inputType)) $value = price($value); + else if ($inputType == 'day' || $inputType == 'datepicker') $value = dol_print_date($value, 'day'); + + if ($condition) + { + $element = false; + $table_element = false; + $fk_element = false; + $loadmethod = false; + $savemethod = false; + $ext_element = false; + $button_only = false; + $inputOption = ''; + + if (is_object($object)) + { + $element = $object->element; + $table_element = $object->table_element; + $fk_element = $object->id; + } + + if (is_object($extObject)) + { + $ext_element = $extObject->element; + } + + if (preg_match('/^(string|email|numeric)/',$inputType)) + { + $tmp=explode(':',$inputType); + $inputType=$tmp[0]; + if (! empty($tmp[1])) $inputOption=$tmp[1]; + if (! empty($tmp[2])) $savemethod=$tmp[2]; $out.= '<input id="width_'.$htmlname.'" value="'.$inputOption.'" type="hidden"/>'."\n"; - } - else if ((preg_match('/^day$/',$inputType)) || (preg_match('/^datepicker/',$inputType)) || (preg_match('/^datehourpicker/',$inputType))) - { - $tmp=explode(':',$inputType); - $inputType=$tmp[0]; - if (! empty($tmp[1])) $inputOption=$tmp[1]; - if (! empty($tmp[2])) $savemethod=$tmp[2]; + } + else if ((preg_match('/^day$/',$inputType)) || (preg_match('/^datepicker/',$inputType)) || (preg_match('/^datehourpicker/',$inputType))) + { + $tmp=explode(':',$inputType); + $inputType=$tmp[0]; + if (! empty($tmp[1])) $inputOption=$tmp[1]; + if (! empty($tmp[2])) $savemethod=$tmp[2]; - $out.= '<input id="timestamp" type="hidden"/>'."\n"; // Use for timestamp format - } - else if (preg_match('/^(select|autocomplete)/',$inputType)) - { - $tmp=explode(':',$inputType); - $inputType=$tmp[0]; $loadmethod=$tmp[1]; - if (! empty($tmp[2])) $savemethod=$tmp[2]; - if (! empty($tmp[3])) $button_only=true; - } - else if (preg_match('/^textarea/',$inputType)) - { - $tmp=explode(':',$inputType); - $inputType=$tmp[0]; - $rows=(empty($tmp[1])?'8':$tmp[1]); - $cols=(empty($tmp[2])?'80':$tmp[2]); - } - else if (preg_match('/^ckeditor/',$inputType)) - { - $tmp=explode(':',$inputType); - $inputType=$tmp[0]; $toolbar=$tmp[1]; - if (! empty($tmp[2])) $width=$tmp[2]; - if (! empty($tmp[3])) $heigth=$tmp[3]; - if (! empty($tmp[4])) $savemethod=$tmp[4]; - - if (! empty($conf->fckeditor->enabled)) - { - $out.= '<input id="ckeditor_toolbar" value="'.$toolbar.'" type="hidden"/>'."\n"; - } - else - { - $inputType = 'textarea'; - } - } + $out.= '<input id="timestamp" type="hidden"/>'."\n"; // Use for timestamp format + } + else if (preg_match('/^(select|autocomplete)/',$inputType)) + { + $tmp=explode(':',$inputType); + $inputType=$tmp[0]; $loadmethod=$tmp[1]; + if (! empty($tmp[2])) $savemethod=$tmp[2]; + if (! empty($tmp[3])) $button_only=true; + } + else if (preg_match('/^textarea/',$inputType)) + { + $tmp=explode(':',$inputType); + $inputType=$tmp[0]; + $rows=(empty($tmp[1])?'8':$tmp[1]); + $cols=(empty($tmp[2])?'80':$tmp[2]); + } + else if (preg_match('/^ckeditor/',$inputType)) + { + $tmp=explode(':',$inputType); + $inputType=$tmp[0]; $toolbar=$tmp[1]; + if (! empty($tmp[2])) $width=$tmp[2]; + if (! empty($tmp[3])) $heigth=$tmp[3]; + if (! empty($tmp[4])) $savemethod=$tmp[4]; - $out.= '<input id="element_'.$htmlname.'" value="'.$element.'" type="hidden"/>'."\n"; - $out.= '<input id="table_element_'.$htmlname.'" value="'.$table_element.'" type="hidden"/>'."\n"; - $out.= '<input id="fk_element_'.$htmlname.'" value="'.$fk_element.'" type="hidden"/>'."\n"; - $out.= '<input id="loadmethod_'.$htmlname.'" value="'.$loadmethod.'" type="hidden"/>'."\n"; - if (! empty($savemethod)) $out.= '<input id="savemethod_'.$htmlname.'" value="'.$savemethod.'" type="hidden"/>'."\n"; - if (! empty($ext_element)) $out.= '<input id="ext_element_'.$htmlname.'" value="'.$ext_element.'" type="hidden"/>'."\n"; - if (! empty($custommsg)) - { - if (is_array($custommsg)) - { - if (!empty($custommsg['success'])) - $out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg['success'].'" type="hidden"/>'."\n"; - if (!empty($custommsg['error'])) - $out.= '<input id="errormsg_'.$htmlname.'" value="'.$custommsg['error'].'" type="hidden"/>'."\n"; - } - else - $out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg.'" type="hidden"/>'."\n"; - } - if ($inputType == 'textarea') { - $out.= '<input id="textarea_'.$htmlname.'_rows" value="'.$rows.'" type="hidden"/>'."\n"; - $out.= '<input id="textarea_'.$htmlname.'_cols" value="'.$cols.'" type="hidden"/>'."\n"; - } - $out.= '<span id="viewval_'.$htmlname.'" class="viewval_'.$inputType.($button_only ? ' inactive' : ' active').'">'.$value.'</span>'."\n"; - $out.= '<span id="editval_'.$htmlname.'" class="editval_'.$inputType.($button_only ? ' inactive' : ' active').' hideobject">'.(! empty($editvalue) ? $editvalue : $value).'</span>'."\n"; - } - else - { - $out = $value; - } - - return $out; - } - - /** - * Show a text and picto with tooltip on text or picto. - * Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip - * - * @param string $text Text to show - * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. - * @param int $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2 - * @param int $direction -1=image is before, 0=no image, 1=image is after - * @param string $img Html code for image (use img_xxx() function to get it) - * @param string $extracss Add a CSS style to td tags - * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span - * @param string $incbefore Include code before the text - * @param int $noencodehtmltext Do not encode into html entity the htmltext - * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) - * @return string Code html du tooltip (texte+picto) - * @see Use function textwithpicto if you can. - * TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip - */ - function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger='') - { - global $conf; - - if ($incbefore) $text = $incbefore.$text; - if (! $htmltext) return $text; - - $tag='td'; - if ($notabs == 2) $tag='div'; - if ($notabs == 3) $tag='span'; - // Sanitize tooltip - $htmltext=str_replace("\\","\\\\",$htmltext); - $htmltext=str_replace("\r","",$htmltext); - $htmltext=str_replace("\n","",$htmltext); - - $extrastyle=''; - if ($direction < 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-left: 3px !important;'; } - if ($direction > 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-right: 3px !important;'; } - - $classfortooltip='classfortooltip'; - - $s='';$textfordialog=''; - - $htmltext=str_replace('"',""",$htmltext); - if ($tooltiptrigger != '') - { - $classfortooltip='classfortooltiponclick'; - $textfordialog.='<div style="display: none;" id="idfortooltiponclick_'.$tooltiptrigger.'" class="classfortooltiponclicktext">'.$htmltext.'</div>'; - } - if ($tooltipon == 2 || $tooltipon == 3) - { - $paramfortooltipimg=' class="'.$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'"'; - if ($tooltiptrigger == '') $paramfortooltipimg.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on img tag to store tooltip - else $paramfortooltipimg.=' dolid="'.$tooltiptrigger.'"'; - } - else $paramfortooltipimg =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag - if ($tooltipon == 1 || $tooltipon == 3) - { - $paramfortooltiptd=' class="'.($tooltipon == 3 ? 'cursorpointer ' : '').$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'" '; - if ($tooltiptrigger == '') $paramfortooltiptd.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td tag to store tooltip - else $paramfortooltiptd.=' dolid="'.$tooltiptrigger.'"'; - } - else $paramfortooltiptd =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag - if (empty($notabs)) $s.='<table class="nobordernopadding" summary=""><tr style="height: auto;">'; - elseif ($notabs == 2) $s.='<div class="inline-block">'; - // Define value if value is before - if ($direction < 0) { - $s.='<'.$tag.$paramfortooltipimg; - if ($tag == 'td') { - $s .= ' valign="top" width="14"'; - } - $s.= '>'.$textfordialog.$img.'</'.$tag.'>'; - } - // Use another method to help avoid having a space in value in order to use this value with jquery - // Define label - if ((string) $text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.'</'.$tag.'>'; - // Define value if value is after - if ($direction > 0) { - $s.='<'.$tag.$paramfortooltipimg; - if ($tag == 'td') $s .= ' valign="middle" width="14"'; - $s.= '>'.$textfordialog.$img.'</'.$tag.'>'; - } - if (empty($notabs)) $s.='</tr></table>'; + if (! empty($conf->fckeditor->enabled)) + { + $out.= '<input id="ckeditor_toolbar" value="'.$toolbar.'" type="hidden"/>'."\n"; + } + else + { + $inputType = 'textarea'; + } + } + + $out.= '<input id="element_'.$htmlname.'" value="'.$element.'" type="hidden"/>'."\n"; + $out.= '<input id="table_element_'.$htmlname.'" value="'.$table_element.'" type="hidden"/>'."\n"; + $out.= '<input id="fk_element_'.$htmlname.'" value="'.$fk_element.'" type="hidden"/>'."\n"; + $out.= '<input id="loadmethod_'.$htmlname.'" value="'.$loadmethod.'" type="hidden"/>'."\n"; + if (! empty($savemethod)) $out.= '<input id="savemethod_'.$htmlname.'" value="'.$savemethod.'" type="hidden"/>'."\n"; + if (! empty($ext_element)) $out.= '<input id="ext_element_'.$htmlname.'" value="'.$ext_element.'" type="hidden"/>'."\n"; + if (! empty($custommsg)) + { + if (is_array($custommsg)) + { + if (!empty($custommsg['success'])) + $out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg['success'].'" type="hidden"/>'."\n"; + if (!empty($custommsg['error'])) + $out.= '<input id="errormsg_'.$htmlname.'" value="'.$custommsg['error'].'" type="hidden"/>'."\n"; + } + else + $out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg.'" type="hidden"/>'."\n"; + } + if ($inputType == 'textarea') { + $out.= '<input id="textarea_'.$htmlname.'_rows" value="'.$rows.'" type="hidden"/>'."\n"; + $out.= '<input id="textarea_'.$htmlname.'_cols" value="'.$cols.'" type="hidden"/>'."\n"; + } + $out.= '<span id="viewval_'.$htmlname.'" class="viewval_'.$inputType.($button_only ? ' inactive' : ' active').'">'.$value.'</span>'."\n"; + $out.= '<span id="editval_'.$htmlname.'" class="editval_'.$inputType.($button_only ? ' inactive' : ' active').' hideobject">'.(! empty($editvalue) ? $editvalue : $value).'</span>'."\n"; + } + else + { + $out = $value; + } + + return $out; + } + + /** + * Show a text and picto with tooltip on text or picto. + * Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip + * + * @param string $text Text to show + * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. + * @param int $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2 + * @param int $direction -1=image is before, 0=no image, 1=image is after + * @param string $img Html code for image (use img_xxx() function to get it) + * @param string $extracss Add a CSS style to td tags + * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span + * @param string $incbefore Include code before the text + * @param int $noencodehtmltext Do not encode into html entity the htmltext + * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @return string Code html du tooltip (texte+picto) + * @see Use function textwithpicto if you can. + * TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip + */ + function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger='') + { + global $conf; + + if ($incbefore) $text = $incbefore.$text; + if (! $htmltext) return $text; + + $tag='td'; + if ($notabs == 2) $tag='div'; + if ($notabs == 3) $tag='span'; + // Sanitize tooltip + $htmltext=str_replace("\\","\\\\",$htmltext); + $htmltext=str_replace("\r","",$htmltext); + $htmltext=str_replace("\n","",$htmltext); + + $extrastyle=''; + if ($direction < 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-left: 3px !important;'; } + if ($direction > 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-right: 3px !important;'; } + + $classfortooltip='classfortooltip'; + + $s='';$textfordialog=''; + + $htmltext=str_replace('"',""",$htmltext); + if ($tooltiptrigger != '') + { + $classfortooltip='classfortooltiponclick'; + $textfordialog.='<div style="display: none;" id="idfortooltiponclick_'.$tooltiptrigger.'" class="classfortooltiponclicktext">'.$htmltext.'</div>'; + } + if ($tooltipon == 2 || $tooltipon == 3) + { + $paramfortooltipimg=' class="'.$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'"'; + if ($tooltiptrigger == '') $paramfortooltipimg.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on img tag to store tooltip + else $paramfortooltipimg.=' dolid="'.$tooltiptrigger.'"'; + } + else $paramfortooltipimg =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag + if ($tooltipon == 1 || $tooltipon == 3) + { + $paramfortooltiptd=' class="'.($tooltipon == 3 ? 'cursorpointer ' : '').$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'" '; + if ($tooltiptrigger == '') $paramfortooltiptd.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td tag to store tooltip + else $paramfortooltiptd.=' dolid="'.$tooltiptrigger.'"'; + } + else $paramfortooltiptd =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag + if (empty($notabs)) $s.='<table class="nobordernopadding" summary=""><tr style="height: auto;">'; + elseif ($notabs == 2) $s.='<div class="inline-block">'; + // Define value if value is before + if ($direction < 0) { + $s.='<'.$tag.$paramfortooltipimg; + if ($tag == 'td') { + $s .= ' valign="top" width="14"'; + } + $s.= '>'.$textfordialog.$img.'</'.$tag.'>'; + } + // Use another method to help avoid having a space in value in order to use this value with jquery + // Define label + if ((string) $text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.'</'.$tag.'>'; + // Define value if value is after + if ($direction > 0) { + $s.='<'.$tag.$paramfortooltipimg; + if ($tag == 'td') $s .= ' valign="middle" width="14"'; + $s.= '>'.$textfordialog.$img.'</'.$tag.'>'; + } + if (empty($notabs)) $s.='</tr></table>'; elseif ($notabs == 2) $s.='</div>'; - return $s; - } - - /** - * Show a text with a picto and a tooltip on picto - * - * @param string $text Text to show - * @param string $htmltext Content of tooltip - * @param int $direction 1=Icon is after text, -1=Icon is before text, 0=no icon - * @param string $type Type of picto ('info', 'help', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath - * @param string $extracss Add a CSS style to td, div or span tag - * @param int $noencodehtmltext Do not encode into html entity the htmltext - * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span - * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) - * @return string HTML code of text, picto, tooltip - */ - function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger='') - { - global $conf, $langs; - - $alt = ''; - if ($tooltiptrigger) $alt=$langs->trans("ClickToShowHelp"); - - //For backwards compatibility - if ($type == '0') $type = 'info'; - elseif ($type == '1') $type = 'help'; - - // If info or help with no javascript, show only text - if (empty($conf->use_javascript_ajax)) - { - if ($type == 'info' || $type == 'help') return $text; - else - { - $alt = $htmltext; - $htmltext = ''; - } - } - - // If info or help with smartphone, show only text (tooltip can't works) - if (! empty($conf->dol_no_mouse_hover)) - { - if ($type == 'info' || $type == 'help') return $text; - } - - if ($type == 'info') $img = img_help(0, $alt); - elseif ($type == 'help') $img = img_help(($tooltiptrigger != '' ? 2 : 1), $alt); - elseif ($type == 'superadmin') $img = img_picto($alt, 'redstar'); - elseif ($type == 'admin') $img = img_picto($alt, 'star'); - elseif ($type == 'warning') $img = img_warning($alt); + return $s; + } + + /** + * Show a text with a picto and a tooltip on picto + * + * @param string $text Text to show + * @param string $htmltext Content of tooltip + * @param int $direction 1=Icon is after text, -1=Icon is before text, 0=no icon + * @param string $type Type of picto ('info', 'help', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath + * @param string $extracss Add a CSS style to td, div or span tag + * @param int $noencodehtmltext Do not encode into html entity the htmltext + * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span + * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @return string HTML code of text, picto, tooltip + */ + function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger='') + { + global $conf, $langs; + + $alt = ''; + if ($tooltiptrigger) $alt=$langs->trans("ClickToShowHelp"); + + //For backwards compatibility + if ($type == '0') $type = 'info'; + elseif ($type == '1') $type = 'help'; + + // If info or help with no javascript, show only text + if (empty($conf->use_javascript_ajax)) + { + if ($type == 'info' || $type == 'help') return $text; + else + { + $alt = $htmltext; + $htmltext = ''; + } + } + + // If info or help with smartphone, show only text (tooltip can't works) + if (! empty($conf->dol_no_mouse_hover)) + { + if ($type == 'info' || $type == 'help') return $text; + } + + if ($type == 'info') $img = img_help(0, $alt); + elseif ($type == 'help') $img = img_help(($tooltiptrigger != '' ? 2 : 1), $alt); + elseif ($type == 'superadmin') $img = img_picto($alt, 'redstar'); + elseif ($type == 'admin') $img = img_picto($alt, 'star'); + elseif ($type == 'warning') $img = img_warning($alt); else $img = img_picto($alt, $type); - return $this->textwithtooltip($text, $htmltext, ($tooltiptrigger?3:2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger); - } - - /** - * Generate select HTML to choose massaction - * - * @param string $selected Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default. - * @param int $arrayofaction array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action. - * @param int $alwaysvisible 1=select button always visible - * @return string Select list - */ - function selectMassAction($selected, $arrayofaction, $alwaysvisible=0) - { - global $conf,$langs,$hookmanager; - - if (count($arrayofaction) == 0) return; - - $disabled=0; - $ret='<div class="centpercent center">'; - $ret.='<select class="flat'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionselect" name="massaction"'.($disabled?' disabled="disabled"':'').'>'; - - // Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks. - $parameters=array(); - $reshook=$hookmanager->executeHooks('addMoreMassActions',$parameters); // Note that $action and $object may have been modified by hook - if (empty($reshook)) - { - $ret.='<option value="0"'.($disabled?' disabled="disabled"':'').'>-- '.$langs->trans("SelectAction").' --</option>'; - foreach($arrayofaction as $code => $label) - { - $ret.='<option value="'.$code.'"'.($disabled?' disabled="disabled"':'').'>'.$label.'</option>'; - } - } - $ret.=$hookmanager->resPrint; - - $ret.='</select>'; - // Warning: if you set submit button to disabled, post using 'Enter' will no more work. - $ret.='<input type="submit" name="confirmmassaction" class="button'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; - $ret.='</div>'; - - if (! empty($conf->use_javascript_ajax)) - { - $ret.='<!-- JS CODE TO ENABLE mass action select --> + return $this->textwithtooltip($text, $htmltext, ($tooltiptrigger?3:2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger); + } + + /** + * Generate select HTML to choose massaction + * + * @param string $selected Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default. + * @param int $arrayofaction array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action. + * @param int $alwaysvisible 1=select button always visible + * @return string Select list + */ + function selectMassAction($selected, $arrayofaction, $alwaysvisible=0) + { + global $conf,$langs,$hookmanager; + + if (count($arrayofaction) == 0) return; + + $disabled=0; + $ret='<div class="centpercent center">'; + $ret.='<select class="flat'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionselect" name="massaction"'.($disabled?' disabled="disabled"':'').'>'; + + // Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks. + $parameters=array(); + $reshook=$hookmanager->executeHooks('addMoreMassActions',$parameters); // Note that $action and $object may have been modified by hook + if (empty($reshook)) + { + $ret.='<option value="0"'.($disabled?' disabled="disabled"':'').'>-- '.$langs->trans("SelectAction").' --</option>'; + foreach($arrayofaction as $code => $label) + { + $ret.='<option value="'.$code.'"'.($disabled?' disabled="disabled"':'').'>'.$label.'</option>'; + } + } + $ret.=$hookmanager->resPrint; + + $ret.='</select>'; + // Warning: if you set submit button to disabled, post using 'Enter' will no more work. + $ret.='<input type="submit" name="confirmmassaction" class="button'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; + $ret.='</div>'; + + if (! empty($conf->use_javascript_ajax)) + { + $ret.='<!-- JS CODE TO ENABLE mass action select --> <script type="text/javascript"> function initCheckForSelect() { @@ -615,132 +615,132 @@ class Form }); </script> '; - } - - return $ret; - } - - /** - * Return combo list of activated countries, into language of user - * - * @param string $selected Id or Code or Label of preselected country - * @param string $htmlname Name of html select object - * @param string $htmloption Options html on select object - * @param integer $maxlength Max length for labels (0=no limit) - * @param string $morecss More css class - * @param string $usecodeaskey 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key - * @return string HTML string with select - */ - function select_country($selected='',$htmlname='country_id',$htmloption='',$maxlength=0,$morecss='minwidth300',$usecodeaskey='') - { - global $conf,$langs; - - $langs->load("dict"); - - $out=''; - $countryArray=array(); + } + + return $ret; + } + + /** + * Return combo list of activated countries, into language of user + * + * @param string $selected Id or Code or Label of preselected country + * @param string $htmlname Name of html select object + * @param string $htmloption Options html on select object + * @param integer $maxlength Max length for labels (0=no limit) + * @param string $morecss More css class + * @param string $usecodeaskey 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key + * @return string HTML string with select + */ + function select_country($selected='',$htmlname='country_id',$htmloption='',$maxlength=0,$morecss='minwidth300',$usecodeaskey='') + { + global $conf,$langs; + + $langs->load("dict"); + + $out=''; + $countryArray=array(); $favorite=array(); - $label=array(); + $label=array(); $atleastonefavorite=0; - $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_country"; - $sql.= " WHERE active > 0"; - //$sql.= " ORDER BY code ASC"; - - dol_syslog(get_class($this)."::select_country", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $out.= '<select id="select'.$htmlname.'" class="flat maxwidth200onsmartphone selectcountry'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" '.$htmloption.'>'; - $num = $this->db->num_rows($resql); - $i = 0; - if ($num) - { - $foundselected=false; - - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $countryArray[$i]['rowid'] = $obj->rowid; - $countryArray[$i]['code_iso'] = $obj->code_iso; - $countryArray[$i]['code_iso3'] = $obj->code_iso3; - $countryArray[$i]['label'] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso)!="Country".$obj->code_iso?$langs->transnoentitiesnoconv("Country".$obj->code_iso):($obj->label!='-'?$obj->label:'')); - $countryArray[$i]['favorite'] = $obj->favorite; - $favorite[$i] = $obj->favorite; + $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_country"; + $sql.= " WHERE active > 0"; + //$sql.= " ORDER BY code ASC"; + + dol_syslog(get_class($this)."::select_country", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $out.= '<select id="select'.$htmlname.'" class="flat maxwidth200onsmartphone selectcountry'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" '.$htmloption.'>'; + $num = $this->db->num_rows($resql); + $i = 0; + if ($num) + { + $foundselected=false; + + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $countryArray[$i]['rowid'] = $obj->rowid; + $countryArray[$i]['code_iso'] = $obj->code_iso; + $countryArray[$i]['code_iso3'] = $obj->code_iso3; + $countryArray[$i]['label'] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso)!="Country".$obj->code_iso?$langs->transnoentitiesnoconv("Country".$obj->code_iso):($obj->label!='-'?$obj->label:'')); + $countryArray[$i]['favorite'] = $obj->favorite; + $favorite[$i] = $obj->favorite; $label[$i] = dol_string_unaccent($countryArray[$i]['label']); - $i++; - } + $i++; + } - array_multisort($favorite, SORT_DESC, $label, SORT_ASC, $countryArray); + array_multisort($favorite, SORT_DESC, $label, SORT_ASC, $countryArray); - foreach ($countryArray as $row) - { - if ($row['favorite'] && $row['code_iso']) $atleastonefavorite++; + foreach ($countryArray as $row) + { + if ($row['favorite'] && $row['code_iso']) $atleastonefavorite++; if (empty($row['favorite']) && $atleastonefavorite) { $atleastonefavorite=0; $out.= '<option value="" disabled class="selectoptiondisabledwhite">----------------------</option>'; } - if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) ) - { - $foundselected=true; - $out.= '<option value="'.($usecodeaskey?($usecodeaskey=='code2'?$row['code_iso']:$row['code_iso3']):$row['rowid']).'" selected>'; - } - else + if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) ) { - $out.= '<option value="'.($usecodeaskey?($usecodeaskey=='code2'?$row['code_iso']:$row['code_iso3']):$row['rowid']).'">'; - } - $out.= dol_trunc($row['label'],$maxlength,'middle'); - if ($row['code_iso']) $out.= ' ('.$row['code_iso'] . ')'; - $out.= '</option>'; - } - } - $out.= '</select>'; - } - else + $foundselected=true; + $out.= '<option value="'.($usecodeaskey?($usecodeaskey=='code2'?$row['code_iso']:$row['code_iso3']):$row['rowid']).'" selected>'; + } + else + { + $out.= '<option value="'.($usecodeaskey?($usecodeaskey=='code2'?$row['code_iso']:$row['code_iso3']):$row['rowid']).'">'; + } + $out.= dol_trunc($row['label'],$maxlength,'middle'); + if ($row['code_iso']) $out.= ' ('.$row['code_iso'] . ')'; + $out.= '</option>'; + } + } + $out.= '</select>'; + } + else { - dol_print_error($this->db); - } + dol_print_error($this->db); + } - // Make select dynamic - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $out .= ajax_combobox('select'.$htmlname); + // Make select dynamic + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $out .= ajax_combobox('select'.$htmlname); - return $out; - } + return $out; + } /** - * Return select list of incoterms - * - * @param string $selected Id or Code of preselected incoterm - * @param string $location_incoterms Value of input location - * @param string $page Defined the form action - * @param string $htmlname Name of html select object - * @param string $htmloption Options html on select object - * @param int $forcecombo Force to use standard combo box (no ajax use) - * @param array $events Event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @return string HTML string with select and input - */ - function select_incoterms($selected='', $location_incoterms='', $page='', $htmlname='incoterm_id', $htmloption='', $forcecombo=1, $events=array()) - { - global $conf,$langs; - - $langs->load("dict"); - - $out=''; - $incotermArray=array(); - - $sql = "SELECT rowid, code"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_incoterms"; - $sql.= " WHERE active > 0"; - $sql.= " ORDER BY code ASC"; - - dol_syslog(get_class($this)."::select_incoterm", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($conf->use_javascript_ajax && ! $forcecombo) + * Return select list of incoterms + * + * @param string $selected Id or Code of preselected incoterm + * @param string $location_incoterms Value of input location + * @param string $page Defined the form action + * @param string $htmlname Name of html select object + * @param string $htmloption Options html on select object + * @param int $forcecombo Force to use standard combo box (no ajax use) + * @param array $events Event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @return string HTML string with select and input + */ + function select_incoterms($selected='', $location_incoterms='', $page='', $htmlname='incoterm_id', $htmloption='', $forcecombo=1, $events=array()) + { + global $conf,$langs; + + $langs->load("dict"); + + $out=''; + $incotermArray=array(); + + $sql = "SELECT rowid, code"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_incoterms"; + $sql.= " WHERE active > 0"; + $sql.= " ORDER BY code ASC"; + + dol_syslog(get_class($this)."::select_incoterm", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($conf->use_javascript_ajax && ! $forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $out .= ajax_combobox($htmlname, $events); @@ -749,896 +749,896 @@ class Form if (!empty($page)) { $out .= '<form method="post" action="'.$page.'">'; - $out .= '<input type="hidden" name="action" value="set_incoterms">'; - $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $out .= '<input type="hidden" name="action" value="set_incoterms">'; + $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; } - $out.= '<select id="'.$htmlname.'" class="flat selectincoterm noenlargeonsmartphone" name="'.$htmlname.'" '.$htmloption.'>'; + $out.= '<select id="'.$htmlname.'" class="flat selectincoterm noenlargeonsmartphone" name="'.$htmlname.'" '.$htmloption.'>'; $out.= '<option value="0"> </option>'; - $num = $this->db->num_rows($resql); - $i = 0; - if ($num) - { - $foundselected=false; - - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $incotermArray[$i]['rowid'] = $obj->rowid; - $incotermArray[$i]['code'] = $obj->code; - $i++; - } + $num = $this->db->num_rows($resql); + $i = 0; + if ($num) + { + $foundselected=false; - foreach ($incotermArray as $row) - { - if ($selected && ($selected == $row['rowid'] || $selected == $row['code'])) - { - $out.= '<option value="'.$row['rowid'].'" selected>'; - } - else + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $incotermArray[$i]['rowid'] = $obj->rowid; + $incotermArray[$i]['code'] = $obj->code; + $i++; + } + + foreach ($incotermArray as $row) + { + if ($selected && ($selected == $row['rowid'] || $selected == $row['code'])) { - $out.= '<option value="'.$row['rowid'].'">'; - } + $out.= '<option value="'.$row['rowid'].'" selected>'; + } + else + { + $out.= '<option value="'.$row['rowid'].'">'; + } - if ($row['code']) $out.= $row['code']; + if ($row['code']) $out.= $row['code']; $out.= '</option>'; - } - } - $out.= '</select>'; + } + } + $out.= '</select>'; $out .= '<input id="location_incoterms" class="maxwidth100onsmartphone" name="location_incoterms" value="'.$location_incoterms.'">'; if (!empty($page)) { - $out .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'"></form>'; - } - } - else - { - dol_print_error($this->db); - } - - return $out; - } - - /** - * Return list of types of lines (product or service) - * Example: 0=product, 1=service, 9=other (for external module) - * - * @param string $selected Preselected type - * @param string $htmlname Name of field in html form - * @param int $showempty Add an empty field - * @param int $hidetext Do not show label 'Type' before combo box (used only if there is at least 2 choices to select) - * @param integer $forceall 1=Force to show products and services in combo list, whatever are activated modules, 0=No force, -1=Force none (and set hidden field to 'service') - * @return void - */ - function select_type_of_lines($selected='',$htmlname='type',$showempty=0,$hidetext=0,$forceall=0) - { - global $db,$langs,$user,$conf; - - // If product & services are enabled or both disabled. - if ($forceall > 0 || (empty($forceall) && ! empty($conf->product->enabled) && ! empty($conf->service->enabled)) - || (empty($forceall) && empty($conf->product->enabled) && empty($conf->service->enabled)) ) - { - if (empty($hidetext)) print $langs->trans("Type").': '; - print '<select class="flat" id="select_'.$htmlname.'" name="'.$htmlname.'">'; - if ($showempty) - { - print '<option value="-1"'; - if ($selected == -1) print ' selected'; - print '> </option>'; - } + $out .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'"></form>'; + } + } + else + { + dol_print_error($this->db); + } + + return $out; + } + + /** + * Return list of types of lines (product or service) + * Example: 0=product, 1=service, 9=other (for external module) + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in html form + * @param int $showempty Add an empty field + * @param int $hidetext Do not show label 'Type' before combo box (used only if there is at least 2 choices to select) + * @param integer $forceall 1=Force to show products and services in combo list, whatever are activated modules, 0=No force, -1=Force none (and set hidden field to 'service') + * @return void + */ + function select_type_of_lines($selected='',$htmlname='type',$showempty=0,$hidetext=0,$forceall=0) + { + global $db,$langs,$user,$conf; + + // If product & services are enabled or both disabled. + if ($forceall > 0 || (empty($forceall) && ! empty($conf->product->enabled) && ! empty($conf->service->enabled)) + || (empty($forceall) && empty($conf->product->enabled) && empty($conf->service->enabled)) ) + { + if (empty($hidetext)) print $langs->trans("Type").': '; + print '<select class="flat" id="select_'.$htmlname.'" name="'.$htmlname.'">'; + if ($showempty) + { + print '<option value="-1"'; + if ($selected == -1) print ' selected'; + print '> </option>'; + } + + print '<option value="0"'; + if (0 == $selected) print ' selected'; + print '>'.$langs->trans("Product"); + + print '<option value="1"'; + if (1 == $selected) print ' selected'; + print '>'.$langs->trans("Service"); - print '<option value="0"'; - if (0 == $selected) print ' selected'; - print '>'.$langs->trans("Product"); - - print '<option value="1"'; - if (1 == $selected) print ' selected'; - print '>'.$langs->trans("Service"); - - print '</select>'; - //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - } - if (empty($forceall) && empty($conf->product->enabled) && ! empty($conf->service->enabled)) - { - print $langs->trans("Service"); - print '<input type="hidden" name="'.$htmlname.'" value="1">'; - } - if (empty($forceall) && ! empty($conf->product->enabled) && empty($conf->service->enabled)) - { - print $langs->trans("Product"); - print '<input type="hidden" name="'.$htmlname.'" value="0">'; - } + print '</select>'; + //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + } + if (empty($forceall) && empty($conf->product->enabled) && ! empty($conf->service->enabled)) + { + print $langs->trans("Service"); + print '<input type="hidden" name="'.$htmlname.'" value="1">'; + } + if (empty($forceall) && ! empty($conf->product->enabled) && empty($conf->service->enabled)) + { + print $langs->trans("Product"); + print '<input type="hidden" name="'.$htmlname.'" value="0">'; + } if ($forceall < 0) // This should happened only for contracts when both predefined product and service are disabled. { - print '<input type="hidden" name="'.$htmlname.'" value="1">'; // By default we set on service for contract. If CONTRACT_SUPPORT_PRODUCTS is set, forceall should be 1 not -1 + print '<input type="hidden" name="'.$htmlname.'" value="1">'; // By default we set on service for contract. If CONTRACT_SUPPORT_PRODUCTS is set, forceall should be 1 not -1 } - } + } - /** - * Load into cache cache_types_fees, array of types of fees - * - * @return int Nb of lines loaded, <0 if KO - */ - function load_cache_types_fees() - { - global $langs; + /** + * Load into cache cache_types_fees, array of types of fees + * + * @return int Nb of lines loaded, <0 if KO + */ + function load_cache_types_fees() + { + global $langs; - $num = count($this->cache_types_fees); - if ($num > 0) return 0; // Cache already loaded + $num = count($this->cache_types_fees); + if ($num > 0) return 0; // Cache already loaded - dol_syslog(__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); - $langs->load("trips"); + $langs->load("trips"); - $sql = "SELECT c.code, c.label"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c"; - $sql.= " WHERE active > 0"; + $sql = "SELECT c.code, c.label"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c"; + $sql.= " WHERE active > 0"; - $resql=$this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; + $resql=$this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $label=($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label)); - $this->cache_types_fees[$obj->code] = $label; - $i++; - } + // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut + $label=($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label)); + $this->cache_types_fees[$obj->code] = $label; + $i++; + } asort($this->cache_types_fees); - return $num; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Return list of types of notes - * - * @param string $selected Preselected type - * @param string $htmlname Name of field in form - * @param int $showempty Add an empty field - * @return void - */ - function select_type_fees($selected='',$htmlname='type',$showempty=0) - { - global $user, $langs; - - dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); - - $this->load_cache_types_fees(); - - print '<select class="flat" name="'.$htmlname.'">'; - if ($showempty) - { - print '<option value="-1"'; - if ($selected == -1) print ' selected'; - print '> </option>'; - } - - foreach($this->cache_types_fees as $key => $value) - { - print '<option value="'.$key.'"'; - if ($key == $selected) print ' selected'; - print '>'; - print $value; - print '</option>'; - } - - print '</select>'; - if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - } - - - /** - * Return HTML code to select a company. - * - * @param int $selected Preselected products - * @param string $htmlname Name of HTML select field (must be unique in page) - * @param int $filter Filter on thirdparty - * @param int $limit Limit on number of returned lines - * @param array $ajaxoptions Options for ajax_autocompleter - * @param int $forcecombo Force to use combo box - * @return string Return select box for thirdparty. + return $num; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Return list of types of notes + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param int $showempty Add an empty field + * @return void + */ + function select_type_fees($selected='',$htmlname='type',$showempty=0) + { + global $user, $langs; + + dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); + + $this->load_cache_types_fees(); + + print '<select class="flat" name="'.$htmlname.'">'; + if ($showempty) + { + print '<option value="-1"'; + if ($selected == -1) print ' selected'; + print '> </option>'; + } + + foreach($this->cache_types_fees as $key => $value) + { + print '<option value="'.$key.'"'; + if ($key == $selected) print ' selected'; + print '>'; + print $value; + print '</option>'; + } + + print '</select>'; + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + } + + + /** + * Return HTML code to select a company. + * + * @param int $selected Preselected products + * @param string $htmlname Name of HTML select field (must be unique in page) + * @param int $filter Filter on thirdparty + * @param int $limit Limit on number of returned lines + * @param array $ajaxoptions Options for ajax_autocompleter + * @param int $forcecombo Force to use combo box + * @return string Return select box for thirdparty. * @deprecated 3.8 Use select_company instead. For exemple $form->select_thirdparty(GETPOST('socid'),'socid','',0) => $form->select_company(GETPOST('socid'),'socid','',1,0,0,array(),0) - */ - function select_thirdparty($selected='', $htmlname='socid', $filter='', $limit=20, $ajaxoptions=array(), $forcecombo=0) - { + */ + function select_thirdparty($selected='', $htmlname='socid', $filter='', $limit=20, $ajaxoptions=array(), $forcecombo=0) + { return $this->select_thirdparty_list($selected,$htmlname,$filter,1,0,$forcecombo,array(),'',0, $limit); - } - - /** - * Output html form to select a third party - * - * @param string $selected Preselected type - * @param string $htmlname Name of field in form - * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)') - * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param int $limit Maximum number of elements - * @param string $morecss Add more css styles to the SELECT component - * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container + } + + /** + * Output html form to select a third party + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)') + * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') + * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int $forcecombo Force to use combo box + * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param int $limit Maximum number of elements + * @param string $morecss Add more css styles to the SELECT component + * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) - * @param array $ajaxoptions Options for ajax_autocompleter - * @return string HTML string with select box for thirdparty. - */ - function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='', $selected_input_value='', $hidelabel=1, $ajaxoptions=array()) - { - global $conf,$user,$langs; - - $out=''; - - if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo) - { - // No immediate load of all database - $placeholder=''; - if ($selected && empty($selected_input_value)) - { - require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; - $societetmp = new Societe($this->db); - $societetmp->fetch($selected); - $selected_input_value=$societetmp->name; - unset($societetmp); - } - // mode 1 - $urloption='htmlname='.$htmlname.'&outjson=1&filter='.$filter.($showtype?'&showtype='.$showtype:''); - $out.= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) + * @param array $ajaxoptions Options for ajax_autocompleter + * @return string HTML string with select box for thirdparty. + */ + function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='', $selected_input_value='', $hidelabel=1, $ajaxoptions=array()) + { + global $conf,$user,$langs; + + $out=''; + + if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo) + { + // No immediate load of all database + $placeholder=''; + if ($selected && empty($selected_input_value)) + { + require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + $societetmp = new Societe($this->db); + $societetmp->fetch($selected); + $selected_input_value=$societetmp->name; + unset($societetmp); + } + // mode 1 + $urloption='htmlname='.$htmlname.'&outjson=1&filter='.$filter.($showtype?'&showtype='.$showtype:''); + $out.= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); $out.='<style type="text/css"> .ui-autocomplete { z-index: 250; } </style>'; - if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : '; - else if ($hidelabel > 1) { - if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"'; - else $placeholder=' title="'.$langs->trans("RefOrLabel").'"'; - if ($hidelabel == 2) { - $out.= img_picto($langs->trans("Search"), 'search'); - } - } - $out.= '<input type="text" class="'.$morecss.'" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; - if ($hidelabel == 3) { - $out.= img_picto($langs->trans("Search"), 'search'); - } - } - else - { - // Immediate load of all database - $out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam); - } - - return $out; - } - - /** - * Output html form to select a third party. - * Note, you must use the select_company to get the component to select a third party. This function must only be called by select_company. - * - * @param string $selected Preselected type - * @param string $htmlname Name of field in form - * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)') - * @param string $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty') - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param string $filterkey Filter on key value - * @param int $outputmode 0=HTML select string, 1=Array - * @param int $limit Limit number of answers - * @param string $morecss Add more css styles to the SELECT component - * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container - * @return string HTML string with - */ - function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty='', $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='') - { - global $conf,$user,$langs; - - $out=''; - $num=0; - $outarray=array(); - - // On recherche les societes - $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur"; - $sql.= " FROM ".MAIN_DB_PREFIX ."societe as s"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.entity IN (".getEntity('societe').")"; - if (! empty($user->societe_id)) $sql.= " AND s.rowid = ".$user->societe_id; - if ($filter) $sql.= " AND (".$filter.")"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if (! empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND s.status <> 0"; - // Add criteria - if ($filterkey && $filterkey != '') - { + if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : '; + else if ($hidelabel > 1) { + if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"'; + else $placeholder=' title="'.$langs->trans("RefOrLabel").'"'; + if ($hidelabel == 2) { + $out.= img_picto($langs->trans("Search"), 'search'); + } + } + $out.= '<input type="text" class="'.$morecss.'" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; + if ($hidelabel == 3) { + $out.= img_picto($langs->trans("Search"), 'search'); + } + } + else + { + // Immediate load of all database + $out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam); + } + + return $out; + } + + /** + * Output html form to select a third party. + * Note, you must use the select_company to get the component to select a third party. This function must only be called by select_company. + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)') + * @param string $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty') + * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int $forcecombo Force to use combo box + * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param string $filterkey Filter on key value + * @param int $outputmode 0=HTML select string, 1=Array + * @param int $limit Limit number of answers + * @param string $morecss Add more css styles to the SELECT component + * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container + * @return string HTML string with + */ + function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty='', $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='') + { + global $conf,$user,$langs; + + $out=''; + $num=0; + $outarray=array(); + + // On recherche les societes + $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe as s"; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE s.entity IN (".getEntity('societe').")"; + if (! empty($user->societe_id)) $sql.= " AND s.rowid = ".$user->societe_id; + if ($filter) $sql.= " AND (".$filter.")"; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if (! empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND s.status <> 0"; + // Add criteria + if ($filterkey && $filterkey != '') + { $sql.=" AND ("; - $prefix=empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on - // For natural search - $scrit = explode(' ', $filterkey); - $i=0; - if (count($scrit) > 1) $sql.="("; - foreach ($scrit as $crit) { - if ($i > 0) $sql.=" AND "; - $sql.="(s.nom LIKE '".$this->db->escape($prefix.$crit)."%')"; - $i++; - } - if (count($scrit) > 1) $sql.=")"; - if (! empty($conf->barcode->enabled)) - { - $sql .= " OR s.barcode LIKE '".$this->db->escape($filterkey)."%'"; - } - $sql.=")"; - } - $sql.=$this->db->order("nom","ASC"); + $prefix=empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on + // For natural search + $scrit = explode(' ', $filterkey); + $i=0; + if (count($scrit) > 1) $sql.="("; + foreach ($scrit as $crit) { + if ($i > 0) $sql.=" AND "; + $sql.="(s.nom LIKE '".$this->db->escape($prefix.$crit)."%')"; + $i++; + } + if (count($scrit) > 1) $sql.=")"; + if (! empty($conf->barcode->enabled)) + { + $sql .= " OR s.barcode LIKE '".$this->db->escape($filterkey)."%'"; + } + $sql.=")"; + } + $sql.=$this->db->order("nom","ASC"); $sql.=$this->db->plimit($limit, 0); // Build output string - dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($conf->use_javascript_ajax && ! $forcecombo) - { + dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($conf->use_javascript_ajax && ! $forcecombo) + { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); - $out.= $comboenhancement; - } + $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); + $out.= $comboenhancement; + } - // Construct $out and $outarray - $out.= '<select id="'.$htmlname.'" class="flat'.($morecss?' '.$morecss:'').'"'.($moreparam?' '.$moreparam:'').' name="'.$htmlname.'">'."\n"; + // Construct $out and $outarray + $out.= '<select id="'.$htmlname.'" class="flat'.($morecss?' '.$morecss:'').'"'.($moreparam?' '.$moreparam:'').' name="'.$htmlname.'">'."\n"; - $textifempty=''; - // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. - //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty=''; - if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) - { - if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty); - else $textifempty.=$langs->trans("All"); - } - if ($showempty) $out.= '<option value="-1">'.$textifempty.'</option>'."\n"; + $textifempty=''; + // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. + //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty=''; + if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) + { + if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty); + else $textifempty.=$langs->trans("All"); + } + if ($showempty) $out.= '<option value="-1">'.$textifempty.'</option>'."\n"; $num = $this->db->num_rows($resql); - $i = 0; - if ($num) - { - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $label=''; - if ($conf->global->SOCIETE_ADD_REF_IN_LIST) { - if (($obj->client) && (!empty($obj->code_client))) { - $label = $obj->code_client. ' - '; - } - if (($obj->fournisseur) && (!empty($obj->code_fournisseur))) { - $label .= $obj->code_fournisseur. ' - '; - } - $label.=' '.$obj->name; - } - else - { - $label=$obj->name; - } + $i = 0; + if ($num) + { + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $label=''; + if ($conf->global->SOCIETE_ADD_REF_IN_LIST) { + if (($obj->client) && (!empty($obj->code_client))) { + $label = $obj->code_client. ' - '; + } + if (($obj->fournisseur) && (!empty($obj->code_fournisseur))) { + $label .= $obj->code_fournisseur. ' - '; + } + $label.=' '.$obj->name; + } + else + { + $label=$obj->name; + } if(!empty($obj->name_alias)) { $label.=' ('.$obj->name_alias.')'; } - if ($showtype) - { - if ($obj->client || $obj->fournisseur) $label.=' ('; - if ($obj->client == 1 || $obj->client == 3) $label.=$langs->trans("Customer"); - if ($obj->client == 2 || $obj->client == 3) $label.=($obj->client==3?', ':'').$langs->trans("Prospect"); - if ($obj->fournisseur) $label.=($obj->client?', ':'').$langs->trans("Supplier"); - if ($obj->client || $obj->fournisseur) $label.=')'; - } - if ($selected > 0 && $selected == $obj->rowid) - { - $out.= '<option value="'.$obj->rowid.'" selected>'.$label.'</option>'; - } - else + if ($showtype) { - $out.= '<option value="'.$obj->rowid.'">'.$label.'</option>'; - } - - array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label)); - - $i++; - if (($i % 10) == 0) $out.="\n"; - } - } - $out.= '</select>'."\n"; - } - else - { - dol_print_error($this->db); - } - - $this->result=array('nbofthirdparties'=>$num); - - if ($outputmode) return $outarray; - return $out; - } - - - /** - * Return HTML combo list of absolute discounts - * - * @param string $selected Id remise fixe pre-selectionnee - * @param string $htmlname Nom champ formulaire - * @param string $filter Criteres optionnels de filtre - * @param int $socid Id of thirdparty - * @param int $maxvalue Max value for lines that can be selected - * @return int Return number of qualifed lines in list - */ - function select_remises($selected, $htmlname, $filter, $socid, $maxvalue=0) - { - global $langs,$conf; - - // On recherche les remises - $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; - $sql.= " re.description, re.fk_facture_source"; - $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; - $sql.= " WHERE re.fk_soc = ".(int) $socid; - $sql.= " AND re.entity = " . $conf->entity; - if ($filter) $sql.= " AND ".$filter; - $sql.= " ORDER BY re.description ASC"; - - dol_syslog(get_class($this)."::select_remises", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - print '<select class="flat maxwidthonsmartphone" name="'.$htmlname.'">'; - $num = $this->db->num_rows($resql); - - $qualifiedlines=$num; - - $i = 0; - if ($num) - { - print '<option value="0"> </option>'; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $desc=dol_trunc($obj->description,40); - if (preg_match('/\(CREDIT_NOTE\)/', $desc)) $desc=preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc); - if (preg_match('/\(DEPOSIT\)/', $desc)) $desc=preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc); - if (preg_match('/\(EXCESS RECEIVED\)/', $desc)) $desc=preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc); - - $selectstring=''; - if ($selected > 0 && $selected == $obj->rowid) $selectstring=' selected'; - - $disabled=''; - if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue) - { - $qualifiedlines--; - $disabled=' disabled'; - } - - print '<option value="'.$obj->rowid.'"'.$selectstring.$disabled.'>'.$desc.' ('.price($obj->amount_ht).' '.$langs->trans("HT").' - '.price($obj->amount_ttc).' '.$langs->trans("TTC").')</option>'; - $i++; - } - } - print '</select>'; - return $qualifiedlines; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Return list of all contacts (for a third party or all) - * - * @param int $socid Id ot third party or 0 for all - * @param string $selected Id contact pre-selectionne - * @param string $htmlname Name of HTML field ('none' for a not editable field) - * @param int $showempty 0=no empty value, 1=add an empty value - * @param string $exclude List of contacts id to exclude - * @param string $limitto Disable answers that are not id in this array list - * @param integer $showfunction Add function into label - * @param string $moreclass Add more class to class style - * @param integer $showsoc Add company into label - * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param bool $options_only Return options only (for ajax treatment) - * @return int <0 if KO, Nb of contact in list if OK - * @deprected You can use selectcontacts directly (warning order of param was changed) - */ - function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false) - { - print $this->selectcontacts($socid,$selected,$htmlname,$showempty,$exclude,$limitto,$showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events); - return $this->num; - } - - /** - * Return HTML code of the SELECT of list of all contacts (for a third party or all). - * This also set the number of contacts found into $this->num - * - * @param int $socid Id ot third party or 0 for all - * @param string $selected Id contact pre-selectionne - * @param string $htmlname Name of HTML field ('none' for a not editable field) - * @param int $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit) - * @param string $exclude List of contacts id to exclude - * @param string $limitto Disable answers that are not id in this array list - * @param integer $showfunction Add function into label - * @param string $moreclass Add more class to class style - * @param bool $options_only Return options only (for ajax treatment) - * @param integer $showsoc Add company into label - * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @return int <0 if KO, Nb of contact in list if OK - */ - function selectcontacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array()) - { - global $conf,$langs; - - $langs->load('companies'); - - $out=''; - - // On recherche les societes - $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste"; - if ($showsoc > 0) $sql.= " , s.nom as company"; - $sql.= " FROM ".MAIN_DB_PREFIX ."socpeople as sp"; - if ($showsoc > 0) $sql.= " LEFT OUTER JOIN ".MAIN_DB_PREFIX ."societe as s ON s.rowid=sp.fk_soc"; - $sql.= " WHERE sp.entity IN (".getEntity('societe').")"; - if ($socid > 0) $sql.= " AND sp.fk_soc=".$socid; - if (! empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND sp.statut <> 0"; - $sql.= " ORDER BY sp.lastname ASC"; - - dol_syslog(get_class($this)."::select_contacts", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $num=$this->db->num_rows($resql); - - if ($conf->use_javascript_ajax && ! $forcecombo && ! $options_only) - { - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement = ajax_combobox($htmlname, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT); - $out.= $comboenhancement; - } - - if ($htmlname != 'none' || $options_only) $out.= '<select class="flat'.($moreclass?' '.$moreclass:'').'" id="'.$htmlname.'" name="'.$htmlname.'">'; - if ($showempty == 1) $out.= '<option value="0"'.($selected=='0'?' selected':'').'></option>'; - if ($showempty == 2) $out.= '<option value="0"'.($selected=='0'?' selected':'').'>'.$langs->trans("Internal").'</option>'; - $num = $this->db->num_rows($resql); - $i = 0; - if ($num) - { - include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; - $contactstatic=new Contact($this->db); + if ($obj->client || $obj->fournisseur) $label.=' ('; + if ($obj->client == 1 || $obj->client == 3) $label.=$langs->trans("Customer"); + if ($obj->client == 2 || $obj->client == 3) $label.=($obj->client==3?', ':'').$langs->trans("Prospect"); + if ($obj->fournisseur) $label.=($obj->client?', ':'').$langs->trans("Supplier"); + if ($obj->client || $obj->fournisseur) $label.=')'; + } + if ($selected > 0 && $selected == $obj->rowid) + { + $out.= '<option value="'.$obj->rowid.'" selected>'.$label.'</option>'; + } + else + { + $out.= '<option value="'.$obj->rowid.'">'.$label.'</option>'; + } - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label)); - $contactstatic->id=$obj->rowid; - $contactstatic->lastname=$obj->lastname; - $contactstatic->firstname=$obj->firstname; - if ($obj->statut == 1){ - if ($htmlname != 'none') - { - $disabled=0; - if (is_array($exclude) && count($exclude) && in_array($obj->rowid,$exclude)) $disabled=1; - if (is_array($limitto) && count($limitto) && ! in_array($obj->rowid,$limitto)) $disabled=1; - if ($selected && $selected == $obj->rowid) - { - $out.= '<option value="'.$obj->rowid.'"'; - if ($disabled) $out.= ' disabled'; - $out.= ' selected>'; - $out.= $contactstatic->getFullName($langs); - if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')'; - if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')'; - $out.= '</option>'; - } - else - { - $out.= '<option value="'.$obj->rowid.'"'; - if ($disabled) $out.= ' disabled'; - $out.= '>'; - $out.= $contactstatic->getFullName($langs); - if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')'; - if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')'; - $out.= '</option>'; - } - } - else - { - if ($selected == $obj->rowid) - { - $out.= $contactstatic->getFullName($langs); - if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')'; - if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')'; - } - } + $i++; + if (($i % 10) == 0) $out.="\n"; } - $i++; - } - } - else - { - $out.= '<option value="-1"'.($showempty==2?'':' selected').' disabled>'.$langs->trans($socid?"NoContactDefinedForThirdParty":"NoContactDefined").'</option>'; - } - if ($htmlname != 'none' || $options_only) - { - $out.= '</select>'; - } - - $this->num = $num; - return $out; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Return select list of users - * - * @param string $selected Id user preselected - * @param string $htmlname Field name in form - * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array $include Array list of users id to include - * @param int $enableonly Array list of users id to be enabled. All other must be disabled - * @param int $force_entity 0 or Id of environment to force - * @return void - * @deprecated Use select_dolusers instead - * @see select_dolusers() - */ - function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude=null,$disabled=0,$include='',$enableonly='',$force_entity=0) - { - print $this->select_dolusers($selected,$htmlname,$show_empty,$exclude,$disabled,$include,$enableonly,$force_entity); - } - - /** - * Return select list of users - * - * @param string $selected User id or user object of user preselected. If -1, we use id of current user. - * @param string $htmlname Field name in form - * @param int $show_empty 0=list with no empty value, 1=add also an empty value into list - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array|string $include Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me - * @param array $enableonly Array list of users id to be enabled. If defined, it means that other must be disabled - * @param int $force_entity 0 or Id of environment to force - * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status - * @param string $morefilter Add more filters into sql request - * @param integer $show_every 0=default list, 1=add also a value "Everybody" at beginning of list - * @param string $enableonlytext If option $enableonlytext is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty. - * @param string $morecss More css - * @param int $noactive Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on). - * @return string HTML select string - * @see select_dolgroups - */ - function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0) - { - global $conf,$user,$langs; - - // If no preselected user defined, we take current user - if ((is_numeric($selected) && ($selected < -2 || empty($selected))) && empty($conf->global->SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE)) $selected=$user->id; - - $excludeUsers=null; - $includeUsers=null; - - // Permettre l'exclusion d'utilisateurs - if (is_array($exclude)) $excludeUsers = implode(",",$exclude); - // Permettre l'inclusion d'utilisateurs - if (is_array($include)) $includeUsers = implode(",",$include); - else if ($include == 'hierarchy') - { - // Build list includeUsers to have only hierarchy - $includeUsers = implode(",",$user->getAllChildIds(0)); + } + $out.= '</select>'."\n"; } - else if ($include == 'hierarchyme') + else { - // Build list includeUsers to have only hierarchy and current user - $includeUsers = implode(",",$user->getAllChildIds(1)); - } - - $out=''; - - // On recherche les utilisateurs - $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity"; - if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - $sql.= ", e.label"; - } - $sql.= " FROM ".MAIN_DB_PREFIX ."user as u"; - if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX ."entity as e ON e.rowid=u.entity"; - if ($force_entity) $sql.= " WHERE u.entity IN (0,".$force_entity.")"; - else $sql.= " WHERE u.entity IS NOT NULL"; - } - else - { - if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug"; - $sql.= " ON ug.fk_user = u.rowid"; - $sql.= " WHERE ug.entity = ".$conf->entity; - } - else - { - $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; - } - } - if (! empty($user->societe_id)) $sql.= " AND u.fk_soc = ".$user->societe_id; - if (is_array($exclude) && $excludeUsers) $sql.= " AND u.rowid NOT IN (".$excludeUsers.")"; - if ($includeUsers) $sql.= " AND u.rowid IN (".$includeUsers.")"; - if (! empty($conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive) $sql.= " AND u.statut <> 0"; - if (! empty($morefilter)) $sql.=" ".$morefilter; - - if(empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)){ - $sql.= " ORDER BY u.firstname ASC"; - }else{ - $sql.= " ORDER BY u.lastname ASC"; - } - - - dol_syslog(get_class($this)."::select_dolusers", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - if ($num) - { - // Enhance with select2 - if ($conf->use_javascript_ajax) - { - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement = ajax_combobox($htmlname); - $out.=$comboenhancement; - } - - // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined - $out.= '<select class="flat'.($morecss?' minwidth100 '.$morecss:' minwidth200').'" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>'; - if ($show_empty) $out.= '<option value="-1"'.((empty($selected) || $selected==-1)?' selected':'').'> </option>'."\n"; - if ($show_every) $out.= '<option value="-2"'.(($selected==-2)?' selected':'').'>-- '.$langs->trans("Everybody").' --</option>'."\n"; + dol_print_error($this->db); + } - $userstatic=new User($this->db); + $this->result=array('nbofthirdparties'=>$num); - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + if ($outputmode) return $outarray; + return $out; + } - $userstatic->id=$obj->rowid; - $userstatic->lastname=$obj->lastname; - $userstatic->firstname=$obj->firstname; - $disableline=''; - if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=($enableonlytext?$enableonlytext:'1'); + /** + * Return HTML combo list of absolute discounts + * + * @param string $selected Id remise fixe pre-selectionnee + * @param string $htmlname Nom champ formulaire + * @param string $filter Criteres optionnels de filtre + * @param int $socid Id of thirdparty + * @param int $maxvalue Max value for lines that can be selected + * @return int Return number of qualifed lines in list + */ + function select_remises($selected, $htmlname, $filter, $socid, $maxvalue=0) + { + global $langs,$conf; + + // On recherche les remises + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql.= " re.description, re.fk_facture_source"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; + $sql.= " WHERE re.fk_soc = ".(int) $socid; + $sql.= " AND re.entity = " . $conf->entity; + if ($filter) $sql.= " AND ".$filter; + $sql.= " ORDER BY re.description ASC"; + + dol_syslog(get_class($this)."::select_remises", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + print '<select class="flat maxwidthonsmartphone" name="'.$htmlname.'">'; + $num = $this->db->num_rows($resql); - if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid)) - { - $out.= '<option value="'.$obj->rowid.'"'; - if ($disableline) $out.= ' disabled'; - $out.= ' selected>'; - } - else - { - $out.= '<option value="'.$obj->rowid.'"'; - if ($disableline) $out.= ' disabled'; - $out.= '>'; - } + $qualifiedlines=$num; - $fullNameMode = 0; //Lastname + firstname - if(empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)){ - $fullNameMode = 1; //firstname + lastname - } - $out.= $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength); + $i = 0; + if ($num) + { + print '<option value="0"> </option>'; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $desc=dol_trunc($obj->description,40); + if (preg_match('/\(CREDIT_NOTE\)/', $desc)) $desc=preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc); + if (preg_match('/\(DEPOSIT\)/', $desc)) $desc=preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc); + if (preg_match('/\(EXCESS RECEIVED\)/', $desc)) $desc=preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc); - // Complete name with more info - $moreinfo=0; - if (! empty($conf->global->MAIN_SHOW_LOGIN)) - { - $out.= ($moreinfo?' - ':' (').$obj->login; - $moreinfo++; - } - if ($showstatus >= 0) - { - if ($obj->statut == 1 && $showstatus == 1) - { - $out.=($moreinfo?' - ':' (').$langs->trans('Enabled'); - $moreinfo++; - } - if ($obj->statut == 0) - { - $out.=($moreinfo?' - ':' (').$langs->trans('Disabled'); - $moreinfo++; - } - } - if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - if ($obj->admin && ! $obj->entity) - { - $out.=($moreinfo?' - ':' (').$langs->trans("AllEntities"); - $moreinfo++; - } - else - { - $out.=($moreinfo?' - ':' (').($obj->label?$obj->label:$langs->trans("EntityNameNotDefined")); - $moreinfo++; - } - } - $out.=($moreinfo?')':''); - if ($disableline && $disableline != '1') + $selectstring=''; + if ($selected > 0 && $selected == $obj->rowid) $selectstring=' selected'; + + $disabled=''; + if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue) { - $out.=' - '.$disableline; // This is text from $enableonlytext parameter + $qualifiedlines--; + $disabled=' disabled'; } - $out.= '</option>'; - - $i++; - } - } - else - { - $out.= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'" disabled>'; - $out.= '<option value="">'.$langs->trans("None").'</option>'; - } - $out.= '</select>'; - } - else - { - dol_print_error($this->db); - } - - return $out; - } - - - /** - * Return select list of users. Selected users are stored into session. - * List of users are provided into $_SESSION['assignedtouser']. - * - * @param string $action Value for $action - * @param string $htmlname Field name in form - * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array $include Array list of users id to include or 'hierarchy' to have only supervised users - * @param array $enableonly Array list of users id to be enabled. All other must be disabled - * @param int $force_entity 0 or Id of environment to force - * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status - * @param string $morefilter Add more filters into sql request - * @return string HTML select string - * @see select_dolgroups - */ - function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='') - { - global $conf,$user,$langs; - - $userstatic=new User($this->db); - $out=''; - // Method with no ajax - //$out.='<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; - if ($action == 'view') - { - $out.=''; - } + print '<option value="'.$obj->rowid.'"'.$selectstring.$disabled.'>'.$desc.' ('.price($obj->amount_ht).' '.$langs->trans("HT").' - '.price($obj->amount_ttc).' '.$langs->trans("TTC").')</option>'; + $i++; + } + } + print '</select>'; + return $qualifiedlines; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Return list of all contacts (for a third party or all) + * + * @param int $socid Id ot third party or 0 for all + * @param string $selected Id contact pre-selectionne + * @param string $htmlname Name of HTML field ('none' for a not editable field) + * @param int $showempty 0=no empty value, 1=add an empty value + * @param string $exclude List of contacts id to exclude + * @param string $limitto Disable answers that are not id in this array list + * @param integer $showfunction Add function into label + * @param string $moreclass Add more class to class style + * @param integer $showsoc Add company into label + * @param int $forcecombo Force to use combo box + * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param bool $options_only Return options only (for ajax treatment) + * @return int <0 if KO, Nb of contact in list if OK + * @deprected You can use selectcontacts directly (warning order of param was changed) + */ + function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false) + { + print $this->selectcontacts($socid,$selected,$htmlname,$showempty,$exclude,$limitto,$showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events); + return $this->num; + } + + /** + * Return HTML code of the SELECT of list of all contacts (for a third party or all). + * This also set the number of contacts found into $this->num + * + * @param int $socid Id ot third party or 0 for all + * @param string $selected Id contact pre-selectionne + * @param string $htmlname Name of HTML field ('none' for a not editable field) + * @param int $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit) + * @param string $exclude List of contacts id to exclude + * @param string $limitto Disable answers that are not id in this array list + * @param integer $showfunction Add function into label + * @param string $moreclass Add more class to class style + * @param bool $options_only Return options only (for ajax treatment) + * @param integer $showsoc Add company into label + * @param int $forcecombo Force to use combo box + * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @return int <0 if KO, Nb of contact in list if OK + */ + function selectcontacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array()) + { + global $conf,$langs; + + $langs->load('companies'); + + $out=''; + + // On recherche les societes + $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste"; + if ($showsoc > 0) $sql.= " , s.nom as company"; + $sql.= " FROM ".MAIN_DB_PREFIX ."socpeople as sp"; + if ($showsoc > 0) $sql.= " LEFT OUTER JOIN ".MAIN_DB_PREFIX ."societe as s ON s.rowid=sp.fk_soc"; + $sql.= " WHERE sp.entity IN (".getEntity('societe').")"; + if ($socid > 0) $sql.= " AND sp.fk_soc=".$socid; + if (! empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND sp.statut <> 0"; + $sql.= " ORDER BY sp.lastname ASC"; + + dol_syslog(get_class($this)."::select_contacts", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $num=$this->db->num_rows($resql); + + if ($conf->use_javascript_ajax && ! $forcecombo && ! $options_only) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $comboenhancement = ajax_combobox($htmlname, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT); + $out.= $comboenhancement; + } + + if ($htmlname != 'none' || $options_only) $out.= '<select class="flat'.($moreclass?' '.$moreclass:'').'" id="'.$htmlname.'" name="'.$htmlname.'">'; + if ($showempty == 1) $out.= '<option value="0"'.($selected=='0'?' selected':'').'></option>'; + if ($showempty == 2) $out.= '<option value="0"'.($selected=='0'?' selected':'').'>'.$langs->trans("Internal").'</option>'; + $num = $this->db->num_rows($resql); + $i = 0; + if ($num) + { + include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + $contactstatic=new Contact($this->db); + + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + $contactstatic->id=$obj->rowid; + $contactstatic->lastname=$obj->lastname; + $contactstatic->firstname=$obj->firstname; + if ($obj->statut == 1){ + if ($htmlname != 'none') + { + $disabled=0; + if (is_array($exclude) && count($exclude) && in_array($obj->rowid,$exclude)) $disabled=1; + if (is_array($limitto) && count($limitto) && ! in_array($obj->rowid,$limitto)) $disabled=1; + if ($selected && $selected == $obj->rowid) + { + $out.= '<option value="'.$obj->rowid.'"'; + if ($disabled) $out.= ' disabled'; + $out.= ' selected>'; + $out.= $contactstatic->getFullName($langs); + if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')'; + if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')'; + $out.= '</option>'; + } + else + { + $out.= '<option value="'.$obj->rowid.'"'; + if ($disabled) $out.= ' disabled'; + $out.= '>'; + $out.= $contactstatic->getFullName($langs); + if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')'; + if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')'; + $out.= '</option>'; + } + } + else + { + if ($selected == $obj->rowid) + { + $out.= $contactstatic->getFullName($langs); + if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')'; + if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')'; + } + } + } + $i++; + } + } + else + { + $out.= '<option value="-1"'.($showempty==2?'':' selected').' disabled>'.$langs->trans($socid?"NoContactDefinedForThirdParty":"NoContactDefined").'</option>'; + } + if ($htmlname != 'none' || $options_only) + { + $out.= '</select>'; + } + + $this->num = $num; + return $out; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Return select list of users + * + * @param string $selected Id user preselected + * @param string $htmlname Field name in form + * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue + * @param array $exclude Array list of users id to exclude + * @param int $disabled If select list must be disabled + * @param array $include Array list of users id to include + * @param int $enableonly Array list of users id to be enabled. All other must be disabled + * @param int $force_entity 0 or Id of environment to force + * @return void + * @deprecated Use select_dolusers instead + * @see select_dolusers() + */ + function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude=null,$disabled=0,$include='',$enableonly='',$force_entity=0) + { + print $this->select_dolusers($selected,$htmlname,$show_empty,$exclude,$disabled,$include,$enableonly,$force_entity); + } + + /** + * Return select list of users + * + * @param string $selected User id or user object of user preselected. If -1, we use id of current user. + * @param string $htmlname Field name in form + * @param int $show_empty 0=list with no empty value, 1=add also an empty value into list + * @param array $exclude Array list of users id to exclude + * @param int $disabled If select list must be disabled + * @param array|string $include Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me + * @param array $enableonly Array list of users id to be enabled. If defined, it means that other must be disabled + * @param int $force_entity 0 or Id of environment to force + * @param int $maxlength Maximum length of string into list (0=no limit) + * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param string $morefilter Add more filters into sql request + * @param integer $show_every 0=default list, 1=add also a value "Everybody" at beginning of list + * @param string $enableonlytext If option $enableonlytext is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty. + * @param string $morecss More css + * @param int $noactive Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on). + * @return string HTML select string + * @see select_dolgroups + */ + function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0) + { + global $conf,$user,$langs; + + // If no preselected user defined, we take current user + if ((is_numeric($selected) && ($selected < -2 || empty($selected))) && empty($conf->global->SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE)) $selected=$user->id; + + $excludeUsers=null; + $includeUsers=null; + + // Permettre l'exclusion d'utilisateurs + if (is_array($exclude)) $excludeUsers = implode(",",$exclude); + // Permettre l'inclusion d'utilisateurs + if (is_array($include)) $includeUsers = implode(",",$include); + else if ($include == 'hierarchy') + { + // Build list includeUsers to have only hierarchy + $includeUsers = implode(",",$user->getAllChildIds(0)); + } + else if ($include == 'hierarchyme') + { + // Build list includeUsers to have only hierarchy and current user + $includeUsers = implode(",",$user->getAllChildIds(1)); + } + + $out=''; + + // On recherche les utilisateurs + $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity"; + if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + $sql.= ", e.label"; + } + $sql.= " FROM ".MAIN_DB_PREFIX ."user as u"; + if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX ."entity as e ON e.rowid=u.entity"; + if ($force_entity) $sql.= " WHERE u.entity IN (0,".$force_entity.")"; + else $sql.= " WHERE u.entity IS NOT NULL"; + } + else + { + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql.= " ON ug.fk_user = u.rowid"; + $sql.= " WHERE ug.entity = ".$conf->entity; + } + else + { + $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; + } + } + if (! empty($user->societe_id)) $sql.= " AND u.fk_soc = ".$user->societe_id; + if (is_array($exclude) && $excludeUsers) $sql.= " AND u.rowid NOT IN (".$excludeUsers.")"; + if ($includeUsers) $sql.= " AND u.rowid IN (".$includeUsers.")"; + if (! empty($conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive) $sql.= " AND u.statut <> 0"; + if (! empty($morefilter)) $sql.=" ".$morefilter; + + if(empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)){ + $sql.= " ORDER BY u.firstname ASC"; + }else{ + $sql.= " ORDER BY u.lastname ASC"; + } + + + dol_syslog(get_class($this)."::select_dolusers", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + if ($num) + { + // Enhance with select2 + if ($conf->use_javascript_ajax) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $comboenhancement = ajax_combobox($htmlname); + $out.=$comboenhancement; + } + + // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined + $out.= '<select class="flat'.($morecss?' minwidth100 '.$morecss:' minwidth200').'" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>'; + if ($show_empty) $out.= '<option value="-1"'.((empty($selected) || $selected==-1)?' selected':'').'> </option>'."\n"; + if ($show_every) $out.= '<option value="-2"'.(($selected==-2)?' selected':'').'>-- '.$langs->trans("Everybody").' --</option>'."\n"; + + $userstatic=new User($this->db); + + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + $userstatic->id=$obj->rowid; + $userstatic->lastname=$obj->lastname; + $userstatic->firstname=$obj->firstname; + + $disableline=''; + if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=($enableonlytext?$enableonlytext:'1'); + + if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid)) + { + $out.= '<option value="'.$obj->rowid.'"'; + if ($disableline) $out.= ' disabled'; + $out.= ' selected>'; + } + else + { + $out.= '<option value="'.$obj->rowid.'"'; + if ($disableline) $out.= ' disabled'; + $out.= '>'; + } + + $fullNameMode = 0; //Lastname + firstname + if(empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)){ + $fullNameMode = 1; //firstname + lastname + } + $out.= $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength); + + // Complete name with more info + $moreinfo=0; + if (! empty($conf->global->MAIN_SHOW_LOGIN)) + { + $out.= ($moreinfo?' - ':' (').$obj->login; + $moreinfo++; + } + if ($showstatus >= 0) + { + if ($obj->statut == 1 && $showstatus == 1) + { + $out.=($moreinfo?' - ':' (').$langs->trans('Enabled'); + $moreinfo++; + } + if ($obj->statut == 0) + { + $out.=($moreinfo?' - ':' (').$langs->trans('Disabled'); + $moreinfo++; + } + } + if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + if ($obj->admin && ! $obj->entity) + { + $out.=($moreinfo?' - ':' (').$langs->trans("AllEntities"); + $moreinfo++; + } + else + { + $out.=($moreinfo?' - ':' (').($obj->label?$obj->label:$langs->trans("EntityNameNotDefined")); + $moreinfo++; + } + } + $out.=($moreinfo?')':''); + if ($disableline && $disableline != '1') + { + $out.=' - '.$disableline; // This is text from $enableonlytext parameter + } + $out.= '</option>'; + + $i++; + } + } + else + { + $out.= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'" disabled>'; + $out.= '<option value="">'.$langs->trans("None").'</option>'; + } + $out.= '</select>'; + } + else + { + dol_print_error($this->db); + } + + return $out; + } + + + /** + * Return select list of users. Selected users are stored into session. + * List of users are provided into $_SESSION['assignedtouser']. + * + * @param string $action Value for $action + * @param string $htmlname Field name in form + * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue + * @param array $exclude Array list of users id to exclude + * @param int $disabled If select list must be disabled + * @param array $include Array list of users id to include or 'hierarchy' to have only supervised users + * @param array $enableonly Array list of users id to be enabled. All other must be disabled + * @param int $force_entity 0 or Id of environment to force + * @param int $maxlength Maximum length of string into list (0=no limit) + * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param string $morefilter Add more filters into sql request + * @return string HTML select string + * @see select_dolgroups + */ + function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='') + { + global $conf,$user,$langs; + + $userstatic=new User($this->db); + $out=''; + + // Method with no ajax + //$out.='<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; + if ($action == 'view') + { + $out.=''; + } else { $out.='<input type="hidden" class="removedassignedhidden" name="removedassigned" value="">'; @@ -1671,60 +1671,60 @@ class Form if ($nbassignetouser) $out.='</div>'; //$out.='</form>'; - return $out; - } - - - /** - * Return list of products for customer in Ajax if Ajax activated or go to select_produits_list - * - * @param int $selected Preselected products - * @param string $htmlname Name of HTML select field (must be unique in page) - * @param int $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param int $limit Limit on number of returned lines - * @param int $price_level Level of price to show - * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell - * @param int $finished 2=all, 1=finished, 0=raw material - * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) - * @param array $ajaxoptions Options for ajax_autocompleter - * @param int $socid Thirdparty Id (to get also price dedicated to this customer) - * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. - * @param int $forcecombo Force to use combo box - * @param string $morecss Add more css on select - * @param int $hidepriceinlabel 1=Hide prices in label - * @param string $warehouseStatus warehouse status filter, following comma separated filter options can be used - * 'warehouseopen' = select products from open warehouses, + return $out; + } + + + /** + * Return list of products for customer in Ajax if Ajax activated or go to select_produits_list + * + * @param int $selected Preselected products + * @param string $htmlname Name of HTML select field (must be unique in page) + * @param int $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param int $limit Limit on number of returned lines + * @param int $price_level Level of price to show + * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell + * @param int $finished 2=all, 1=finished, 0=raw material + * @param string $selected_input_value Value of preselected input text (for use with ajax) + * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) + * @param array $ajaxoptions Options for ajax_autocompleter + * @param int $socid Thirdparty Id (to get also price dedicated to this customer) + * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param int $forcecombo Force to use combo box + * @param string $morecss Add more css on select + * @param int $hidepriceinlabel 1=Hide prices in label + * @param string $warehouseStatus warehouse status filter, following comma separated filter options can be used + * 'warehouseopen' = select products from open warehouses, * 'warehouseclosed' = select products from closed warehouses, * 'warehouseinternal' = select products from warehouses for internal correct/transfer only - * @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) - * @return void - */ - function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array(), $socid=0, $showempty='1', $forcecombo=0, $morecss='', $hidepriceinlabel=0, $warehouseStatus='', $selected_combinations = array()) - { - global $langs,$conf; + * @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) + * @return void + */ + function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array(), $socid=0, $showempty='1', $forcecombo=0, $morecss='', $hidepriceinlabel=0, $warehouseStatus='', $selected_combinations = array()) + { + global $langs,$conf; - $price_level = (! empty($price_level) ? $price_level : 0); + $price_level = (! empty($price_level) ? $price_level : 0); - if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) - { - $placeholder=''; + if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) + { + $placeholder=''; - if ($selected && empty($selected_input_value)) - { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - $producttmpselect = new Product($this->db); - $producttmpselect->fetch($selected); - $selected_input_value=$producttmpselect->ref; - unset($producttmpselect); - } - // mode=1 means customers products - $urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished.'&hidepriceinlabel='.$hidepriceinlabel.'&warehousestatus='.$warehouseStatus; - //Price by customer - if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { - $urloption.='&socid='.$socid; - } - print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + if ($selected && empty($selected_input_value)) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $producttmpselect = new Product($this->db); + $producttmpselect->fetch($selected); + $selected_input_value=$producttmpselect->ref; + unset($producttmpselect); + } + // mode=1 means customers products + $urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished.'&hidepriceinlabel='.$hidepriceinlabel.'&warehousestatus='.$warehouseStatus; + //Price by customer + if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { + $urloption.='&socid='.$socid; + } + print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); if (!empty($conf->variants->enabled)) { ?> @@ -1798,92 +1798,92 @@ class Form }); </script> <?php - } - if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : '; - else if ($hidelabel > 1) { - if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"'; - else $placeholder=' title="'.$langs->trans("RefOrLabel").'"'; - if ($hidelabel == 2) { - print img_picto($langs->trans("Search"), 'search'); - } - } - print '<input type="text" class="minwidth100" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; - if ($hidelabel == 3) { - print img_picto($langs->trans("Search"), 'search'); - } - } - else - { - print $this->select_produits_list($selected,$htmlname,$filtertype,$limit,$price_level,'',$status,$finished,0,$socid,$showempty,$forcecombo,$morecss,$hidepriceinlabel, $warehouseStatus); - } - } - - /** - * Return list of products for a customer - * - * @param int $selected Preselected product - * @param string $htmlname Name of select html - * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param int $limit Limit on number of returned lines - * @param int $price_level Level of price to show - * @param string $filterkey Filter on product - * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell - * @param int $finished Filter on finished field: 2=No filter - * @param int $outputmode 0=HTML select string, 1=Array - * @param int $socid Thirdparty Id (to get also price dedicated to this customer) - * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. - * @param int $forcecombo Force to use combo box - * @param string $morecss Add more css on select - * @param int $hidepriceinlabel 1=Hide prices in label - * @param string $warehouseStatus warehouse status filter, following comma separated filter options can be used - * 'warehouseopen' = select products from open warehouses, + } + if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : '; + else if ($hidelabel > 1) { + if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"'; + else $placeholder=' title="'.$langs->trans("RefOrLabel").'"'; + if ($hidelabel == 2) { + print img_picto($langs->trans("Search"), 'search'); + } + } + print '<input type="text" class="minwidth100" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; + if ($hidelabel == 3) { + print img_picto($langs->trans("Search"), 'search'); + } + } + else + { + print $this->select_produits_list($selected,$htmlname,$filtertype,$limit,$price_level,'',$status,$finished,0,$socid,$showempty,$forcecombo,$morecss,$hidepriceinlabel, $warehouseStatus); + } + } + + /** + * Return list of products for a customer + * + * @param int $selected Preselected product + * @param string $htmlname Name of select html + * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param int $limit Limit on number of returned lines + * @param int $price_level Level of price to show + * @param string $filterkey Filter on product + * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell + * @param int $finished Filter on finished field: 2=No filter + * @param int $outputmode 0=HTML select string, 1=Array + * @param int $socid Thirdparty Id (to get also price dedicated to this customer) + * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param int $forcecombo Force to use combo box + * @param string $morecss Add more css on select + * @param int $hidepriceinlabel 1=Hide prices in label + * @param string $warehouseStatus warehouse status filter, following comma separated filter options can be used + * 'warehouseopen' = select products from open warehouses, * 'warehouseclosed' = select products from closed warehouses, * 'warehouseinternal' = select products from warehouses for internal correct/transfer only - * @return array Array of keys for json - */ - function select_produits_list($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$filterkey='',$status=1,$finished=2,$outputmode=0,$socid=0,$showempty='1',$forcecombo=0,$morecss='',$hidepriceinlabel=0, $warehouseStatus='') - { - global $langs,$conf,$user,$db; - - $out=''; - $outarray=array(); - - $warehouseStatusArray = array(); - if (! empty($warehouseStatus)) - { - require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; - if (preg_match('/warehouseclosed/', $warehouseStatus)) - { - $warehouseStatusArray[] = Entrepot::STATUS_CLOSED; - } - if (preg_match('/warehouseopen/', $warehouseStatus)) - { - $warehouseStatusArray[] = Entrepot::STATUS_OPEN_ALL; - } - if (preg_match('/warehouseinternal/', $warehouseStatus)) - { - $warehouseStatusArray[] = Entrepot::STATUS_OPEN_INTERNAL; - } - } - - $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression"; - (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock"; - - $sql = "SELECT "; - $sql.= $selectFields . $selectFieldsGrouped; - //Price by customer - if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { - $sql.=' ,pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,'; - $sql.=' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx'; - $selectFields.= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx"; - } - - // Multilang : we add translation - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $sql.= ", pl.label as label_translated"; - $selectFields.= ", label_translated"; - } + * @return array Array of keys for json + */ + function select_produits_list($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$filterkey='',$status=1,$finished=2,$outputmode=0,$socid=0,$showempty='1',$forcecombo=0,$morecss='',$hidepriceinlabel=0, $warehouseStatus='') + { + global $langs,$conf,$user,$db; + + $out=''; + $outarray=array(); + + $warehouseStatusArray = array(); + if (! empty($warehouseStatus)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; + if (preg_match('/warehouseclosed/', $warehouseStatus)) + { + $warehouseStatusArray[] = Entrepot::STATUS_CLOSED; + } + if (preg_match('/warehouseopen/', $warehouseStatus)) + { + $warehouseStatusArray[] = Entrepot::STATUS_OPEN_ALL; + } + if (preg_match('/warehouseinternal/', $warehouseStatus)) + { + $warehouseStatusArray[] = Entrepot::STATUS_OPEN_INTERNAL; + } + } + + $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression"; + (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock"; + + $sql = "SELECT "; + $sql.= $selectFields . $selectFieldsGrouped; + //Price by customer + if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { + $sql.=' ,pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,'; + $sql.=' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx'; + $selectFields.= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx"; + } + + // Multilang : we add translation + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $sql.= ", pl.label as label_translated"; + $selectFields.= ", label_translated"; + } // Price by quantity if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { @@ -1895,130 +1895,130 @@ class Form if ($price_level >= 1 && !empty($conf->global->PRODUIT_MULTIPRICES)) $sql.= " AND price_level=".$price_level; $sql.= " ORDER BY date_price"; $sql.= " DESC LIMIT 1) as price_by_qty"; - $selectFields.= ", price_rowid, price_by_qty"; - } - $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; - if (count($warehouseStatusArray)) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_product = p.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e on ps.fk_entrepot = e.rowid"; - } - - //Price by customer - if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { - $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."product_customer_price as pcp ON pcp.fk_soc=".$socid." AND pcp.fk_product=p.rowid"; - } - // Multilang : we add translation - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='". $langs->getDefaultLang() ."'"; - } - - if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { - $sql .= " LEFT JOIN llx_product_attribute_combination pac ON pac.fk_product_child = p.rowid"; - } - - $sql.= ' WHERE p.entity IN ('.getEntity('product').')'; - if (count($warehouseStatusArray)) - { - $sql.= ' AND (p.fk_product_type = 1 OR e.statut IN ('.$this->db->escape(implode(',',$warehouseStatusArray)).'))'; - } - - if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { - $sql .= " AND pac.rowid IS NULL"; - } - - if ($finished == 0) - { - $sql.= " AND p.finished = ".$finished; - } - elseif ($finished == 1) - { - $sql.= " AND p.finished = ".$finished; - if ($status >= 0) $sql.= " AND p.tosell = ".$status; - } - elseif ($status >= 0) - { - $sql.= " AND p.tosell = ".$status; - } - if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$filtertype; - // Add criteria on ref/label - if ($filterkey != '') - { - $sql.=' AND ('; - $prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on - // For natural search - $scrit = explode(' ', $filterkey); - $i=0; - if (count($scrit) > 1) $sql.="("; - foreach ($scrit as $crit) - { - if ($i > 0) $sql.=" AND "; - $sql.="(p.ref LIKE '".$db->escape($prefix.$crit)."%' OR p.label LIKE '".$db->escape($prefix.$crit)."%'"; - if (! empty($conf->global->MAIN_MULTILANGS)) $sql.=" OR pl.label LIKE '".$db->escape($prefix.$crit)."%'"; - $sql.=")"; - $i++; - } - if (count($scrit) > 1) $sql.=")"; - if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$db->escape($prefix.$filterkey)."%'"; - $sql.=')'; - } - if (count($warehouseStatusArray)) - { - $sql.= ' GROUP BY'.$selectFields; - } - $sql.= $db->order("p.ref"); - $sql.= $db->plimit($limit, 0); - - // Build output string - dol_syslog(get_class($this)."::select_produits_list search product", LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; - $num = $this->db->num_rows($result); - - $events=null; - - if ($conf->use_javascript_ajax && ! $forcecombo) - { - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); - $out.= $comboenhancement; - } + $selectFields.= ", price_rowid, price_by_qty"; + } + $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; + if (count($warehouseStatusArray)) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_product = p.rowid"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e on ps.fk_entrepot = e.rowid"; + } - $out.='<select class="flat'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" id="'.$htmlname.'">'; + //Price by customer + if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { + $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."product_customer_price as pcp ON pcp.fk_soc=".$socid." AND pcp.fk_product=p.rowid"; + } + // Multilang : we add translation + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='". $langs->getDefaultLang() ."'"; + } - $textifempty=''; - // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. - //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty=''; - if (! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) - { - if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty); - else $textifempty.=$langs->trans("All"); - } - if ($showempty) $out.='<option value="0" selected>'.$textifempty.'</option>'; + if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $sql .= " LEFT JOIN llx_product_attribute_combination pac ON pac.fk_product_child = p.rowid"; + } - $i = 0; - while ($num && $i < $num) - { - $opt = ''; - $optJson = array(); - $objp = $this->db->fetch_object($result); + $sql.= ' WHERE p.entity IN ('.getEntity('product').')'; + if (count($warehouseStatusArray)) + { + $sql.= ' AND (p.fk_product_type = 1 OR e.statut IN ('.$this->db->escape(implode(',',$warehouseStatusArray)).'))'; + } - if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1) - { // Price by quantity will return many prices for the same product - $sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise"; - $sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty"; - $sql.= " WHERE fk_product_price=".$objp->price_rowid; - $sql.= " ORDER BY quantity ASC"; + if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $sql .= " AND pac.rowid IS NULL"; + } - dol_syslog(get_class($this)."::select_produits_list search price by qty", LOG_DEBUG); - $result2 = $this->db->query($sql); - if ($result2) - { - $nb_prices = $this->db->num_rows($result2); + if ($finished == 0) + { + $sql.= " AND p.finished = ".$finished; + } + elseif ($finished == 1) + { + $sql.= " AND p.finished = ".$finished; + if ($status >= 0) $sql.= " AND p.tosell = ".$status; + } + elseif ($status >= 0) + { + $sql.= " AND p.tosell = ".$status; + } + if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$filtertype; + // Add criteria on ref/label + if ($filterkey != '') + { + $sql.=' AND ('; + $prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on + // For natural search + $scrit = explode(' ', $filterkey); + $i=0; + if (count($scrit) > 1) $sql.="("; + foreach ($scrit as $crit) + { + if ($i > 0) $sql.=" AND "; + $sql.="(p.ref LIKE '".$db->escape($prefix.$crit)."%' OR p.label LIKE '".$db->escape($prefix.$crit)."%'"; + if (! empty($conf->global->MAIN_MULTILANGS)) $sql.=" OR pl.label LIKE '".$db->escape($prefix.$crit)."%'"; + $sql.=")"; + $i++; + } + if (count($scrit) > 1) $sql.=")"; + if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$db->escape($prefix.$filterkey)."%'"; + $sql.=')'; + } + if (count($warehouseStatusArray)) + { + $sql.= ' GROUP BY'.$selectFields; + } + $sql.= $db->order("p.ref"); + $sql.= $db->plimit($limit, 0); + + // Build output string + dol_syslog(get_class($this)."::select_produits_list search product", LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; + $num = $this->db->num_rows($result); + + $events=null; + + if ($conf->use_javascript_ajax && ! $forcecombo) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); + $out.= $comboenhancement; + } + + $out.='<select class="flat'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" id="'.$htmlname.'">'; + + $textifempty=''; + // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. + //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty=''; + if (! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) + { + if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty); + else $textifempty.=$langs->trans("All"); + } + if ($showempty) $out.='<option value="0" selected>'.$textifempty.'</option>'; + + $i = 0; + while ($num && $i < $num) + { + $opt = ''; + $optJson = array(); + $objp = $this->db->fetch_object($result); + + if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1) + { // Price by quantity will return many prices for the same product + $sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise"; + $sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty"; + $sql.= " WHERE fk_product_price=".$objp->price_rowid; + $sql.= " ORDER BY quantity ASC"; + + dol_syslog(get_class($this)."::select_produits_list search price by qty", LOG_DEBUG); + $result2 = $this->db->query($sql); + if ($result2) + { + $nb_prices = $this->db->num_rows($result2); $j = 0; while ($nb_prices && $j < $nb_prices) { $objp2 = $this->db->fetch_object($result2); @@ -2044,19 +2044,19 @@ class Form } else { - if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_price_expression)) { - $price_product = new Product($this->db); - $price_product->fetch($objp->rowid, '', '', 1); - $priceparser = new PriceParser($this->db); - $price_result = $priceparser->parseProduct($price_product); - if ($price_result >= 0) { - $objp->price = $price_result; - $objp->unitprice = $price_result; - //Calculate the VAT - $objp->price_ttc = price2num($objp->price) * (1 + ($objp->tva_tx / 100)); - $objp->price_ttc = price2num($objp->price_ttc,'MU'); - } - } + if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_price_expression)) { + $price_product = new Product($this->db); + $price_product->fetch($objp->rowid, '', '', 1); + $priceparser = new PriceParser($this->db); + $price_result = $priceparser->parseProduct($price_product); + if ($price_result >= 0) { + $objp->price = $price_result; + $objp->unitprice = $price_result; + //Calculate the VAT + $objp->price_ttc = price2num($objp->price) * (1 + ($objp->tva_tx / 100)); + $objp->price_ttc = price2num($objp->price_ttc,'MU'); + } + } $this->constructProductListOption($objp, $opt, $optJson, $price_level, $selected, $hidepriceinlabel); // Add new entry // "key" value of json key array is used by jQuery automatically as selected value @@ -2065,128 +2065,128 @@ class Form array_push($outarray, $optJson); } - $i++; - } + $i++; + } + + $out.='</select>'; - $out.='</select>'; - - $this->db->free($result); - - if (empty($outputmode)) return $out; - return $outarray; - } - else - { - dol_print_error($db); - } - } - - /** - * constructProductListOption - * - * @param resultset $objp Resultset of fetch - * @param string $opt Option (var used for returned value in string option format) - * @param string $optJson Option (var used for returned value in json format) - * @param int $price_level Price level - * @param string $selected Preselected value - * @param int $hidepriceinlabel Hide price in label - * @return void - */ + $this->db->free($result); + + if (empty($outputmode)) return $out; + return $outarray; + } + else + { + dol_print_error($db); + } + } + + /** + * constructProductListOption + * + * @param resultset $objp Resultset of fetch + * @param string $opt Option (var used for returned value in string option format) + * @param string $optJson Option (var used for returned value in json format) + * @param int $price_level Price level + * @param string $selected Preselected value + * @param int $hidepriceinlabel Hide price in label + * @return void + */ private function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel=0) { global $langs,$conf,$user,$db; - $outkey=''; - $outval=''; - $outref=''; - $outlabel=''; - $outdesc=''; - $outbarcode=''; - $outtype=''; - $outprice_ht=''; - $outprice_ttc=''; - $outpricebasetype=''; - $outtva_tx=''; + $outkey=''; + $outval=''; + $outref=''; + $outlabel=''; + $outdesc=''; + $outbarcode=''; + $outtype=''; + $outprice_ht=''; + $outprice_ttc=''; + $outpricebasetype=''; + $outtva_tx=''; $outqty=1; $outdiscount=0; $maxlengtharticle=(empty($conf->global->PRODUCT_MAX_LENGTH_COMBO)?48:$conf->global->PRODUCT_MAX_LENGTH_COMBO); - $label=$objp->label; - if (! empty($objp->label_translated)) $label=$objp->label_translated; - if (! empty($filterkey) && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1); + $label=$objp->label; + if (! empty($objp->label_translated)) $label=$objp->label_translated; + if (! empty($filterkey) && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1); - $outkey=$objp->rowid; - $outref=$objp->ref; - $outlabel=$objp->label; - $outdesc=$objp->description; - $outbarcode=$objp->barcode; + $outkey=$objp->rowid; + $outref=$objp->ref; + $outlabel=$objp->label; + $outdesc=$objp->description; + $outbarcode=$objp->barcode; - $outtype=$objp->fk_product_type; - $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):''; - $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):''; + $outtype=$objp->fk_product_type; + $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):''; + $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):''; - $opt = '<option value="'.$objp->rowid.'"'; - $opt.= ($objp->rowid == $selected)?' selected':''; + $opt = '<option value="'.$objp->rowid.'"'; + $opt.= ($objp->rowid == $selected)?' selected':''; $opt.= (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0)?' pbq="'.$objp->price_by_qty_rowid.'"':''; - if (! empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock)) - { + if (! empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock)) + { if ($objp->stock > 0) $opt.= ' class="product_line_stock_ok"'; else if ($objp->stock <= 0) $opt.= ' class="product_line_stock_too_low"'; - } - $opt.= '>'; - $opt.= $objp->ref; - if ($outbarcode) $opt.=' ('.$outbarcode.')'; - $opt.=' - '.dol_trunc($label,$maxlengtharticle); - - $objRef = $objp->ref; - if (! empty($filterkey) && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1); - $outval.=$objRef; - if ($outbarcode) $outval.=' ('.$outbarcode.')'; - $outval.=' - '.dol_trunc($label,$maxlengtharticle); - - $found=0; - - // Multiprice - if (empty($hidepriceinlabel) && $price_level >= 1 && $conf->global->PRODUIT_MULTIPRICES) // If we need a particular price level (from 1 to 6) - { - $sql = "SELECT price, price_ttc, price_base_type, tva_tx"; - $sql.= " FROM ".MAIN_DB_PREFIX."product_price"; - $sql.= " WHERE fk_product='".$objp->rowid."'"; - $sql.= " AND entity IN (".getEntity('productprice').")"; - $sql.= " AND price_level=".$price_level; - $sql.= " ORDER BY date_price DESC, rowid DESC"; // Warning DESC must be both on date_price and rowid. - $sql.= " LIMIT 1"; - - dol_syslog(get_class($this).'::constructProductListOption search price for level '.$price_level.'', LOG_DEBUG); - $result2 = $this->db->query($sql); - if ($result2) - { - $objp2 = $this->db->fetch_object($result2); - if ($objp2) - { - $found=1; - if ($objp2->price_base_type == 'HT') - { - $opt.= ' - '.price($objp2->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT"); - $outval.= ' - '.price($objp2->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT"); - } - else - { - $opt.= ' - '.price($objp2->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC"); - $outval.= ' - '.price($objp2->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC"); - } - $outprice_ht=price($objp2->price); - $outprice_ttc=price($objp2->price_ttc); - $outpricebasetype=$objp2->price_base_type; - $outtva_tx=$objp2->tva_tx; - } - } - else - { - dol_print_error($this->db); - } - } + } + $opt.= '>'; + $opt.= $objp->ref; + if ($outbarcode) $opt.=' ('.$outbarcode.')'; + $opt.=' - '.dol_trunc($label,$maxlengtharticle); + + $objRef = $objp->ref; + if (! empty($filterkey) && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1); + $outval.=$objRef; + if ($outbarcode) $outval.=' ('.$outbarcode.')'; + $outval.=' - '.dol_trunc($label,$maxlengtharticle); + + $found=0; + + // Multiprice + if (empty($hidepriceinlabel) && $price_level >= 1 && $conf->global->PRODUIT_MULTIPRICES) // If we need a particular price level (from 1 to 6) + { + $sql = "SELECT price, price_ttc, price_base_type, tva_tx"; + $sql.= " FROM ".MAIN_DB_PREFIX."product_price"; + $sql.= " WHERE fk_product='".$objp->rowid."'"; + $sql.= " AND entity IN (".getEntity('productprice').")"; + $sql.= " AND price_level=".$price_level; + $sql.= " ORDER BY date_price DESC, rowid DESC"; // Warning DESC must be both on date_price and rowid. + $sql.= " LIMIT 1"; + + dol_syslog(get_class($this).'::constructProductListOption search price for level '.$price_level.'', LOG_DEBUG); + $result2 = $this->db->query($sql); + if ($result2) + { + $objp2 = $this->db->fetch_object($result2); + if ($objp2) + { + $found=1; + if ($objp2->price_base_type == 'HT') + { + $opt.= ' - '.price($objp2->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT"); + $outval.= ' - '.price($objp2->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT"); + } + else + { + $opt.= ' - '.price($objp2->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC"); + $outval.= ' - '.price($objp2->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC"); + } + $outprice_ht=price($objp2->price); + $outprice_ttc=price($objp2->price_ttc); + $outpricebasetype=$objp2->price_base_type; + $outtva_tx=$objp2->tva_tx; + } + } + else + { + dol_print_error($this->db); + } + } // Price by quantity if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1 && ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) @@ -2210,9 +2210,9 @@ class Form } $outprice_ht=price($objp->unitprice); - $outprice_ttc=price($objp->unitprice * (1 + ($objp->tva_tx / 100))); - $outpricebasetype=$objp->price_base_type; - $outtva_tx=$objp->tva_tx; + $outprice_ttc=price($objp->unitprice * (1 + ($objp->tva_tx / 100))); + $outpricebasetype=$objp->price_base_type; + $outtva_tx=$objp->tva_tx; } if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1) { @@ -2250,2994 +2250,2994 @@ class Form } } - // If level no defined or multiprice not found, we used the default price - if (empty($hidepriceinlabel) && ! $found) - { - if ($objp->price_base_type == 'HT') - { - $opt.= ' - '.price($objp->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT"); - $outval.= ' - '.price($objp->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT"); - } - else - { - $opt.= ' - '.price($objp->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC"); - $outval.= ' - '.price($objp->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC"); - } - $outprice_ht=price($objp->price); - $outprice_ttc=price($objp->price_ttc); - $outpricebasetype=$objp->price_base_type; - $outtva_tx=$objp->tva_tx; - } - - if (! empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0) - { - $opt.= ' - '.$langs->trans("Stock").':'.$objp->stock; - - if ($objp->stock > 0) { - $outval.= ' - <span class="product_line_stock_ok">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>'; - }elseif ($objp->stock <= 0) { - $outval.= ' - <span class="product_line_stock_too_low">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>'; - } - } + // If level no defined or multiprice not found, we used the default price + if (empty($hidepriceinlabel) && ! $found) + { + if ($objp->price_base_type == 'HT') + { + $opt.= ' - '.price($objp->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT"); + $outval.= ' - '.price($objp->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT"); + } + else + { + $opt.= ' - '.price($objp->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC"); + $outval.= ' - '.price($objp->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC"); + } + $outprice_ht=price($objp->price); + $outprice_ttc=price($objp->price_ttc); + $outpricebasetype=$objp->price_base_type; + $outtva_tx=$objp->tva_tx; + } - if ($outdurationvalue && $outdurationunit) - { - $da=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("Day"),"w"=>$langs->trans("Week"),"m"=>$langs->trans("Month"),"y"=>$langs->trans("Year")); - if (isset($da[$outdurationunit])) - { - $key = $da[$outdurationunit].($outdurationvalue > 1?'s':''); - $opt.= ' - '.$outdurationvalue.' '.$langs->trans($key); - $outval.=' - '.$outdurationvalue.' '.$langs->transnoentities($key); - } - } + if (! empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0) + { + $opt.= ' - '.$langs->trans("Stock").':'.$objp->stock; + + if ($objp->stock > 0) { + $outval.= ' - <span class="product_line_stock_ok">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>'; + }elseif ($objp->stock <= 0) { + $outval.= ' - <span class="product_line_stock_too_low">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>'; + } + } + + if ($outdurationvalue && $outdurationunit) + { + $da=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("Day"),"w"=>$langs->trans("Week"),"m"=>$langs->trans("Month"),"y"=>$langs->trans("Year")); + if (isset($da[$outdurationunit])) + { + $key = $da[$outdurationunit].($outdurationvalue > 1?'s':''); + $opt.= ' - '.$outdurationvalue.' '.$langs->trans($key); + $outval.=' - '.$outdurationvalue.' '.$langs->transnoentities($key); + } + } - $opt.= "</option>\n"; + $opt.= "</option>\n"; $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit); } - /** - * Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list) - * - * @param int $socid Id third party - * @param string $selected Preselected product - * @param string $htmlname Name of HTML Select - * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param string $filtre For a SQL filter - * @param array $ajaxoptions Options for ajax_autocompleter + /** + * Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list) + * + * @param int $socid Id third party + * @param string $selected Preselected product + * @param string $htmlname Name of HTML Select + * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param string $filtre For a SQL filter + * @param array $ajaxoptions Options for ajax_autocompleter * @param int $hidelabel Hide label (0=no, 1=yes) * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices - * @return void - */ - function select_produits_fournisseurs($socid, $selected='', $htmlname='productid', $filtertype='', $filtre='', $ajaxoptions=array(), $hidelabel=0, $alsoproductwithnosupplierprice=0) - { - global $langs,$conf; - global $price_level, $status, $finished; - - $selected_input_value=''; - if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) - { - if ($selected > 0) - { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - $producttmpselect = new Product($this->db); - $producttmpselect->fetch($selected); - $selected_input_value=$producttmpselect->ref; - unset($producttmpselect); - } + * @return void + */ + function select_produits_fournisseurs($socid, $selected='', $htmlname='productid', $filtertype='', $filtre='', $ajaxoptions=array(), $hidelabel=0, $alsoproductwithnosupplierprice=0) + { + global $langs,$conf; + global $price_level, $status, $finished; + + $selected_input_value=''; + if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) + { + if ($selected > 0) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $producttmpselect = new Product($this->db); + $producttmpselect->fetch($selected); + $selected_input_value=$producttmpselect->ref; + unset($producttmpselect); + } // mode=2 means suppliers products - $urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished.'&alsoproductwithnosupplierprice='.$alsoproductwithnosupplierprice; - print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); - print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'">'; - } - else - { - print $this->select_produits_fournisseurs_list($socid,$selected,$htmlname,$filtertype,$filtre,'',-1,0,0,$alsoproductwithnosupplierprice); - } - } - - /** - * Return list of suppliers products - * - * @param int $socid Id societe fournisseur (0 pour aucun filtre) - * @param int $selected Produit pre-selectionne - * @param string $htmlname Nom de la zone select - * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param string $filtre Pour filtre sql - * @param string $filterkey Filtre des produits - * @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request) - * @param int $outputmode 0=HTML select string, 1=Array - * @param int $limit Limit of line number + $urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished.'&alsoproductwithnosupplierprice='.$alsoproductwithnosupplierprice; + print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'">'; + } + else + { + print $this->select_produits_fournisseurs_list($socid,$selected,$htmlname,$filtertype,$filtre,'',-1,0,0,$alsoproductwithnosupplierprice); + } + } + + /** + * Return list of suppliers products + * + * @param int $socid Id societe fournisseur (0 pour aucun filtre) + * @param int $selected Produit pre-selectionne + * @param string $htmlname Nom de la zone select + * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param string $filtre Pour filtre sql + * @param string $filterkey Filtre des produits + * @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request) + * @param int $outputmode 0=HTML select string, 1=Array + * @param int $limit Limit of line number * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices - * @return array Array of keys for json - */ - function select_produits_fournisseurs_list($socid,$selected='',$htmlname='productid',$filtertype='',$filtre='',$filterkey='',$statut=-1,$outputmode=0,$limit=100,$alsoproductwithnosupplierprice=0) - { - global $langs,$conf,$db; - - $out=''; - $outarray=array(); - - $langs->load('stocks'); - - $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,"; - $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,"; - $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,"; - $sql.= " pfp.supplier_reputation"; - $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; - if ($socid) $sql.= " AND pfp.fk_soc = ".$socid; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid"; - $sql.= " WHERE p.entity IN (".getEntity('product').")"; - $sql.= " AND p.tobuy = 1"; - if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$this->db->escape($filtertype); - if (! empty($filtre)) $sql.=" ".$filtre; - // Add criteria on ref/label - if ($filterkey != '') - { - $sql.=' AND ('; - $prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on - // For natural search - $scrit = explode(' ', $filterkey); - $i=0; - if (count($scrit) > 1) $sql.="("; - foreach ($scrit as $crit) - { - if ($i > 0) $sql.=" AND "; - $sql.="(pfp.ref_fourn LIKE '".$this->db->escape($prefix.$crit)."%' OR p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%')"; - $i++; - } - if (count($scrit) > 1) $sql.=")"; - if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; - $sql.=')'; - } - $sql.= " ORDER BY pfp.ref_fourn DESC, pfp.quantity ASC"; - $sql.= $db->plimit($limit, 0); - - // Build output string - - dol_syslog(get_class($this)."::select_produits_fournisseurs_list", LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; - - $num = $this->db->num_rows($result); - - //$out.='<select class="flat" id="select'.$htmlname.'" name="'.$htmlname.'">'; // remove select to have id same with combo and ajax - $out.='<select class="flat maxwidthonsmartphone" id="'.$htmlname.'" name="'.$htmlname.'">'; - if (! $selected) $out.='<option value="0" selected> </option>'; - else $out.='<option value="0"> </option>'; - - $i = 0; - while ($i < $num) - { - $objp = $this->db->fetch_object($result); + * @return array Array of keys for json + */ + function select_produits_fournisseurs_list($socid,$selected='',$htmlname='productid',$filtertype='',$filtre='',$filterkey='',$statut=-1,$outputmode=0,$limit=100,$alsoproductwithnosupplierprice=0) + { + global $langs,$conf,$db; + + $out=''; + $outarray=array(); + + $langs->load('stocks'); + + $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,"; + $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,"; + $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,"; + $sql.= " pfp.supplier_reputation"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; + if ($socid) $sql.= " AND pfp.fk_soc = ".$socid; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid"; + $sql.= " WHERE p.entity IN (".getEntity('product').")"; + $sql.= " AND p.tobuy = 1"; + if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$this->db->escape($filtertype); + if (! empty($filtre)) $sql.=" ".$filtre; + // Add criteria on ref/label + if ($filterkey != '') + { + $sql.=' AND ('; + $prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on + // For natural search + $scrit = explode(' ', $filterkey); + $i=0; + if (count($scrit) > 1) $sql.="("; + foreach ($scrit as $crit) + { + if ($i > 0) $sql.=" AND "; + $sql.="(pfp.ref_fourn LIKE '".$this->db->escape($prefix.$crit)."%' OR p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%')"; + $i++; + } + if (count($scrit) > 1) $sql.=")"; + if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; + $sql.=')'; + } + $sql.= " ORDER BY pfp.ref_fourn DESC, pfp.quantity ASC"; + $sql.= $db->plimit($limit, 0); + + // Build output string + + dol_syslog(get_class($this)."::select_produits_fournisseurs_list", LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; + + $num = $this->db->num_rows($result); + + //$out.='<select class="flat" id="select'.$htmlname.'" name="'.$htmlname.'">'; // remove select to have id same with combo and ajax + $out.='<select class="flat maxwidthonsmartphone" id="'.$htmlname.'" name="'.$htmlname.'">'; + if (! $selected) $out.='<option value="0" selected> </option>'; + else $out.='<option value="0"> </option>'; + + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); - $outkey=$objp->idprodfournprice; // id in table of price - if (! $outkey && $alsoproductwithnosupplierprice) $outkey='idprod_'.$objp->rowid; // id of product + $outkey=$objp->idprodfournprice; // id in table of price + if (! $outkey && $alsoproductwithnosupplierprice) $outkey='idprod_'.$objp->rowid; // id of product - $outref=$objp->ref; - $outval=''; - $outqty=1; + $outref=$objp->ref; + $outval=''; + $outqty=1; $outdiscount=0; - $outtype=$objp->fk_product_type; - $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):''; - $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):''; - - $opt = '<option value="'.$outkey.'"'; - if ($selected && $selected == $objp->idprodfournprice) $opt.= ' selected'; - if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt.=' disabled'; - $opt.= '>'; - - $objRef = $objp->ref; - if ($filterkey && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1); - $objRefFourn = $objp->ref_fourn; - if ($filterkey && $filterkey != '') $objRefFourn=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRefFourn,1); - $label = $objp->label; - if ($filterkey && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1); - - $opt.=$objp->ref; - if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) - $opt.=' ('.$objp->ref_fourn.')'; - $opt.=' - '; - $outval.=$objRef; - if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) - $outval.=' ('.$objRefFourn.')'; - $outval.=' - '; - $opt.=dol_trunc($label, 72).' - '; - $outval.=dol_trunc($label, 72).' - '; - - if (! empty($objp->idprodfournprice)) - { - $outqty=$objp->quantity; + $outtype=$objp->fk_product_type; + $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):''; + $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):''; + + $opt = '<option value="'.$outkey.'"'; + if ($selected && $selected == $objp->idprodfournprice) $opt.= ' selected'; + if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt.=' disabled'; + $opt.= '>'; + + $objRef = $objp->ref; + if ($filterkey && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1); + $objRefFourn = $objp->ref_fourn; + if ($filterkey && $filterkey != '') $objRefFourn=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRefFourn,1); + $label = $objp->label; + if ($filterkey && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1); + + $opt.=$objp->ref; + if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) + $opt.=' ('.$objp->ref_fourn.')'; + $opt.=' - '; + $outval.=$objRef; + if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) + $outval.=' ('.$objRefFourn.')'; + $outval.=' - '; + $opt.=dol_trunc($label, 72).' - '; + $outval.=dol_trunc($label, 72).' - '; + + if (! empty($objp->idprodfournprice)) + { + $outqty=$objp->quantity; $outdiscount=$objp->remise_percent; - if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) { - $prod_supplier = new ProductFournisseur($this->db); - $prod_supplier->product_fourn_price_id = $objp->idprodfournprice; - $prod_supplier->id = $objp->fk_product; - $prod_supplier->fourn_qty = $objp->quantity; - $prod_supplier->fourn_tva_tx = $objp->tva_tx; - $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression; - $priceparser = new PriceParser($this->db); - $price_result = $priceparser->parseProductSupplier($prod_supplier); - if ($price_result >= 0) { - $objp->fprice = $price_result; - if ($objp->quantity >= 1) - { - $objp->unitprice = $objp->fprice / $objp->quantity; - } - } - } - if ($objp->quantity == 1) - { - $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/"; - $outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/"; - $opt.= $langs->trans("Unit"); // Do not use strtolower because it breaks utf8 encoding - $outval.=$langs->transnoentities("Unit"); - } - else - { - $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/".$objp->quantity; - $outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/".$objp->quantity; - $opt.= ' '.$langs->trans("Units"); // Do not use strtolower because it breaks utf8 encoding - $outval.= ' '.$langs->transnoentities("Units"); - } + if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) { + $prod_supplier = new ProductFournisseur($this->db); + $prod_supplier->product_fourn_price_id = $objp->idprodfournprice; + $prod_supplier->id = $objp->fk_product; + $prod_supplier->fourn_qty = $objp->quantity; + $prod_supplier->fourn_tva_tx = $objp->tva_tx; + $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression; + $priceparser = new PriceParser($this->db); + $price_result = $priceparser->parseProductSupplier($prod_supplier); + if ($price_result >= 0) { + $objp->fprice = $price_result; + if ($objp->quantity >= 1) + { + $objp->unitprice = $objp->fprice / $objp->quantity; + } + } + } + if ($objp->quantity == 1) + { + $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/"; + $outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/"; + $opt.= $langs->trans("Unit"); // Do not use strtolower because it breaks utf8 encoding + $outval.=$langs->transnoentities("Unit"); + } + else + { + $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/".$objp->quantity; + $outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/".$objp->quantity; + $opt.= ' '.$langs->trans("Units"); // Do not use strtolower because it breaks utf8 encoding + $outval.= ' '.$langs->transnoentities("Units"); + } - if ($objp->quantity >= 1) - { - $opt.=" (".price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit").")"; // Do not use strtolower because it breaks utf8 encoding - $outval.=" (".price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/".$langs->transnoentities("Unit").")"; // Do not use strtolower because it breaks utf8 encoding - } + if ($objp->quantity >= 1) + { + $opt.=" (".price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit").")"; // Do not use strtolower because it breaks utf8 encoding + $outval.=" (".price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/".$langs->transnoentities("Unit").")"; // Do not use strtolower because it breaks utf8 encoding + } if ($objp->remise_percent >= 1) - { - $opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %'; - $outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %'; - } - if ($objp->duration) - { - $opt .= " - ".$objp->duration; - $outval.=" - ".$objp->duration; - } - if (! $socid) - { - $opt .= " - ".dol_trunc($objp->name,8); - $outval.=" - ".dol_trunc($objp->name,8); - } - if ($objp->supplier_reputation) - { - //TODO dictionary - $reputations=array(''=>$langs->trans('Standard'),'FAVORITE'=>$langs->trans('Favorite'),'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier')); + { + $opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %'; + $outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %'; + } + if ($objp->duration) + { + $opt .= " - ".$objp->duration; + $outval.=" - ".$objp->duration; + } + if (! $socid) + { + $opt .= " - ".dol_trunc($objp->name,8); + $outval.=" - ".dol_trunc($objp->name,8); + } + if ($objp->supplier_reputation) + { + //TODO dictionary + $reputations=array(''=>$langs->trans('Standard'),'FAVORITE'=>$langs->trans('Favorite'),'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier')); - $opt .= " - ".$reputations[$objp->supplier_reputation]; - $outval.=" - ".$reputations[$objp->supplier_reputation]; - } - } - else - { - if (empty($alsoproductwithnosupplierprice)) // No supplier price defined for couple product/supplier - { - $opt.= $langs->trans("NoPriceDefinedForThisSupplier"); - $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier"); - } - else // No supplier price defined for product, even on other suppliers - { - $opt.= $langs->trans("NoPriceDefinedForThisSupplier"); - $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier"); - } - } - $opt .= "</option>\n"; + $opt .= " - ".$reputations[$objp->supplier_reputation]; + $outval.=" - ".$reputations[$objp->supplier_reputation]; + } + } + else + { + if (empty($alsoproductwithnosupplierprice)) // No supplier price defined for couple product/supplier + { + $opt.= $langs->trans("NoPriceDefinedForThisSupplier"); + $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier"); + } + else // No supplier price defined for product, even on other suppliers + { + $opt.= $langs->trans("NoPriceDefinedForThisSupplier"); + $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier"); + } + } + $opt .= "</option>\n"; - // Add new entry - // "key" value of json key array is used by jQuery automatically as selected value - // "label" value of json key array is used by jQuery automatically as text for combo box - $out.=$opt; - array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice)?true:false))); + // Add new entry + // "key" value of json key array is used by jQuery automatically as selected value + // "label" value of json key array is used by jQuery automatically as text for combo box + $out.=$opt; + array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice)?true:false))); // Exemple of var_dump $outarray // array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp" // ["label"]=>string(76) "ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)" // ["qty"]=>string(1) "1" ["discount"]=>string(1) "0" ["disabled"]=>bool(false) - //} - //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval)); - //$outval=array('label'=>'ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/ Unité (20,00 Euros/unité)'); - //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval)); - - $i++; - } - $out.='</select>'; - - $this->db->free($result); - - if (empty($outputmode)) return $out; - return $outarray; - } - else - { - dol_print_error($this->db); - } - } - - /** - * Return list of suppliers prices for a product - * - * @param int $productid Id of product - * @param string $htmlname Name of HTML field - * @param int $selected_supplier Pre-selected supplier if more than 1 result - * @return void - */ - function select_product_fourn_price($productid, $htmlname='productfournpriceid', $selected_supplier='') - { - global $langs,$conf; - - $langs->load('stocks'); - - $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,"; - $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice,"; - $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name"; - $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid"; - $sql.= " WHERE p.entity IN (".getEntity('productprice').")"; - $sql.= " AND p.tobuy = 1"; - $sql.= " AND s.fournisseur = 1"; - $sql.= " AND p.rowid = ".$productid; - $sql.= " ORDER BY s.nom, pfp.ref_fourn DESC"; - - dol_syslog(get_class($this)."::select_product_fourn_price", LOG_DEBUG); - $result=$this->db->query($sql); - - if ($result) - { - $num = $this->db->num_rows($result); - - $form = '<select class="flat" name="'.$htmlname.'">'; - - if (! $num) - { - $form.= '<option value="0">-- '.$langs->trans("NoSupplierPriceDefinedForThisProduct").' --</option>'; - } - else - { - require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; - $form.= '<option value="0"> </option>'; - - $i = 0; - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - - $opt = '<option value="'.$objp->idprodfournprice.'"'; - //if there is only one supplier, preselect it - if($num == 1 || ($selected_supplier > 0 && $objp->fk_soc == $selected_supplier)) { - $opt .= ' selected'; - } - $opt.= '>'.$objp->name.' - '.$objp->ref_fourn.' - '; - - if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) { - $prod_supplier = new ProductFournisseur($this->db); - $prod_supplier->product_fourn_price_id = $objp->idprodfournprice; - $prod_supplier->id = $productid; - $prod_supplier->fourn_qty = $objp->quantity; - $prod_supplier->fourn_tva_tx = $objp->tva_tx; - $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression; - $priceparser = new PriceParser($this->db); - $price_result = $priceparser->parseProductSupplier($prod_supplier); - if ($price_result >= 0) { - $objp->fprice = $price_result; - if ($objp->quantity >= 1) - { - $objp->unitprice = $objp->fprice / $objp->quantity; - } - } - } - if ($objp->quantity == 1) - { - $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/"; - } - - $opt.= $objp->quantity.' '; - - if ($objp->quantity == 1) - { - $opt.= $langs->trans("Unit"); - } - else - { - $opt.= $langs->trans("Units"); - } - if ($objp->quantity > 1) - { - $opt.=" - "; - $opt.= price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit"); - } - if ($objp->duration) $opt .= " - ".$objp->duration; - $opt .= "</option>\n"; - - $form.= $opt; - $i++; - } - } - - $form.= '</select>'; - $this->db->free($result); - return $form; - } - else - { - dol_print_error($this->db); - } - } - - /** - * Return list of delivery address - * - * @param string $selected Id contact pre-selectionn - * @param int $socid Id of company - * @param string $htmlname Name of HTML field - * @param int $showempty Add an empty field - * @return integer|null - */ - function select_address($selected, $socid, $htmlname='address_id',$showempty=0) - { - // On recherche les utilisateurs - $sql = "SELECT a.rowid, a.label"; - $sql .= " FROM ".MAIN_DB_PREFIX ."societe_address as a"; - $sql .= " WHERE a.fk_soc = ".$socid; - $sql .= " ORDER BY a.label ASC"; - - dol_syslog(get_class($this)."::select_address", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - print '<select class="flat" name="'.$htmlname.'">'; - if ($showempty) print '<option value="0"> </option>'; - $num = $this->db->num_rows($resql); - $i = 0; - if ($num) - { - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + //} + //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval)); + //$outval=array('label'=>'ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/ Unité (20,00 Euros/unité)'); + //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval)); - if ($selected && $selected == $obj->rowid) - { - print '<option value="'.$obj->rowid.'" selected>'.$obj->label.'</option>'; - } - else - { - print '<option value="'.$obj->rowid.'">'.$obj->label.'</option>'; - } - $i++; - } - } - print '</select>'; - return $num; - } - else - { - dol_print_error($this->db); - } - } - - - /** - * Load into cache list of payment terms - * - * @return int Nb of lines loaded, <0 if KO - */ - function load_cache_conditions_paiements() - { - global $langs; - - $num = count($this->cache_conditions_paiements); - if ($num > 0) return 0; // Cache already loaded - - dol_syslog(__METHOD__, LOG_DEBUG); - - $sql = "SELECT rowid, code, libelle as label"; - $sql.= " FROM ".MAIN_DB_PREFIX.'c_payment_term'; - $sql.= " WHERE entity = " . getEntity('c_payment_term'); - $sql.= " AND active > 0"; - $sql.= " ORDER BY sortorder"; - - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + $i++; + } + $out.='</select>'; - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $label=($langs->trans("PaymentConditionShort".$obj->code)!=("PaymentConditionShort".$obj->code)?$langs->trans("PaymentConditionShort".$obj->code):($obj->label!='-'?$obj->label:'')); - $this->cache_conditions_paiements[$obj->rowid]['code'] =$obj->code; - $this->cache_conditions_paiements[$obj->rowid]['label']=$label; - $i++; - } + $this->db->free($result); - //$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label', 'asc', 0, 0, 1); // We use the field sortorder of table + if (empty($outputmode)) return $out; + return $outarray; + } + else + { + dol_print_error($this->db); + } + } - return $num; - } - else + /** + * Return list of suppliers prices for a product + * + * @param int $productid Id of product + * @param string $htmlname Name of HTML field + * @param int $selected_supplier Pre-selected supplier if more than 1 result + * @return void + */ + function select_product_fourn_price($productid, $htmlname='productfournpriceid', $selected_supplier='') + { + global $langs,$conf; + + $langs->load('stocks'); + + $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,"; + $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice,"; + $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid"; + $sql.= " WHERE p.entity IN (".getEntity('productprice').")"; + $sql.= " AND p.tobuy = 1"; + $sql.= " AND s.fournisseur = 1"; + $sql.= " AND p.rowid = ".$productid; + $sql.= " ORDER BY s.nom, pfp.ref_fourn DESC"; + + dol_syslog(get_class($this)."::select_product_fourn_price", LOG_DEBUG); + $result=$this->db->query($sql); + + if ($result) { - dol_print_error($this->db); - return -1; - } - } + $num = $this->db->num_rows($result); - /** - * Charge dans cache la liste des délais de livraison possibles - * - * @return int Nb of lines loaded, <0 if KO - */ - function load_cache_availability() - { - global $langs; + $form = '<select class="flat" name="'.$htmlname.'">'; - $num = count($this->cache_availability); - if ($num > 0) return 0; // Cache already loaded + if (! $num) + { + $form.= '<option value="0">-- '.$langs->trans("NoSupplierPriceDefinedForThisProduct").' --</option>'; + } + else + { + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; + $form.= '<option value="0"> </option>'; - dol_syslog(__METHOD__, LOG_DEBUG); + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); - $langs->load('propal'); + $opt = '<option value="'.$objp->idprodfournprice.'"'; + //if there is only one supplier, preselect it + if($num == 1 || ($selected_supplier > 0 && $objp->fk_soc == $selected_supplier)) { + $opt .= ' selected'; + } + $opt.= '>'.$objp->name.' - '.$objp->ref_fourn.' - '; + + if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) { + $prod_supplier = new ProductFournisseur($this->db); + $prod_supplier->product_fourn_price_id = $objp->idprodfournprice; + $prod_supplier->id = $productid; + $prod_supplier->fourn_qty = $objp->quantity; + $prod_supplier->fourn_tva_tx = $objp->tva_tx; + $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression; + $priceparser = new PriceParser($this->db); + $price_result = $priceparser->parseProductSupplier($prod_supplier); + if ($price_result >= 0) { + $objp->fprice = $price_result; + if ($objp->quantity >= 1) + { + $objp->unitprice = $objp->fprice / $objp->quantity; + } + } + } + if ($objp->quantity == 1) + { + $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/"; + } - $sql = "SELECT rowid, code, label"; - $sql.= " FROM ".MAIN_DB_PREFIX.'c_availability'; - $sql.= " WHERE active > 0"; + $opt.= $objp->quantity.' '; - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $label=($langs->trans("AvailabilityType".$obj->code)!=("AvailabilityType".$obj->code)?$langs->trans("AvailabilityType".$obj->code):($obj->label!='-'?$obj->label:'')); - $this->cache_availability[$obj->rowid]['code'] =$obj->code; - $this->cache_availability[$obj->rowid]['label']=$label; - $i++; - } + if ($objp->quantity == 1) + { + $opt.= $langs->trans("Unit"); + } + else + { + $opt.= $langs->trans("Units"); + } + if ($objp->quantity > 1) + { + $opt.=" - "; + $opt.= price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit"); + } + if ($objp->duration) $opt .= " - ".$objp->duration; + $opt .= "</option>\n"; - $this->cache_availability = dol_sort_array($this->cache_availability, 'label', 'asc', 0, 0, 1); - - return $num; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Retourne la liste des types de delais de livraison possibles - * - * @param int $selected Id du type de delais pre-selectionne - * @param string $htmlname Nom de la zone select - * @param string $filtertype To add a filter - * @param int $addempty Add empty entry - * @return void - */ - function selectAvailabilityDelay($selected='',$htmlname='availid',$filtertype='',$addempty=0) - { - global $langs,$user; - - $this->load_cache_availability(); - - dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); - - print '<select class="flat" name="'.$htmlname.'">'; - if ($addempty) print '<option value="0"> </option>'; - foreach($this->cache_availability as $id => $arrayavailability) - { - if ($selected == $id) - { - print '<option value="'.$id.'" selected>'; - } - else - { - print '<option value="'.$id.'">'; - } - print $arrayavailability['label']; - print '</option>'; - } - print '</select>'; - if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - } - - /** - * Load into cache cache_demand_reason, array of input reasons - * - * @return int Nb of lines loaded, <0 if KO - */ - function loadCacheInputReason() - { - global $langs; - - $num = count($this->cache_demand_reason); - if ($num > 0) return 0; // Cache already loaded - - $sql = "SELECT rowid, code, label"; - $sql.= " FROM ".MAIN_DB_PREFIX.'c_input_reason'; - $sql.= " WHERE active > 0"; - - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - $tmparray=array(); - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $label=($langs->trans("DemandReasonType".$obj->code)!=("DemandReasonType".$obj->code)?$langs->trans("DemandReasonType".$obj->code):($obj->label!='-'?$obj->label:'')); - $tmparray[$obj->rowid]['id'] =$obj->rowid; - $tmparray[$obj->rowid]['code'] =$obj->code; - $tmparray[$obj->rowid]['label']=$label; - $i++; - } + $form.= $opt; + $i++; + } + } - $this->cache_demand_reason=dol_sort_array($tmparray, 'label', 'asc', 0, 0, 1); + $form.= '</select>'; + $this->db->free($result); + return $form; + } + else + { + dol_print_error($this->db); + } + } - unset($tmparray); - return $num; - } - else + /** + * Return list of delivery address + * + * @param string $selected Id contact pre-selectionn + * @param int $socid Id of company + * @param string $htmlname Name of HTML field + * @param int $showempty Add an empty field + * @return integer|null + */ + function select_address($selected, $socid, $htmlname='address_id',$showempty=0) + { + // On recherche les utilisateurs + $sql = "SELECT a.rowid, a.label"; + $sql .= " FROM ".MAIN_DB_PREFIX ."societe_address as a"; + $sql .= " WHERE a.fk_soc = ".$socid; + $sql .= " ORDER BY a.label ASC"; + + dol_syslog(get_class($this)."::select_address", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) { - dol_print_error($this->db); - return -1; - } - } + print '<select class="flat" name="'.$htmlname.'">'; + if ($showempty) print '<option value="0"> </option>'; + $num = $this->db->num_rows($resql); + $i = 0; + if ($num) + { + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); - /** - * Return list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...) - * List found into table c_input_reason loaded by loadCacheInputReason - * - * @param int $selected Id or code of type origin to select by default - * @param string $htmlname Nom de la zone select - * @param string $exclude To exclude a code value (Example: SRC_PROP) - * @param int $addempty Add an empty entry - * @return void - */ - function selectInputReason($selected='',$htmlname='demandreasonid',$exclude='',$addempty=0) - { - global $langs,$user; - - $this->loadCacheInputReason(); - - print '<select class="flat" name="'.$htmlname.'">'; - if ($addempty) print '<option value="0"'.(empty($selected)?' selected':'').'> </option>'; - foreach($this->cache_demand_reason as $id => $arraydemandreason) - { - if ($arraydemandreason['code']==$exclude) continue; - - if ($selected && ($selected == $arraydemandreason['id'] || $selected == $arraydemandreason['code'])) - { - print '<option value="'.$arraydemandreason['id'].'" selected>'; - } - else - { - print '<option value="'.$arraydemandreason['id'].'">'; - } - print $arraydemandreason['label']; - print '</option>'; - } - print '</select>'; - if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - } - - /** - * Charge dans cache la liste des types de paiements possibles - * - * @return int Nb of lines loaded, <0 if KO - */ - function load_cache_types_paiements() - { - global $langs; - - $num=count($this->cache_types_paiements); - if ($num > 0) return $num; // Cache already loaded - - dol_syslog(__METHOD__, LOG_DEBUG); - - $this->cache_types_paiements = array(); - - $sql = "SELECT id, code, libelle as label, type, active"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement"; - $sql.= " WHERE entity = " . getEntity('c_paiement'); - //if ($active >= 0) $sql.= " AND active = ".$active; - - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $label=($langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code)!=("PaymentTypeShort".$obj->code)?$langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code):($obj->label!='-'?$obj->label:'')); - $this->cache_types_paiements[$obj->id]['id'] =$obj->id; - $this->cache_types_paiements[$obj->id]['code'] =$obj->code; - $this->cache_types_paiements[$obj->id]['label']=$label; - $this->cache_types_paiements[$obj->id]['type'] =$obj->type; - $this->cache_types_paiements[$obj->id]['active'] =$obj->active; - $i++; - } + if ($selected && $selected == $obj->rowid) + { + print '<option value="'.$obj->rowid.'" selected>'.$obj->label.'</option>'; + } + else + { + print '<option value="'.$obj->rowid.'">'.$obj->label.'</option>'; + } + $i++; + } + } + print '</select>'; + return $num; + } + else + { + dol_print_error($this->db); + } + } - $this->cache_types_paiements = dol_sort_array($this->cache_types_paiements, 'label', 'asc', 0, 0, 1); - - return $num; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - - /** - * Return list of payment modes. - * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. - * See instead to force the default value by the caller. - * - * @param int $selected Id of payment term to preselect by default - * @param string $htmlname Nom de la zone select - * @param int $filtertype Not used - * @param int $addempty Add an empty entry - * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info - * @param string $morecss Add more CSS on select tag - * @return void - */ - function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0, $noinfoadmin=0, $morecss='') - { - global $langs, $user, $conf; - - dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); - - $this->load_cache_conditions_paiements(); - - // Set default value if not already set by caller - if (empty($selected) && ! empty($conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID)) $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID; - - print '<select id="'.$htmlname.'" class="flat selectpaymentterms'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'">'; - if ($addempty) print '<option value="0"> </option>'; - foreach($this->cache_conditions_paiements as $id => $arrayconditions) - { - if ($selected == $id) - { - print '<option value="'.$id.'" selected>'; - } - else - { - print '<option value="'.$id.'">'; - } - print $arrayconditions['label']; - print '</option>'; - } - print '</select>'; - if ($user->admin && empty($noinfoadmin)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - } - - - /** - * Return list of payment methods - * - * @param string $selected Id du mode de paiement pre-selectionne - * @param string $htmlname Nom de la zone select - * @param string $filtertype To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz)) - * @param int $format 0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code - * @param int $empty 1=peut etre vide, 0 sinon - * @param int $noadmininfo 0=Add admin info, 1=Disable admin info - * @param int $maxlength Max length of label - * @param int $active Active or not, -1 = all - * @param string $morecss Add more CSS on select tag - * @return void - */ - function select_types_paiements($selected='', $htmlname='paiementtype', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $active=1, $morecss='') - { - global $langs,$user; - - dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG); - - $filterarray=array(); - if ($filtertype == 'CRDT') $filterarray=array(0,2,3); - elseif ($filtertype == 'DBIT') $filterarray=array(1,2,3); - elseif ($filtertype != '' && $filtertype != '-1') $filterarray=explode(',',$filtertype); - - $this->load_cache_types_paiements(); - - print '<select id="select'.$htmlname.'" class="flat selectpaymenttypes'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'">'; - if ($empty) print '<option value=""> </option>'; - foreach($this->cache_types_paiements as $id => $arraytypes) - { - // If not good status - if ($active >= 0 && $arraytypes['active'] != $active) continue; - - // On passe si on a demande de filtrer sur des modes de paiments particuliers - if (count($filterarray) && ! in_array($arraytypes['type'],$filterarray)) continue; - - // We discard empty line if showempty is on because an empty line has already been output. - if ($empty && empty($arraytypes['code'])) continue; - - if ($format == 0) print '<option value="'.$id.'"'; - if ($format == 1) print '<option value="'.$arraytypes['code'].'"'; - if ($format == 2) print '<option value="'.$arraytypes['code'].'"'; - if ($format == 3) print '<option value="'.$id.'"'; - // Si selected est text, on compare avec code, sinon avec id - if (preg_match('/[a-z]/i', $selected) && $selected == $arraytypes['code']) print ' selected'; - elseif ($selected == $id) print ' selected'; - print '>'; - if ($format == 0) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']); - if ($format == 1) $value=$arraytypes['code']; - if ($format == 2) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']); - if ($format == 3) $value=$arraytypes['code']; - print $value?$value:' '; - print '</option>'; - } - print '</select>'; - if ($user->admin && ! $noadmininfo) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - } - - - /** - * Selection HT or TTC - * - * @param string $selected Id pre-selectionne - * @param string $htmlname Nom de la zone select - * @return string Code of HTML select to chose tax or not - */ - function selectPriceBaseType($selected='',$htmlname='price_base_type') - { - global $langs; - - $return=''; - - $return.= '<select class="flat" name="'.$htmlname.'">'; - $options = array( - 'HT'=>$langs->trans("HT"), - 'TTC'=>$langs->trans("TTC") - ); - foreach($options as $id => $value) - { - if ($selected == $id) - { - $return.= '<option value="'.$id.'" selected>'.$value; - } - else - { - $return.= '<option value="'.$id.'">'.$value; - } - $return.= '</option>'; - } - $return.= '</select>'; - - return $return; - } - - /** - * Return a HTML select list of shipping mode - * - * @param string $selected Id shipping mode pre-selected - * @param string $htmlname Name of select zone - * @param string $filtre To filter list - * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @param string $moreattrib To add more attribute on select - * @return void - */ - function selectShippingMethod($selected='',$htmlname='shipping_method_id',$filtre='',$useempty=0,$moreattrib='') - { - global $langs, $conf, $user; - - $langs->load("admin"); - $langs->load("deliveries"); - - $sql = "SELECT rowid, code, libelle as label"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode"; - $sql.= " WHERE active > 0"; - if ($filtre) $sql.=" AND ".$filtre; - $sql.= " ORDER BY libelle ASC"; - - dol_syslog(get_class($this)."::selectShippingMode", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $num = $this->db->num_rows($result); - $i = 0; - if ($num) { - print '<select id="select'.$htmlname.'" class="flat selectshippingmethod" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>'; - if ($useempty == 1 || ($useempty == 2 && $num > 1)) { - print '<option value="-1"> </option>'; - } - while ($i < $num) { - $obj = $this->db->fetch_object($result); - if ($selected == $obj->rowid) { - print '<option value="'.$obj->rowid.'" selected>'; - } else { - print '<option value="'.$obj->rowid.'">'; - } - print ($langs->trans("SendingMethod".strtoupper($obj->code)) != "SendingMethod".strtoupper($obj->code)) ? $langs->trans("SendingMethod".strtoupper($obj->code)) : $obj->label; - print '</option>'; - $i++; - } - print "</select>"; - if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - } else { - print $langs->trans("NoShippingMethodDefined"); - } - } else { - dol_print_error($this->db); - } - } - - /** - * Display form to select shipping mode - * - * @param string $page Page - * @param int $selected Id of shipping mode - * @param string $htmlname Name of select html field - * @param int $addempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @return void - */ - function formSelectShippingMethod($page, $selected='', $htmlname='shipping_method_id', $addempty=0) - { - global $langs, $db; - - $langs->load("deliveries"); - - if ($htmlname != "none") { - print '<form method="POST" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setshippingmethod">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $this->selectShippingMethod($selected, $htmlname, '', $addempty); - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } else { - if ($selected) { - $code=$langs->getLabelFromKey($db, $selected, 'c_shipment_mode', 'rowid', 'code'); - print $langs->trans("SendingMethod".strtoupper($code)); - } else { - print " "; - } - } - } /** - * Creates HTML last in cycle situation invoices selector - * - * @param string $selected Preselected ID - * @param int $socid Company ID + * Load into cache list of payment terms * - * @return string HTML select + * @return int Nb of lines loaded, <0 if KO */ - function selectSituationInvoices($selected = '', $socid = 0) + function load_cache_conditions_paiements() { global $langs; - $langs->load('bills'); + $num = count($this->cache_conditions_paiements); + if ($num > 0) return 0; // Cache already loaded + + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = "SELECT rowid, code, libelle as label"; + $sql.= " FROM ".MAIN_DB_PREFIX.'c_payment_term'; + $sql.= " WHERE entity = " . getEntity('c_payment_term'); + $sql.= " AND active > 0"; + $sql.= " ORDER BY sortorder"; - $opt = '<option value ="" selected></option>'; - $sql = 'SELECT rowid, facnumber, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1'; - $sql.= ' ORDER by situation_cycle_ref, situation_counter desc'; $resql = $this->db->query($sql); - if ($resql && $this->db->num_rows($resql) > 0) { - // Last seen cycle - $ref = 0; - while ($res = $this->db->fetch_array($resql, MYSQL_NUM)) { - //Same company ? - if ($socid == $res[5]) { - //Same cycle ? - if ($res[2] != $ref) { - // Just seen this cycle - $ref = $res[2]; - //not final ? - if ($res[4] != 1) { - //Not prov? - if (substr($res[1], 1, 4) != 'PROV') { - if ($selected == $res[0]) { - $opt .= '<option value="' . $res[0] . '" selected>' . $res[1] . '</option>'; - } else { - $opt .= '<option value="' . $res[0] . '">' . $res[1] . '</option>'; - } - } - } - } - } + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut + $label=($langs->trans("PaymentConditionShort".$obj->code)!=("PaymentConditionShort".$obj->code)?$langs->trans("PaymentConditionShort".$obj->code):($obj->label!='-'?$obj->label:'')); + $this->cache_conditions_paiements[$obj->rowid]['code'] =$obj->code; + $this->cache_conditions_paiements[$obj->rowid]['label']=$label; + $i++; } + + //$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label', 'asc', 0, 0, 1); // We use the field sortorder of table + + return $num; } else { - dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR); - } - if ($opt == '<option value ="" selected></option>') - { - $opt = '<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>'; + dol_print_error($this->db); + return -1; } - return $opt; } - /** - * Creates HTML units selector (code => label) - * - * @param string $selected Preselected Unit ID - * @param string $htmlname Select name - * @param int $showempty Add a nempty line - * @return string HTML select - */ - function selectUnits($selected = '', $htmlname = 'units', $showempty=0) - { - global $langs; + /** + * Charge dans cache la liste des délais de livraison possibles + * + * @return int Nb of lines loaded, <0 if KO + */ + function load_cache_availability() + { + global $langs; - $langs->load('products'); + $num = count($this->cache_availability); + if ($num > 0) return 0; // Cache already loaded - $return= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'">'; + dol_syslog(__METHOD__, LOG_DEBUG); - $sql = 'SELECT rowid, label, code from '.MAIN_DB_PREFIX.'c_units'; - $sql.= ' WHERE active > 0'; + $langs->load('propal'); - $resql = $this->db->query($sql); - if($resql && $this->db->num_rows($resql) > 0) - { - if ($showempty) $return .= '<option value="none"></option>'; + $sql = "SELECT rowid, code, label"; + $sql.= " FROM ".MAIN_DB_PREFIX.'c_availability'; + $sql.= " WHERE active > 0"; - while($res = $this->db->fetch_object($resql)) - { - if ($selected == $res->rowid) - { - $return.='<option value="'.$res->rowid.'" selected>'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>'; - } - else - { - $return.='<option value="'.$res->rowid.'">'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>'; - } - } - $return.='</select>'; - } - return $return; - } - - /** - * Return a HTML select list of bank accounts - * - * @param string $selected Id account pre-selected - * @param string $htmlname Name of select zone - * @param int $statut Status of searched accounts (0=open, 1=closed, 2=both) - * @param string $filtre To filter list - * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @param string $moreattrib To add more attribute on select - * @param int $showcurrency Show currency in label - * @return void - */ - function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='',$showcurrency=0) - { - global $langs, $conf; - - $langs->load("admin"); - - $sql = "SELECT rowid, label, bank, clos as status, currency_code"; - $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; - $sql.= " WHERE entity IN (".getEntity('bank_account').")"; - if ($statut != 2) $sql.= " AND clos = '".$statut."'"; - if ($filtre) $sql.=" AND ".$filtre; - $sql.= " ORDER BY label"; - - dol_syslog(get_class($this)."::select_comptes", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - if ($num) - { - print '<select id="select'.$htmlname.'" class="flat selectbankaccount" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>'; - if ($useempty == 1 || ($useempty == 2 && $num > 1)) - { - print '<option value="-1"> </option>'; - } + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); - while ($i < $num) - { - $obj = $this->db->fetch_object($result); - if ($selected == $obj->rowid) - { - print '<option value="'.$obj->rowid.'" selected>'; - } - else - { - print '<option value="'.$obj->rowid.'">'; - } - print trim($obj->label); - if ($showcurrency) print ' ('.$obj->currency_code.')'; - if ($statut == 2 && $obj->status == 1) print ' ('.$langs->trans("Closed").')'; - print '</option>'; - $i++; - } - print "</select>"; - } - else - { - print $langs->trans("NoActiveBankAccountDefined"); - } - } - else { - dol_print_error($this->db); - } - } - - /** - * Display form to select bank account - * - * @param string $page Page - * @param int $selected Id of bank account - * @param string $htmlname Name of select html field - * @param int $addempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @return void - */ - function formSelectAccount($page, $selected='', $htmlname='fk_account', $addempty=0) - { - global $langs; - if ($htmlname != "none") { - print '<form method="POST" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setbankaccount">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $this->select_comptes($selected, $htmlname, 0, '', $addempty); - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } else { - - $langs->load('banks'); - - if ($selected) { - require_once DOL_DOCUMENT_ROOT .'/compta/bank/class/account.class.php'; - $bankstatic=new Account($this->db); - $bankstatic->fetch($selected); - print $bankstatic->getNomUrl(1); - } else { - print " "; - } - } - } - - /** - * Return list of categories having choosed type - * - * @param string|int $type Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated. - * @param string $selected Id of category preselected or 'auto' (autoselect category if there is only one element) - * @param string $htmlname HTML field name - * @param int $maxlength Maximum length for labels - * @param int $excludeafterid Exclude all categories after this leaf in category tree. - * @param int $outputmode 0=HTML select string, 1=Array - * @return string - * @see select_categories - */ - function select_all_categories($type, $selected='', $htmlname="parent", $maxlength=64, $excludeafterid=0, $outputmode=0) - { - global $conf, $langs; - $langs->load("categories"); + // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut + $label=($langs->trans("AvailabilityType".$obj->code)!=("AvailabilityType".$obj->code)?$langs->trans("AvailabilityType".$obj->code):($obj->label!='-'?$obj->label:'')); + $this->cache_availability[$obj->rowid]['code'] =$obj->code; + $this->cache_availability[$obj->rowid]['label']=$label; + $i++; + } - include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + $this->cache_availability = dol_sort_array($this->cache_availability, 'label', 'asc', 0, 0, 1); - // For backward compatibility - if (is_numeric($type)) + return $num; + } + else { - dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING); + dol_print_error($this->db); + return -1; } + } - if ($type === Categorie::TYPE_BANK_LINE) + /** + * Retourne la liste des types de delais de livraison possibles + * + * @param int $selected Id du type de delais pre-selectionne + * @param string $htmlname Nom de la zone select + * @param string $filtertype To add a filter + * @param int $addempty Add empty entry + * @return void + */ + function selectAvailabilityDelay($selected='',$htmlname='availid',$filtertype='',$addempty=0) + { + global $langs,$user; + + $this->load_cache_availability(); + + dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); + + print '<select class="flat" name="'.$htmlname.'">'; + if ($addempty) print '<option value="0"> </option>'; + foreach($this->cache_availability as $id => $arrayavailability) { - // TODO Move this into common category feature - $categids=array(); - $sql = "SELECT c.label, c.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."bank_categ as c"; - $sql.= " WHERE entity = ".$conf->entity; - $sql.= " ORDER BY c.label"; - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - if ($objp) $cate_arbo[$objp->rowid]=array('id'=>$objp->rowid, 'fulllabel'=>$objp->label); - $i++; - } - $this->db->free($result); - } - else dol_print_error($this->db); + if ($selected == $id) + { + print '<option value="'.$id.'" selected>'; + } + else + { + print '<option value="'.$id.'">'; + } + print $arrayavailability['label']; + print '</option>'; + } + print '</select>'; + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + } + + /** + * Load into cache cache_demand_reason, array of input reasons + * + * @return int Nb of lines loaded, <0 if KO + */ + function loadCacheInputReason() + { + global $langs; + + $num = count($this->cache_demand_reason); + if ($num > 0) return 0; // Cache already loaded + + $sql = "SELECT rowid, code, label"; + $sql.= " FROM ".MAIN_DB_PREFIX.'c_input_reason'; + $sql.= " WHERE active > 0"; + + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + $tmparray=array(); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut + $label=($langs->trans("DemandReasonType".$obj->code)!=("DemandReasonType".$obj->code)?$langs->trans("DemandReasonType".$obj->code):($obj->label!='-'?$obj->label:'')); + $tmparray[$obj->rowid]['id'] =$obj->rowid; + $tmparray[$obj->rowid]['code'] =$obj->code; + $tmparray[$obj->rowid]['label']=$label; + $i++; + } + + $this->cache_demand_reason=dol_sort_array($tmparray, 'label', 'asc', 0, 0, 1); + + unset($tmparray); + return $num; } else { - $cat = new Categorie($this->db); - $cate_arbo = $cat->get_full_arbo($type, $excludeafterid); + dol_print_error($this->db); + return -1; } + } - $output = '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">'; - $outarray=array(); - if (is_array($cate_arbo)) - { - if (! count($cate_arbo)) $output.= '<option value="-1" disabled>'.$langs->trans("NoCategoriesDefined").'</option>'; - else - { - $output.= '<option value="-1"> </option>'; - foreach($cate_arbo as $key => $value) - { - if ($cate_arbo[$key]['id'] == $selected || ($selected == 'auto' && count($cate_arbo) == 1)) - { - $add = 'selected '; - } - else - { - $add = ''; - } - $output.= '<option '.$add.'value="'.$cate_arbo[$key]['id'].'">'.dol_trunc($cate_arbo[$key]['fulllabel'],$maxlength,'middle').'</option>'; + /** + * Return list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...) + * List found into table c_input_reason loaded by loadCacheInputReason + * + * @param int $selected Id or code of type origin to select by default + * @param string $htmlname Nom de la zone select + * @param string $exclude To exclude a code value (Example: SRC_PROP) + * @param int $addempty Add an empty entry + * @return void + */ + function selectInputReason($selected='',$htmlname='demandreasonid',$exclude='',$addempty=0) + { + global $langs,$user; - $outarray[$cate_arbo[$key]['id']] = $cate_arbo[$key]['fulllabel']; - } - } - } - $output.= '</select>'; - $output.= "\n"; + $this->loadCacheInputReason(); - if ($outputmode) return $outarray; - return $output; - } - - /** - * Show a confirmation HTML form or AJAX popup - * - * @param string $page Url of page to call if confirmation is OK - * @param string $title Title - * @param string $question Question - * @param string $action Action - * @param array $formquestion An array with forms complementary inputs - * @param string $selectedchoice "" or "no" or "yes" - * @param int $useajax 0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=preoutput confirm box with div id=dialog-confirm-xxx - * @param int $height Force height of box - * @param int $width Force width of box - * @return void - * @deprecated - * @see formconfirm() - */ - function form_confirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=170, $width=500) - { - print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width); - } - - /** - * Show a confirmation HTML form or AJAX popup. - * Easiest way to use this is with useajax=1. - * If you use useajax='xxx', you must also add jquery code to trigger opening of box (with correct parameters) - * just after calling this method. For example: - * print '<script type="text/javascript">'."\n"; - * print 'jQuery(document).ready(function() {'."\n"; - * print 'jQuery(".xxxlink").click(function(e) { jQuery("#aparamid").val(jQuery(this).attr("rel")); jQuery("#dialog-confirm-xxx").dialog("open"); return false; });'."\n"; - * print '});'."\n"; - * print '</script>'."\n"; - * - * @param string $page Url of page to call if confirmation is OK - * @param string $title Title - * @param string $question Question - * @param string $action Action - * @param array $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , )) - * @param string $selectedchoice "" or "no" or "yes" - * @param int $useajax 0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx - * @param int $height Force height of box - * @param int $width Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones. - * @return string HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form - */ - function formconfirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=200, $width=500) - { - global $langs,$conf; - global $useglobalvars; - - $more=''; - $formconfirm=''; - $inputok=array(); - $inputko=array(); - - // Clean parameters - $newselectedchoice=empty($selectedchoice)?"no":$selectedchoice; - if ($conf->browser->layout == 'phone') $width='95%'; - - if (is_array($formquestion) && ! empty($formquestion)) - { - // First add hidden fields and value - foreach ($formquestion as $key => $input) - { - if (is_array($input) && ! empty($input)) - { - if ($input['type'] == 'hidden') - { - $more.='<input type="hidden" id="'.$input['name'].'" name="'.$input['name'].'" value="'.dol_escape_htmltag($input['value']).'">'."\n"; - } - } - } + print '<select class="flat" name="'.$htmlname.'">'; + if ($addempty) print '<option value="0"'.(empty($selected)?' selected':'').'> </option>'; + foreach($this->cache_demand_reason as $id => $arraydemandreason) + { + if ($arraydemandreason['code']==$exclude) continue; - // Now add questions - $more.='<table class="paddingtopbottomonly" width="100%">'."\n"; - $more.='<tr><td colspan="3">'.(! empty($formquestion['text'])?$formquestion['text']:'').'</td></tr>'."\n"; - foreach ($formquestion as $key => $input) - { - if (is_array($input) && ! empty($input)) - { - $size=(! empty($input['size'])?' size="'.$input['size'].'"':''); + if ($selected && ($selected == $arraydemandreason['id'] || $selected == $arraydemandreason['code'])) + { + print '<option value="'.$arraydemandreason['id'].'" selected>'; + } + else + { + print '<option value="'.$arraydemandreason['id'].'">'; + } + print $arraydemandreason['label']; + print '</option>'; + } + print '</select>'; + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + } - if ($input['type'] == 'text') - { - $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="text" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n"; - } - else if ($input['type'] == 'password') - { - $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="password" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n"; - } - else if ($input['type'] == 'select') - { - $more.='<tr><td>'; - if (! empty($input['label'])) $more.=$input['label'].'</td><td valign="top" colspan="2" align="left">'; - $more.=$this->selectarray($input['name'],$input['values'],$input['default'],1); - $more.='</td></tr>'."\n"; - } - else if ($input['type'] == 'checkbox') - { - $more.='<tr>'; - $more.='<td>'.$input['label'].' </td><td align="left">'; - $more.='<input type="checkbox" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'; - if (! is_bool($input['value']) && $input['value'] != 'false') $more.=' checked'; - if (is_bool($input['value']) && $input['value']) $more.=' checked'; - if (isset($input['disabled'])) $more.=' disabled'; - $more.=' /></td>'; - $more.='<td align="left"> </td>'; - $more.='</tr>'."\n"; - } - else if ($input['type'] == 'radio') - { - $i=0; - foreach($input['values'] as $selkey => $selval) - { - $more.='<tr>'; - if ($i==0) $more.='<td class="tdtop">'.$input['label'].'</td>'; - else $more.='<td> </td>'; - $more.='<td width="20"><input type="radio" class="flat" id="'.$input['name'].'" name="'.$input['name'].'" value="'.$selkey.'"'; - if ($input['disabled']) $more.=' disabled'; - $more.=' /></td>'; - $more.='<td align="left">'; - $more.=$selval; - $more.='</td></tr>'."\n"; - $i++; - } - } - else if ($input['type'] == 'date') - { - $more.='<tr><td>'.$input['label'].'</td>'; - $more.='<td colspan="2" align="left">'; - $more.=$this->select_date($input['value'],$input['name'],0,0,0,'',1,0,1); - $more.='</td></tr>'."\n"; - $formquestion[] = array('name'=>$input['name'].'day'); - $formquestion[] = array('name'=>$input['name'].'month'); - $formquestion[] = array('name'=>$input['name'].'year'); - $formquestion[] = array('name'=>$input['name'].'hour'); - $formquestion[] = array('name'=>$input['name'].'min'); - } - else if ($input['type'] == 'other') - { - $more.='<tr><td>'; - if (! empty($input['label'])) $more.=$input['label'].'</td><td colspan="2" align="left">'; - $more.=$input['value']; - $more.='</td></tr>'."\n"; - } + /** + * Charge dans cache la liste des types de paiements possibles + * + * @return int Nb of lines loaded, <0 if KO + */ + function load_cache_types_paiements() + { + global $langs; - else if ($input['type'] == 'onecolumn') - { - $more.='<tr><td colspan="3" align="left">'; - $more.=$input['value']; - $more.='</td></tr>'."\n"; - } - } - } - $more.='</table>'."\n"; - } + $num=count($this->cache_types_paiements); + if ($num > 0) return $num; // Cache already loaded - // JQUI method dialog is broken with jmobile, we use standard HTML. - // Note: When using dol_use_jmobile or no js, you must also check code for button use a GET url with action=xxx and check that you also output the confirm code when action=xxx - // See page product/card.php for example - if (! empty($conf->dol_use_jmobile)) $useajax=0; - if (empty($conf->use_javascript_ajax)) $useajax=0; + dol_syslog(__METHOD__, LOG_DEBUG); - if ($useajax) - { - $autoOpen=true; - $dialogconfirm='dialog-confirm'; - $button=''; - if (! is_numeric($useajax)) - { - $button=$useajax; - $useajax=1; - $autoOpen=false; - $dialogconfirm.='-'.$button; - } - $pageyes=$page.(preg_match('/\?/',$page)?'&':'?').'action='.$action.'&confirm=yes'; - $pageno=($useajax == 2 ? $page.(preg_match('/\?/',$page)?'&':'?').'confirm=no':''); - // Add input fields into list of fields to read during submit (inputok and inputko) - if (is_array($formquestion)) - { - foreach ($formquestion as $key => $input) - { - //print "xx ".$key." rr ".is_array($input)."<br>\n"; - if (is_array($input) && isset($input['name'])) array_push($inputok,$input['name']); - if (isset($input['inputko']) && $input['inputko'] == 1) array_push($inputko,$input['name']); - } - } - // Show JQuery confirm box. Note that global var $useglobalvars is used inside this template - $formconfirm.= '<div id="'.$dialogconfirm.'" title="'.dol_escape_htmltag($title).'" style="display: none;">'; - if (! empty($more)) { - $formconfirm.= '<div class="confirmquestions">'.$more.'</div>'; - } - $formconfirm.= ($question ? '<div class="confirmmessage">'.img_help('','').' '.$question . '</div>': ''); - $formconfirm.= '</div>'."\n"; + $this->cache_types_paiements = array(); - $formconfirm.= "\n<!-- begin ajax form_confirm page=".$page." -->\n"; - $formconfirm.= '<script type="text/javascript">'."\n"; - $formconfirm.= 'jQuery(document).ready(function() { - $(function() { - $( "#'.$dialogconfirm.'" ).dialog( - { - autoOpen: '.($autoOpen ? "true" : "false").','; - if ($newselectedchoice == 'no') - { - $formconfirm.=' - open: function() { - $(this).parent().find("button.ui-button:eq(2)").focus(); - },'; - } - $formconfirm.=' - resizable: false, - height: "'.$height.'", - width: "'.$width.'", - modal: true, - closeOnEscape: false, - buttons: { - "'.dol_escape_js($langs->transnoentities("Yes")).'": function() { - var options=""; - var inputok = '.json_encode($inputok).'; - var pageyes = "'.dol_escape_js(! empty($pageyes)?$pageyes:'').'"; - if (inputok.length>0) { - $.each(inputok, function(i, inputname) { - var more = ""; - if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; } - if ($("#" + inputname).attr("type") == "radio") { more = ":checked"; } - var inputvalue = $("#" + inputname + more).val(); - if (typeof inputvalue == "undefined") { inputvalue=""; } - options += "&" + inputname + "=" + inputvalue; - }); - } - var urljump = pageyes + (pageyes.indexOf("?") < 0 ? "?" : "") + options; - //alert(urljump); - if (pageyes.length > 0) { location.href = urljump; } - $(this).dialog("close"); - }, - "'.dol_escape_js($langs->transnoentities("No")).'": function() { - var options = ""; - var inputko = '.json_encode($inputko).'; - var pageno="'.dol_escape_js(! empty($pageno)?$pageno:'').'"; - if (inputko.length>0) { - $.each(inputko, function(i, inputname) { - var more = ""; - if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; } - var inputvalue = $("#" + inputname + more).val(); - if (typeof inputvalue == "undefined") { inputvalue=""; } - options += "&" + inputname + "=" + inputvalue; - }); - } - var urljump=pageno + (pageno.indexOf("?") < 0 ? "?" : "") + options; - //alert(urljump); - if (pageno.length > 0) { location.href = urljump; } - $(this).dialog("close"); - } - } - } - ); + $sql = "SELECT id, code, libelle as label, type, active"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement"; + $sql.= " WHERE entity = " . getEntity('c_paiement'); + //if ($active >= 0) $sql.= " AND active = ".$active; - var button = "'.$button.'"; - if (button.length > 0) { - $( "#" + button ).click(function() { - $("#'.$dialogconfirm.'").dialog("open"); - }); - } - }); - }); - </script>'; - $formconfirm.= "<!-- end ajax form_confirm -->\n"; - } - else - { - $formconfirm.= "\n<!-- begin form_confirm page=".$page." -->\n"; + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut + $label=($langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code)!=("PaymentTypeShort".$obj->code)?$langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code):($obj->label!='-'?$obj->label:'')); + $this->cache_types_paiements[$obj->id]['id'] =$obj->id; + $this->cache_types_paiements[$obj->id]['code'] =$obj->code; + $this->cache_types_paiements[$obj->id]['label']=$label; + $this->cache_types_paiements[$obj->id]['type'] =$obj->type; + $this->cache_types_paiements[$obj->id]['active'] =$obj->active; + $i++; + } - $formconfirm.= '<form method="POST" action="'.$page.'" class="notoptoleftroright">'."\n"; - $formconfirm.= '<input type="hidden" name="action" value="'.$action.'">'."\n"; - $formconfirm.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'."\n"; + $this->cache_types_paiements = dol_sort_array($this->cache_types_paiements, 'label', 'asc', 0, 0, 1); - $formconfirm.= '<table width="100%" class="valid">'."\n"; + return $num; + } + else + { + dol_print_error($this->db); + return -1; + } + } - // Line title - $formconfirm.= '<tr class="validtitre"><td class="validtitre" colspan="3">'.img_picto('','recent').' '.$title.'</td></tr>'."\n"; - // Line form fields - if ($more) - { - $formconfirm.='<tr class="valid"><td class="valid" colspan="3">'."\n"; - $formconfirm.=$more; - $formconfirm.='</td></tr>'."\n"; - } + /** + * Return list of payment modes. + * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. + * See instead to force the default value by the caller. + * + * @param int $selected Id of payment term to preselect by default + * @param string $htmlname Nom de la zone select + * @param int $filtertype Not used + * @param int $addempty Add an empty entry + * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info + * @param string $morecss Add more CSS on select tag + * @return void + */ + function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0, $noinfoadmin=0, $morecss='') + { + global $langs, $user, $conf; - // Line with question - $formconfirm.= '<tr class="valid">'; - $formconfirm.= '<td class="valid">'.$question.'</td>'; - $formconfirm.= '<td class="valid">'; - $formconfirm.= $this->selectyesno("confirm",$newselectedchoice); - $formconfirm.= '</td>'; - $formconfirm.= '<td class="valid" align="center"><input class="button valignmiddle" type="submit" value="'.$langs->trans("Validate").'"></td>'; - $formconfirm.= '</tr>'."\n"; - - $formconfirm.= '</table>'."\n"; - - $formconfirm.= "</form>\n"; - $formconfirm.= '<br>'; - - $formconfirm.= "<!-- end form_confirm -->\n"; - } - - return $formconfirm; - } - - - /** - * Show a form to select a project - * - * @param int $page Page - * @param int $socid Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id) - * @param int $selected Id pre-selected project - * @param string $htmlname Name of select field - * @param int $discard_closed Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable) - * @param int $maxlength Max length - * @param int $forcefocus Force focus on field (works with javascript only) - * @param int $nooutput No print is done. String is returned. - * @return string Return html content - */ - function form_project($page, $socid, $selected='', $htmlname='projectid', $discard_closed=0, $maxlength=20, $forcefocus=0, $nooutput=0) - { - global $langs; - - require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; - - $out=''; - - $formproject=new FormProjets($this->db); - - $langs->load("project"); - if ($htmlname != "none") - { - $out.="\n"; - $out.='<form method="post" action="'.$page.'">'; - $out.='<input type="hidden" name="action" value="classin">'; - $out.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $out.=$formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0, '', 1); - $out.='<input type="submit" class="button" value="'.$langs->trans("Modify").'">'; - $out.='</form>'; - } - else - { - if ($selected) - { - $projet = new Project($this->db); - $projet->fetch($selected); - //print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>'; - $out.=$projet->getNomUrl(0,'',1); - } - else - { - $out.=" "; - } - } - - if (empty($nooutput)) - { - print $out; - return ''; - } - return $out; - } - - /** - * Show a form to select payment conditions - * - * @param int $page Page - * @param string $selected Id condition pre-selectionne - * @param string $htmlname Name of select html field - * @param int $addempty Add empty entry - * @return void - */ - function form_conditions_reglement($page, $selected='', $htmlname='cond_reglement_id', $addempty=0) - { - global $langs; - if ($htmlname != "none") - { - print '<form method="post" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setconditions">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $this->select_conditions_paiements($selected,$htmlname,-1,$addempty); - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - if ($selected) - { - $this->load_cache_conditions_paiements(); - print $this->cache_conditions_paiements[$selected]['label']; - } else { - print " "; - } - } - } - - /** - * Show a form to select a delivery delay - * - * @param int $page Page - * @param string $selected Id condition pre-selectionne - * @param string $htmlname Name of select html field - * @param int $addempty Ajoute entree vide - * @return void - */ - function form_availability($page, $selected='', $htmlname='availability', $addempty=0) - { - global $langs; - if ($htmlname != "none") - { - print '<form method="post" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setavailability">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $this->selectAvailabilityDelay($selected,$htmlname,-1,$addempty); - print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - if ($selected) - { - $this->load_cache_availability(); - print $this->cache_availability[$selected]['label']; - } else { - print " "; - } - } - } + dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); - /** - * Output HTML form to select list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...) - * List found into table c_input_reason loaded by loadCacheInputReason - * - * @param string $page Page - * @param string $selected Id condition pre-selectionne - * @param string $htmlname Name of select html field - * @param int $addempty Add empty entry - * @return void - */ - function formInputReason($page, $selected='', $htmlname='demandreason', $addempty=0) - { - global $langs; - if ($htmlname != "none") - { - print '<form method="post" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setdemandreason">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $this->selectInputReason($selected,$htmlname,-1,$addempty); - print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - if ($selected) - { - $this->loadCacheInputReason(); - foreach ($this->cache_demand_reason as $key => $val) - { - if ($val['id'] == $selected) - { - print $val['label']; - break; - } - } - } else { - print " "; - } - } - } - - /** - * Show a form + html select a date - * - * @param string $page Page - * @param string $selected Date preselected - * @param string $htmlname Html name of date input fields or 'none' - * @param int $displayhour Display hour selector - * @param int $displaymin Display minutes selector - * @param int $nooutput 1=No print output, return string - * @return string - * @see select_date - */ - function form_date($page, $selected, $htmlname, $displayhour=0, $displaymin=0, $nooutput=0) - { - global $langs; - - $ret=''; - - if ($htmlname != "none") - { - $ret.='<form method="post" action="'.$page.'" name="form'.$htmlname.'">'; - $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">'; - $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">'; - $ret.='<tr><td>'; - $ret.=$this->select_date($selected,$htmlname,$displayhour,$displaymin,1,'form'.$htmlname,1,0,1); - $ret.='</td>'; - $ret.='<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>'; - $ret.='</tr></table></form>'; - } - else - { - if ($displayhour) $ret.=dol_print_date($selected,'dayhour'); - else $ret.=dol_print_date($selected,'day'); - } - - if (empty($nooutput)) print $ret; - return $ret; - } - - - /** - * Show a select form to choose a user - * - * @param string $page Page - * @param string $selected Id of user preselected - * @param string $htmlname Name of input html field. If 'none', we just output the user link. - * @param array $exclude List of users id to exclude - * @param array $include List of users id to include - * @return void - */ - function form_users($page, $selected='', $htmlname='userid', $exclude='', $include='') - { - global $langs; - - if ($htmlname != "none") - { - print '<form method="POST" action="'.$page.'" name="form'.$htmlname.'">'; - print '<input type="hidden" name="action" value="set'.$htmlname.'">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print $this->select_dolusers($selected,$htmlname,1,$exclude,0,$include); - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - if ($selected) - { - require_once DOL_DOCUMENT_ROOT .'/user/class/user.class.php'; - $theuser=new User($this->db); - $theuser->fetch($selected); - print $theuser->getNomUrl(1); - } else { - print " "; - } - } - } - - - /** - * Show form with payment mode - * - * @param string $page Page - * @param int $selected Id mode pre-selectionne - * @param string $htmlname Name of select html field - * @param string $filtertype To filter on field type in llx_c_paiement (array('code'=>xx,'label'=>zz)) - * @param int $active Active or not, -1 = all - * @return void - */ - function form_modes_reglement($page, $selected='', $htmlname='mode_reglement_id', $filtertype='', $active=1) - { - global $langs; - if ($htmlname != "none") - { - print '<form method="POST" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setmode">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - $this->select_types_paiements($selected,$htmlname,$filtertype,0,0,0,0,$active); - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - if ($selected) - { - $this->load_cache_types_paiements(); - print $this->cache_types_paiements[$selected]['label']; - } else { - print " "; - } - } - } + $this->load_cache_conditions_paiements(); + + // Set default value if not already set by caller + if (empty($selected) && ! empty($conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID)) $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID; + + print '<select id="'.$htmlname.'" class="flat selectpaymentterms'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'">'; + if ($addempty) print '<option value="0"> </option>'; + foreach($this->cache_conditions_paiements as $id => $arrayconditions) + { + if ($selected == $id) + { + print '<option value="'.$id.'" selected>'; + } + else + { + print '<option value="'.$id.'">'; + } + print $arrayconditions['label']; + print '</option>'; + } + print '</select>'; + if ($user->admin && empty($noinfoadmin)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + } - /** - * Show form with multicurrency code - * - * @param string $page Page - * @param string $selected code pre-selectionne - * @param string $htmlname Name of select html field - * @return void - */ - function form_multicurrency_code($page, $selected='', $htmlname='multicurrency_code') - { - global $langs; - if ($htmlname != "none") - { - print '<form method="POST" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setmulticurrencycode">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print $this->selectMultiCurrency($selected, $htmlname, 0); - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - dol_include_once('/core/lib/company.lib.php'); - print !empty($selected) ? currency_name($selected,1) : ' '; - } - } /** - * Show form with multicurrency rate - * - * @param string $page Page - * @param double $rate Current rate - * @param string $htmlname Name of select html field - * @param string $currency Currency code to explain the rate - * @return void - */ - function form_multicurrency_rate($page, $rate='', $htmlname='multicurrency_tx', $currency='') - { - global $langs, $mysoc, $conf; - - if ($htmlname != "none") - { - print '<form method="POST" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setmulticurrencyrate">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="text" name="'.$htmlname.'" value="'.(!empty($rate) ? price($rate) : 1).'" size="10" /> '; - print '<select name="calculation_mode">'; - print '<option value="1">'.$currency.' > '.$conf->currency.'</option>'; - print '<option value="2">'.$conf->currency.' > '.$currency.'</option>'; - print '</select> '; - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - if (! empty($rate)) - { - print price($rate, 1, $langs, 1, 0); - if ($currency && $rate != 1) print ' ('.price($rate, 1, $langs, 1, 0).' '.$currency.' = 1 '.$conf->currency.')'; - } - else - { - print 1; - } - } - } - - - /** - * Show a select box with available absolute discounts - * - * @param string $page Page URL where form is shown - * @param int $selected Value pre-selected - * @param string $htmlname Name of SELECT component. If 'none', not changeable. Example 'remise_id'. - * @param int $socid Third party id - * @param float $amount Total amount available - * @param string $filter SQL filter on discounts - * @param int $maxvalue Max value for lines that can be selected - * @param string $more More string to add - * @param int $hidelist 1=Hide list - * @return void - */ - function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0) - { - global $conf,$langs; - if ($htmlname != "none") - { - print '<form method="post" action="'.$page.'">'; - print '<input type="hidden" name="action" value="setabsolutediscount">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<div class="inline-block">'; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) - { - if (! $filter || $filter=="fk_facture_source IS NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); // If we want deposit to be substracted to payments only and not to total of final invoice - else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency)); - } - else - { - if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); - else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency)); - } - if (empty($hidelist)) print ': '; - print '</div>'; - if (empty($hidelist)) - { - print '<div class="inline-block" style="padding-right: 10px">'; - $newfilter='fk_facture IS NULL AND fk_facture_line IS NULL'; // Remises disponibles - if ($filter) $newfilter.=' AND ('.$filter.')'; - $nbqualifiedlines=$this->select_remises($selected,$htmlname,$newfilter,$socid,$maxvalue); - if ($nbqualifiedlines > 0) - { - print ' <input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("UseLine")).'"'; - if ($filter && $filter != "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')") print ' title="'.$langs->trans("UseCreditNoteInInvoicePayment").'"'; - print '>'; - } - print '</div>'; - } - if ($more) - { - print '<div class="inline-block">'; - print $more; - print '</div>'; - } - print '</form>'; - } - else - { - if ($selected) - { - print $selected; - } - else - { - print "0"; - } - } - } - - - /** - * Show forms to select a contact - * - * @param string $page Page - * @param Societe $societe Filter on third party - * @param int $selected Id contact pre-selectionne - * @param string $htmlname Name of HTML select. If 'none', we just show contact link. - * @return void - */ - function form_contacts($page, $societe, $selected='', $htmlname='contactid') - { - global $langs, $conf; - - if ($htmlname != "none") - { - print '<form method="post" action="'.$page.'">'; - print '<input type="hidden" name="action" value="set_contact">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">'; - print '<tr><td>'; - $num=$this->select_contacts($societe->id, $selected, $htmlname); - if ($num==0) - { - $addcontact = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress")); - print '<a href="'.DOL_URL_ROOT.'/contact/card.php?socid='.$societe->id.'&action=create&backtoreferer=1">'.$addcontact.'</a>'; - } - print '</td>'; - print '<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>'; - print '</tr></table></form>'; - } - else - { - if ($selected) - { - require_once DOL_DOCUMENT_ROOT .'/contact/class/contact.class.php'; - $contact=new Contact($this->db); - $contact->fetch($selected); - print $contact->getFullName($langs); - } else { - print " "; - } - } - } - - /** - * Output html select to select thirdparty - * - * @param string $page Page - * @param string $selected Id preselected - * @param string $htmlname Name of HTML select - * @param string $filter optional filters criteras - * @param int $showempty Add an empty field - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @return void - */ - function form_thirdparty($page, $selected='', $htmlname='socid', $filter='',$showempty=0, $showtype=0, $forcecombo=0, $events=array()) - { - global $langs; - - if ($htmlname != "none") - { - print '<form method="post" action="'.$page.'">'; - print '<input type="hidden" name="action" value="set_thirdparty">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events); - print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; - print '</form>'; - } - else - { - if ($selected) - { - require_once DOL_DOCUMENT_ROOT .'/societe/class/societe.class.php'; - $soc = new Societe($this->db); - $soc->fetch($selected); - print $soc->getNomUrl($langs); - } - else - { - print " "; - } - } - } - - /** - * Retourne la liste des devises, dans la langue de l'utilisateur - * - * @param string $selected preselected currency code - * @param string $htmlname name of HTML select list - * @return void - */ - function select_currency($selected='',$htmlname='currency_id') - { - print $this->selectCurrency($selected,$htmlname); - } - - /** - * Retourne la liste des devises, dans la langue de l'utilisateur - * - * @param string $selected preselected currency code - * @param string $htmlname name of HTML select list - * @return string - */ - function selectCurrency($selected='',$htmlname='currency_id') + * Return list of payment methods + * + * @param string $selected Id du mode de paiement pre-selectionne + * @param string $htmlname Nom de la zone select + * @param string $filtertype To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz)) + * @param int $format 0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code + * @param int $empty 1=peut etre vide, 0 sinon + * @param int $noadmininfo 0=Add admin info, 1=Disable admin info + * @param int $maxlength Max length of label + * @param int $active Active or not, -1 = all + * @param string $morecss Add more CSS on select tag + * @return void + */ + function select_types_paiements($selected='', $htmlname='paiementtype', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $active=1, $morecss='') { - global $conf,$langs,$user; + global $langs,$user; - $langs->loadCacheCurrencies(''); + dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG); - $out=''; + $filterarray=array(); + if ($filtertype == 'CRDT') $filterarray=array(0,2,3); + elseif ($filtertype == 'DBIT') $filterarray=array(1,2,3); + elseif ($filtertype != '' && $filtertype != '-1') $filterarray=explode(',',$filtertype); - if ($selected=='euro' || $selected=='euros') $selected='EUR'; // Pour compatibilite + $this->load_cache_types_paiements(); - $out.= '<select class="flat maxwidth200onsmartphone minwidth300" name="'.$htmlname.'" id="'.$htmlname.'">'; - foreach ($langs->cache_currencies as $code_iso => $currency) + print '<select id="select'.$htmlname.'" class="flat selectpaymenttypes'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'">'; + if ($empty) print '<option value=""> </option>'; + foreach($this->cache_types_paiements as $id => $arraytypes) { - if ($selected && $selected == $code_iso) + // If not good status + if ($active >= 0 && $arraytypes['active'] != $active) continue; + + // On passe si on a demande de filtrer sur des modes de paiments particuliers + if (count($filterarray) && ! in_array($arraytypes['type'],$filterarray)) continue; + + // We discard empty line if showempty is on because an empty line has already been output. + if ($empty && empty($arraytypes['code'])) continue; + + if ($format == 0) print '<option value="'.$id.'"'; + if ($format == 1) print '<option value="'.$arraytypes['code'].'"'; + if ($format == 2) print '<option value="'.$arraytypes['code'].'"'; + if ($format == 3) print '<option value="'.$id.'"'; + // Si selected est text, on compare avec code, sinon avec id + if (preg_match('/[a-z]/i', $selected) && $selected == $arraytypes['code']) print ' selected'; + elseif ($selected == $id) print ' selected'; + print '>'; + if ($format == 0) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']); + if ($format == 1) $value=$arraytypes['code']; + if ($format == 2) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']); + if ($format == 3) $value=$arraytypes['code']; + print $value?$value:' '; + print '</option>'; + } + print '</select>'; + if ($user->admin && ! $noadmininfo) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + } + + + /** + * Selection HT or TTC + * + * @param string $selected Id pre-selectionne + * @param string $htmlname Nom de la zone select + * @return string Code of HTML select to chose tax or not + */ + function selectPriceBaseType($selected='',$htmlname='price_base_type') + { + global $langs; + + $return=''; + + $return.= '<select class="flat" name="'.$htmlname.'">'; + $options = array( + 'HT'=>$langs->trans("HT"), + 'TTC'=>$langs->trans("TTC") + ); + foreach($options as $id => $value) + { + if ($selected == $id) { - $out.= '<option value="'.$code_iso.'" selected>'; + $return.= '<option value="'.$id.'" selected>'.$value; } else { - $out.= '<option value="'.$code_iso.'">'; + $return.= '<option value="'.$id.'">'.$value; + } + $return.= '</option>'; + } + $return.= '</select>'; + + return $return; + } + + /** + * Return a HTML select list of shipping mode + * + * @param string $selected Id shipping mode pre-selected + * @param string $htmlname Name of select zone + * @param string $filtre To filter list + * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @param string $moreattrib To add more attribute on select + * @return void + */ + function selectShippingMethod($selected='',$htmlname='shipping_method_id',$filtre='',$useempty=0,$moreattrib='') + { + global $langs, $conf, $user; + + $langs->load("admin"); + $langs->load("deliveries"); + + $sql = "SELECT rowid, code, libelle as label"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode"; + $sql.= " WHERE active > 0"; + if ($filtre) $sql.=" AND ".$filtre; + $sql.= " ORDER BY libelle ASC"; + + dol_syslog(get_class($this)."::selectShippingMode", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) { + $num = $this->db->num_rows($result); + $i = 0; + if ($num) { + print '<select id="select'.$htmlname.'" class="flat selectshippingmethod" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>'; + if ($useempty == 1 || ($useempty == 2 && $num > 1)) { + print '<option value="-1"> </option>'; + } + while ($i < $num) { + $obj = $this->db->fetch_object($result); + if ($selected == $obj->rowid) { + print '<option value="'.$obj->rowid.'" selected>'; + } else { + print '<option value="'.$obj->rowid.'">'; + } + print ($langs->trans("SendingMethod".strtoupper($obj->code)) != "SendingMethod".strtoupper($obj->code)) ? $langs->trans("SendingMethod".strtoupper($obj->code)) : $obj->label; + print '</option>'; + $i++; + } + print "</select>"; + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + } else { + print $langs->trans("NoShippingMethodDefined"); + } + } else { + dol_print_error($this->db); + } + } + + /** + * Display form to select shipping mode + * + * @param string $page Page + * @param int $selected Id of shipping mode + * @param string $htmlname Name of select html field + * @param int $addempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @return void + */ + function formSelectShippingMethod($page, $selected='', $htmlname='shipping_method_id', $addempty=0) + { + global $langs, $db; + + $langs->load("deliveries"); + + if ($htmlname != "none") { + print '<form method="POST" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setshippingmethod">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $this->selectShippingMethod($selected, $htmlname, '', $addempty); + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } else { + if ($selected) { + $code=$langs->getLabelFromKey($db, $selected, 'c_shipment_mode', 'rowid', 'code'); + print $langs->trans("SendingMethod".strtoupper($code)); + } else { + print " "; + } + } + } + + /** + * Creates HTML last in cycle situation invoices selector + * + * @param string $selected Preselected ID + * @param int $socid Company ID + * + * @return string HTML select + */ + function selectSituationInvoices($selected = '', $socid = 0) + { + global $langs; + + $langs->load('bills'); + + $opt = '<option value ="" selected></option>'; + $sql = 'SELECT rowid, facnumber, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1'; + $sql.= ' ORDER by situation_cycle_ref, situation_counter desc'; + $resql = $this->db->query($sql); + if ($resql && $this->db->num_rows($resql) > 0) { + // Last seen cycle + $ref = 0; + while ($res = $this->db->fetch_array($resql, MYSQL_NUM)) { + //Same company ? + if ($socid == $res[5]) { + //Same cycle ? + if ($res[2] != $ref) { + // Just seen this cycle + $ref = $res[2]; + //not final ? + if ($res[4] != 1) { + //Not prov? + if (substr($res[1], 1, 4) != 'PROV') { + if ($selected == $res[0]) { + $opt .= '<option value="' . $res[0] . '" selected>' . $res[1] . '</option>'; + } else { + $opt .= '<option value="' . $res[0] . '">' . $res[1] . '</option>'; + } + } + } + } + } + } + } + else + { + dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR); + } + if ($opt == '<option value ="" selected></option>') + { + $opt = '<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>'; + } + return $opt; + } + + /** + * Creates HTML units selector (code => label) + * + * @param string $selected Preselected Unit ID + * @param string $htmlname Select name + * @param int $showempty Add a nempty line + * @return string HTML select + */ + function selectUnits($selected = '', $htmlname = 'units', $showempty=0) + { + global $langs; + + $langs->load('products'); + + $return= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'">'; + + $sql = 'SELECT rowid, label, code from '.MAIN_DB_PREFIX.'c_units'; + $sql.= ' WHERE active > 0'; + + $resql = $this->db->query($sql); + if($resql && $this->db->num_rows($resql) > 0) + { + if ($showempty) $return .= '<option value="none"></option>'; + + while($res = $this->db->fetch_object($resql)) + { + if ($selected == $res->rowid) + { + $return.='<option value="'.$res->rowid.'" selected>'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>'; + } + else + { + $return.='<option value="'.$res->rowid.'">'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>'; + } + } + $return.='</select>'; + } + return $return; + } + + /** + * Return a HTML select list of bank accounts + * + * @param string $selected Id account pre-selected + * @param string $htmlname Name of select zone + * @param int $statut Status of searched accounts (0=open, 1=closed, 2=both) + * @param string $filtre To filter list + * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @param string $moreattrib To add more attribute on select + * @param int $showcurrency Show currency in label + * @return void + */ + function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='',$showcurrency=0) + { + global $langs, $conf; + + $langs->load("admin"); + + $sql = "SELECT rowid, label, bank, clos as status, currency_code"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; + $sql.= " WHERE entity IN (".getEntity('bank_account').")"; + if ($statut != 2) $sql.= " AND clos = '".$statut."'"; + if ($filtre) $sql.=" AND ".$filtre; + $sql.= " ORDER BY label"; + + dol_syslog(get_class($this)."::select_comptes", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + if ($num) + { + print '<select id="select'.$htmlname.'" class="flat selectbankaccount" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>'; + if ($useempty == 1 || ($useempty == 2 && $num > 1)) + { + print '<option value="-1"> </option>'; + } + + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + if ($selected == $obj->rowid) + { + print '<option value="'.$obj->rowid.'" selected>'; + } + else + { + print '<option value="'.$obj->rowid.'">'; + } + print trim($obj->label); + if ($showcurrency) print ' ('.$obj->currency_code.')'; + if ($statut == 2 && $obj->status == 1) print ' ('.$langs->trans("Closed").')'; + print '</option>'; + $i++; + } + print "</select>"; + } + else + { + print $langs->trans("NoActiveBankAccountDefined"); + } + } + else { + dol_print_error($this->db); + } + } + + /** + * Display form to select bank account + * + * @param string $page Page + * @param int $selected Id of bank account + * @param string $htmlname Name of select html field + * @param int $addempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @return void + */ + function formSelectAccount($page, $selected='', $htmlname='fk_account', $addempty=0) + { + global $langs; + if ($htmlname != "none") { + print '<form method="POST" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setbankaccount">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $this->select_comptes($selected, $htmlname, 0, '', $addempty); + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } else { + + $langs->load('banks'); + + if ($selected) { + require_once DOL_DOCUMENT_ROOT .'/compta/bank/class/account.class.php'; + $bankstatic=new Account($this->db); + $bankstatic->fetch($selected); + print $bankstatic->getNomUrl(1); + } else { + print " "; + } + } + } + + /** + * Return list of categories having choosed type + * + * @param string|int $type Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated. + * @param string $selected Id of category preselected or 'auto' (autoselect category if there is only one element) + * @param string $htmlname HTML field name + * @param int $maxlength Maximum length for labels + * @param int $excludeafterid Exclude all categories after this leaf in category tree. + * @param int $outputmode 0=HTML select string, 1=Array + * @return string + * @see select_categories + */ + function select_all_categories($type, $selected='', $htmlname="parent", $maxlength=64, $excludeafterid=0, $outputmode=0) + { + global $conf, $langs; + $langs->load("categories"); + + include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + + // For backward compatibility + if (is_numeric($type)) + { + dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING); + } + + if ($type === Categorie::TYPE_BANK_LINE) + { + // TODO Move this into common category feature + $categids=array(); + $sql = "SELECT c.label, c.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank_categ as c"; + $sql.= " WHERE entity = ".$conf->entity; + $sql.= " ORDER BY c.label"; + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + if ($objp) $cate_arbo[$objp->rowid]=array('id'=>$objp->rowid, 'fulllabel'=>$objp->label); + $i++; + } + $this->db->free($result); + } + else dol_print_error($this->db); + } + else + { + $cat = new Categorie($this->db); + $cate_arbo = $cat->get_full_arbo($type, $excludeafterid); + } + + $output = '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">'; + $outarray=array(); + if (is_array($cate_arbo)) + { + if (! count($cate_arbo)) $output.= '<option value="-1" disabled>'.$langs->trans("NoCategoriesDefined").'</option>'; + else + { + $output.= '<option value="-1"> </option>'; + foreach($cate_arbo as $key => $value) + { + if ($cate_arbo[$key]['id'] == $selected || ($selected == 'auto' && count($cate_arbo) == 1)) + { + $add = 'selected '; + } + else + { + $add = ''; + } + $output.= '<option '.$add.'value="'.$cate_arbo[$key]['id'].'">'.dol_trunc($cate_arbo[$key]['fulllabel'],$maxlength,'middle').'</option>'; + + $outarray[$cate_arbo[$key]['id']] = $cate_arbo[$key]['fulllabel']; + } + } + } + $output.= '</select>'; + $output.= "\n"; + + if ($outputmode) return $outarray; + return $output; + } + + /** + * Show a confirmation HTML form or AJAX popup + * + * @param string $page Url of page to call if confirmation is OK + * @param string $title Title + * @param string $question Question + * @param string $action Action + * @param array $formquestion An array with forms complementary inputs + * @param string $selectedchoice "" or "no" or "yes" + * @param int $useajax 0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=preoutput confirm box with div id=dialog-confirm-xxx + * @param int $height Force height of box + * @param int $width Force width of box + * @return void + * @deprecated + * @see formconfirm() + */ + function form_confirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=170, $width=500) + { + print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width); + } + + /** + * Show a confirmation HTML form or AJAX popup. + * Easiest way to use this is with useajax=1. + * If you use useajax='xxx', you must also add jquery code to trigger opening of box (with correct parameters) + * just after calling this method. For example: + * print '<script type="text/javascript">'."\n"; + * print 'jQuery(document).ready(function() {'."\n"; + * print 'jQuery(".xxxlink").click(function(e) { jQuery("#aparamid").val(jQuery(this).attr("rel")); jQuery("#dialog-confirm-xxx").dialog("open"); return false; });'."\n"; + * print '});'."\n"; + * print '</script>'."\n"; + * + * @param string $page Url of page to call if confirmation is OK + * @param string $title Title + * @param string $question Question + * @param string $action Action + * @param array $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , )) + * @param string $selectedchoice "" or "no" or "yes" + * @param int $useajax 0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx + * @param int $height Force height of box + * @param int $width Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones. + * @return string HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form + */ + function formconfirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=200, $width=500) + { + global $langs,$conf; + global $useglobalvars; + + $more=''; + $formconfirm=''; + $inputok=array(); + $inputko=array(); + + // Clean parameters + $newselectedchoice=empty($selectedchoice)?"no":$selectedchoice; + if ($conf->browser->layout == 'phone') $width='95%'; + + if (is_array($formquestion) && ! empty($formquestion)) + { + // First add hidden fields and value + foreach ($formquestion as $key => $input) + { + if (is_array($input) && ! empty($input)) + { + if ($input['type'] == 'hidden') + { + $more.='<input type="hidden" id="'.$input['name'].'" name="'.$input['name'].'" value="'.dol_escape_htmltag($input['value']).'">'."\n"; + } + } + } + + // Now add questions + $more.='<table class="paddingtopbottomonly" width="100%">'."\n"; + $more.='<tr><td colspan="3">'.(! empty($formquestion['text'])?$formquestion['text']:'').'</td></tr>'."\n"; + foreach ($formquestion as $key => $input) + { + if (is_array($input) && ! empty($input)) + { + $size=(! empty($input['size'])?' size="'.$input['size'].'"':''); + + if ($input['type'] == 'text') + { + $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="text" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n"; + } + else if ($input['type'] == 'password') + { + $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="password" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n"; + } + else if ($input['type'] == 'select') + { + $more.='<tr><td>'; + if (! empty($input['label'])) $more.=$input['label'].'</td><td valign="top" colspan="2" align="left">'; + $more.=$this->selectarray($input['name'],$input['values'],$input['default'],1); + $more.='</td></tr>'."\n"; + } + else if ($input['type'] == 'checkbox') + { + $more.='<tr>'; + $more.='<td>'.$input['label'].' </td><td align="left">'; + $more.='<input type="checkbox" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'; + if (! is_bool($input['value']) && $input['value'] != 'false') $more.=' checked'; + if (is_bool($input['value']) && $input['value']) $more.=' checked'; + if (isset($input['disabled'])) $more.=' disabled'; + $more.=' /></td>'; + $more.='<td align="left"> </td>'; + $more.='</tr>'."\n"; + } + else if ($input['type'] == 'radio') + { + $i=0; + foreach($input['values'] as $selkey => $selval) + { + $more.='<tr>'; + if ($i==0) $more.='<td class="tdtop">'.$input['label'].'</td>'; + else $more.='<td> </td>'; + $more.='<td width="20"><input type="radio" class="flat" id="'.$input['name'].'" name="'.$input['name'].'" value="'.$selkey.'"'; + if ($input['disabled']) $more.=' disabled'; + $more.=' /></td>'; + $more.='<td align="left">'; + $more.=$selval; + $more.='</td></tr>'."\n"; + $i++; + } + } + else if ($input['type'] == 'date') + { + $more.='<tr><td>'.$input['label'].'</td>'; + $more.='<td colspan="2" align="left">'; + $more.=$this->select_date($input['value'],$input['name'],0,0,0,'',1,0,1); + $more.='</td></tr>'."\n"; + $formquestion[] = array('name'=>$input['name'].'day'); + $formquestion[] = array('name'=>$input['name'].'month'); + $formquestion[] = array('name'=>$input['name'].'year'); + $formquestion[] = array('name'=>$input['name'].'hour'); + $formquestion[] = array('name'=>$input['name'].'min'); + } + else if ($input['type'] == 'other') + { + $more.='<tr><td>'; + if (! empty($input['label'])) $more.=$input['label'].'</td><td colspan="2" align="left">'; + $more.=$input['value']; + $more.='</td></tr>'."\n"; + } + + else if ($input['type'] == 'onecolumn') + { + $more.='<tr><td colspan="3" align="left">'; + $more.=$input['value']; + $more.='</td></tr>'."\n"; + } + } + } + $more.='</table>'."\n"; + } + + // JQUI method dialog is broken with jmobile, we use standard HTML. + // Note: When using dol_use_jmobile or no js, you must also check code for button use a GET url with action=xxx and check that you also output the confirm code when action=xxx + // See page product/card.php for example + if (! empty($conf->dol_use_jmobile)) $useajax=0; + if (empty($conf->use_javascript_ajax)) $useajax=0; + + if ($useajax) + { + $autoOpen=true; + $dialogconfirm='dialog-confirm'; + $button=''; + if (! is_numeric($useajax)) + { + $button=$useajax; + $useajax=1; + $autoOpen=false; + $dialogconfirm.='-'.$button; + } + $pageyes=$page.(preg_match('/\?/',$page)?'&':'?').'action='.$action.'&confirm=yes'; + $pageno=($useajax == 2 ? $page.(preg_match('/\?/',$page)?'&':'?').'confirm=no':''); + // Add input fields into list of fields to read during submit (inputok and inputko) + if (is_array($formquestion)) + { + foreach ($formquestion as $key => $input) + { + //print "xx ".$key." rr ".is_array($input)."<br>\n"; + if (is_array($input) && isset($input['name'])) array_push($inputok,$input['name']); + if (isset($input['inputko']) && $input['inputko'] == 1) array_push($inputko,$input['name']); + } + } + // Show JQuery confirm box. Note that global var $useglobalvars is used inside this template + $formconfirm.= '<div id="'.$dialogconfirm.'" title="'.dol_escape_htmltag($title).'" style="display: none;">'; + if (! empty($more)) { + $formconfirm.= '<div class="confirmquestions">'.$more.'</div>'; + } + $formconfirm.= ($question ? '<div class="confirmmessage">'.img_help('','').' '.$question . '</div>': ''); + $formconfirm.= '</div>'."\n"; + + $formconfirm.= "\n<!-- begin ajax form_confirm page=".$page." -->\n"; + $formconfirm.= '<script type="text/javascript">'."\n"; + $formconfirm.= 'jQuery(document).ready(function() { + $(function() { + $( "#'.$dialogconfirm.'" ).dialog( + { + autoOpen: '.($autoOpen ? "true" : "false").','; + if ($newselectedchoice == 'no') + { + $formconfirm.=' + open: function() { + $(this).parent().find("button.ui-button:eq(2)").focus(); + },'; + } + $formconfirm.=' + resizable: false, + height: "'.$height.'", + width: "'.$width.'", + modal: true, + closeOnEscape: false, + buttons: { + "'.dol_escape_js($langs->transnoentities("Yes")).'": function() { + var options=""; + var inputok = '.json_encode($inputok).'; + var pageyes = "'.dol_escape_js(! empty($pageyes)?$pageyes:'').'"; + if (inputok.length>0) { + $.each(inputok, function(i, inputname) { + var more = ""; + if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; } + if ($("#" + inputname).attr("type") == "radio") { more = ":checked"; } + var inputvalue = $("#" + inputname + more).val(); + if (typeof inputvalue == "undefined") { inputvalue=""; } + options += "&" + inputname + "=" + inputvalue; + }); + } + var urljump = pageyes + (pageyes.indexOf("?") < 0 ? "?" : "") + options; + //alert(urljump); + if (pageyes.length > 0) { location.href = urljump; } + $(this).dialog("close"); + }, + "'.dol_escape_js($langs->transnoentities("No")).'": function() { + var options = ""; + var inputko = '.json_encode($inputko).'; + var pageno="'.dol_escape_js(! empty($pageno)?$pageno:'').'"; + if (inputko.length>0) { + $.each(inputko, function(i, inputname) { + var more = ""; + if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; } + var inputvalue = $("#" + inputname + more).val(); + if (typeof inputvalue == "undefined") { inputvalue=""; } + options += "&" + inputname + "=" + inputvalue; + }); + } + var urljump=pageno + (pageno.indexOf("?") < 0 ? "?" : "") + options; + //alert(urljump); + if (pageno.length > 0) { location.href = urljump; } + $(this).dialog("close"); + } + } + } + ); + + var button = "'.$button.'"; + if (button.length > 0) { + $( "#" + button ).click(function() { + $("#'.$dialogconfirm.'").dialog("open"); + }); + } + }); + }); + </script>'; + $formconfirm.= "<!-- end ajax form_confirm -->\n"; + } + else + { + $formconfirm.= "\n<!-- begin form_confirm page=".$page." -->\n"; + + $formconfirm.= '<form method="POST" action="'.$page.'" class="notoptoleftroright">'."\n"; + $formconfirm.= '<input type="hidden" name="action" value="'.$action.'">'."\n"; + $formconfirm.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'."\n"; + + $formconfirm.= '<table width="100%" class="valid">'."\n"; + + // Line title + $formconfirm.= '<tr class="validtitre"><td class="validtitre" colspan="3">'.img_picto('','recent').' '.$title.'</td></tr>'."\n"; + + // Line form fields + if ($more) + { + $formconfirm.='<tr class="valid"><td class="valid" colspan="3">'."\n"; + $formconfirm.=$more; + $formconfirm.='</td></tr>'."\n"; + } + + // Line with question + $formconfirm.= '<tr class="valid">'; + $formconfirm.= '<td class="valid">'.$question.'</td>'; + $formconfirm.= '<td class="valid">'; + $formconfirm.= $this->selectyesno("confirm",$newselectedchoice); + $formconfirm.= '</td>'; + $formconfirm.= '<td class="valid" align="center"><input class="button valignmiddle" type="submit" value="'.$langs->trans("Validate").'"></td>'; + $formconfirm.= '</tr>'."\n"; + + $formconfirm.= '</table>'."\n"; + + $formconfirm.= "</form>\n"; + $formconfirm.= '<br>'; + + $formconfirm.= "<!-- end form_confirm -->\n"; + } + + return $formconfirm; + } + + + /** + * Show a form to select a project + * + * @param int $page Page + * @param int $socid Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id) + * @param int $selected Id pre-selected project + * @param string $htmlname Name of select field + * @param int $discard_closed Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable) + * @param int $maxlength Max length + * @param int $forcefocus Force focus on field (works with javascript only) + * @param int $nooutput No print is done. String is returned. + * @return string Return html content + */ + function form_project($page, $socid, $selected='', $htmlname='projectid', $discard_closed=0, $maxlength=20, $forcefocus=0, $nooutput=0) + { + global $langs; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; + + $out=''; + + $formproject=new FormProjets($this->db); + + $langs->load("project"); + if ($htmlname != "none") + { + $out.="\n"; + $out.='<form method="post" action="'.$page.'">'; + $out.='<input type="hidden" name="action" value="classin">'; + $out.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $out.=$formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0, '', 1); + $out.='<input type="submit" class="button" value="'.$langs->trans("Modify").'">'; + $out.='</form>'; + } + else + { + if ($selected) + { + $projet = new Project($this->db); + $projet->fetch($selected); + //print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>'; + $out.=$projet->getNomUrl(0,'',1); + } + else + { + $out.=" "; + } + } + + if (empty($nooutput)) + { + print $out; + return ''; + } + return $out; + } + + /** + * Show a form to select payment conditions + * + * @param int $page Page + * @param string $selected Id condition pre-selectionne + * @param string $htmlname Name of select html field + * @param int $addempty Add empty entry + * @return void + */ + function form_conditions_reglement($page, $selected='', $htmlname='cond_reglement_id', $addempty=0) + { + global $langs; + if ($htmlname != "none") + { + print '<form method="post" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setconditions">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $this->select_conditions_paiements($selected,$htmlname,-1,$addempty); + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + if ($selected) + { + $this->load_cache_conditions_paiements(); + print $this->cache_conditions_paiements[$selected]['label']; + } else { + print " "; + } + } + } + + /** + * Show a form to select a delivery delay + * + * @param int $page Page + * @param string $selected Id condition pre-selectionne + * @param string $htmlname Name of select html field + * @param int $addempty Ajoute entree vide + * @return void + */ + function form_availability($page, $selected='', $htmlname='availability', $addempty=0) + { + global $langs; + if ($htmlname != "none") + { + print '<form method="post" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setavailability">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $this->selectAvailabilityDelay($selected,$htmlname,-1,$addempty); + print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + if ($selected) + { + $this->load_cache_availability(); + print $this->cache_availability[$selected]['label']; + } else { + print " "; + } + } + } + + /** + * Output HTML form to select list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...) + * List found into table c_input_reason loaded by loadCacheInputReason + * + * @param string $page Page + * @param string $selected Id condition pre-selectionne + * @param string $htmlname Name of select html field + * @param int $addempty Add empty entry + * @return void + */ + function formInputReason($page, $selected='', $htmlname='demandreason', $addempty=0) + { + global $langs; + if ($htmlname != "none") + { + print '<form method="post" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setdemandreason">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $this->selectInputReason($selected,$htmlname,-1,$addempty); + print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + if ($selected) + { + $this->loadCacheInputReason(); + foreach ($this->cache_demand_reason as $key => $val) + { + if ($val['id'] == $selected) + { + print $val['label']; + break; + } + } + } else { + print " "; + } + } + } + + /** + * Show a form + html select a date + * + * @param string $page Page + * @param string $selected Date preselected + * @param string $htmlname Html name of date input fields or 'none' + * @param int $displayhour Display hour selector + * @param int $displaymin Display minutes selector + * @param int $nooutput 1=No print output, return string + * @return string + * @see select_date + */ + function form_date($page, $selected, $htmlname, $displayhour=0, $displaymin=0, $nooutput=0) + { + global $langs; + + $ret=''; + + if ($htmlname != "none") + { + $ret.='<form method="post" action="'.$page.'" name="form'.$htmlname.'">'; + $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">'; + $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">'; + $ret.='<tr><td>'; + $ret.=$this->select_date($selected,$htmlname,$displayhour,$displaymin,1,'form'.$htmlname,1,0,1); + $ret.='</td>'; + $ret.='<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>'; + $ret.='</tr></table></form>'; + } + else + { + if ($displayhour) $ret.=dol_print_date($selected,'dayhour'); + else $ret.=dol_print_date($selected,'day'); + } + + if (empty($nooutput)) print $ret; + return $ret; + } + + + /** + * Show a select form to choose a user + * + * @param string $page Page + * @param string $selected Id of user preselected + * @param string $htmlname Name of input html field. If 'none', we just output the user link. + * @param array $exclude List of users id to exclude + * @param array $include List of users id to include + * @return void + */ + function form_users($page, $selected='', $htmlname='userid', $exclude='', $include='') + { + global $langs; + + if ($htmlname != "none") + { + print '<form method="POST" action="'.$page.'" name="form'.$htmlname.'">'; + print '<input type="hidden" name="action" value="set'.$htmlname.'">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print $this->select_dolusers($selected,$htmlname,1,$exclude,0,$include); + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + if ($selected) + { + require_once DOL_DOCUMENT_ROOT .'/user/class/user.class.php'; + $theuser=new User($this->db); + $theuser->fetch($selected); + print $theuser->getNomUrl(1); + } else { + print " "; + } + } + } + + + /** + * Show form with payment mode + * + * @param string $page Page + * @param int $selected Id mode pre-selectionne + * @param string $htmlname Name of select html field + * @param string $filtertype To filter on field type in llx_c_paiement (array('code'=>xx,'label'=>zz)) + * @param int $active Active or not, -1 = all + * @return void + */ + function form_modes_reglement($page, $selected='', $htmlname='mode_reglement_id', $filtertype='', $active=1) + { + global $langs; + if ($htmlname != "none") + { + print '<form method="POST" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setmode">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $this->select_types_paiements($selected,$htmlname,$filtertype,0,0,0,0,$active); + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + if ($selected) + { + $this->load_cache_types_paiements(); + print $this->cache_types_paiements[$selected]['label']; + } else { + print " "; + } + } + } + + /** + * Show form with multicurrency code + * + * @param string $page Page + * @param string $selected code pre-selectionne + * @param string $htmlname Name of select html field + * @return void + */ + function form_multicurrency_code($page, $selected='', $htmlname='multicurrency_code') + { + global $langs; + if ($htmlname != "none") + { + print '<form method="POST" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setmulticurrencycode">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print $this->selectMultiCurrency($selected, $htmlname, 0); + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + dol_include_once('/core/lib/company.lib.php'); + print !empty($selected) ? currency_name($selected,1) : ' '; + } + } + + /** + * Show form with multicurrency rate + * + * @param string $page Page + * @param double $rate Current rate + * @param string $htmlname Name of select html field + * @param string $currency Currency code to explain the rate + * @return void + */ + function form_multicurrency_rate($page, $rate='', $htmlname='multicurrency_tx', $currency='') + { + global $langs, $mysoc, $conf; + + if ($htmlname != "none") + { + print '<form method="POST" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setmulticurrencyrate">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="text" name="'.$htmlname.'" value="'.(!empty($rate) ? price($rate) : 1).'" size="10" /> '; + print '<select name="calculation_mode">'; + print '<option value="1">'.$currency.' > '.$conf->currency.'</option>'; + print '<option value="2">'.$conf->currency.' > '.$currency.'</option>'; + print '</select> '; + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + if (! empty($rate)) + { + print price($rate, 1, $langs, 1, 0); + if ($currency && $rate != 1) print ' ('.price($rate, 1, $langs, 1, 0).' '.$currency.' = 1 '.$conf->currency.')'; + } + else + { + print 1; + } + } + } + + + /** + * Show a select box with available absolute discounts + * + * @param string $page Page URL where form is shown + * @param int $selected Value pre-selected + * @param string $htmlname Name of SELECT component. If 'none', not changeable. Example 'remise_id'. + * @param int $socid Third party id + * @param float $amount Total amount available + * @param string $filter SQL filter on discounts + * @param int $maxvalue Max value for lines that can be selected + * @param string $more More string to add + * @param int $hidelist 1=Hide list + * @return void + */ + function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0) + { + global $conf,$langs; + if ($htmlname != "none") + { + print '<form method="post" action="'.$page.'">'; + print '<input type="hidden" name="action" value="setabsolutediscount">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<div class="inline-block">'; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + { + if (! $filter || $filter=="fk_facture_source IS NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); // If we want deposit to be substracted to payments only and not to total of final invoice + else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency)); + } + else + { + if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); + else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency)); + } + if (empty($hidelist)) print ': '; + print '</div>'; + if (empty($hidelist)) + { + print '<div class="inline-block" style="padding-right: 10px">'; + $newfilter='fk_facture IS NULL AND fk_facture_line IS NULL'; // Remises disponibles + if ($filter) $newfilter.=' AND ('.$filter.')'; + $nbqualifiedlines=$this->select_remises($selected,$htmlname,$newfilter,$socid,$maxvalue); + if ($nbqualifiedlines > 0) + { + print ' <input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("UseLine")).'"'; + if ($filter && $filter != "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')") print ' title="'.$langs->trans("UseCreditNoteInInvoicePayment").'"'; + print '>'; + } + print '</div>'; + } + if ($more) + { + print '<div class="inline-block">'; + print $more; + print '</div>'; + } + print '</form>'; + } + else + { + if ($selected) + { + print $selected; + } + else + { + print "0"; + } + } + } + + + /** + * Show forms to select a contact + * + * @param string $page Page + * @param Societe $societe Filter on third party + * @param int $selected Id contact pre-selectionne + * @param string $htmlname Name of HTML select. If 'none', we just show contact link. + * @return void + */ + function form_contacts($page, $societe, $selected='', $htmlname='contactid') + { + global $langs, $conf; + + if ($htmlname != "none") + { + print '<form method="post" action="'.$page.'">'; + print '<input type="hidden" name="action" value="set_contact">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">'; + print '<tr><td>'; + $num=$this->select_contacts($societe->id, $selected, $htmlname); + if ($num==0) + { + $addcontact = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress")); + print '<a href="'.DOL_URL_ROOT.'/contact/card.php?socid='.$societe->id.'&action=create&backtoreferer=1">'.$addcontact.'</a>'; + } + print '</td>'; + print '<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>'; + print '</tr></table></form>'; + } + else + { + if ($selected) + { + require_once DOL_DOCUMENT_ROOT .'/contact/class/contact.class.php'; + $contact=new Contact($this->db); + $contact->fetch($selected); + print $contact->getFullName($langs); + } else { + print " "; + } + } + } + + /** + * Output html select to select thirdparty + * + * @param string $page Page + * @param string $selected Id preselected + * @param string $htmlname Name of HTML select + * @param string $filter optional filters criteras + * @param int $showempty Add an empty field + * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int $forcecombo Force to use combo box + * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @return void + */ + function form_thirdparty($page, $selected='', $htmlname='socid', $filter='',$showempty=0, $showtype=0, $forcecombo=0, $events=array()) + { + global $langs; + + if ($htmlname != "none") + { + print '<form method="post" action="'.$page.'">'; + print '<input type="hidden" name="action" value="set_thirdparty">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events); + print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">'; + print '</form>'; + } + else + { + if ($selected) + { + require_once DOL_DOCUMENT_ROOT .'/societe/class/societe.class.php'; + $soc = new Societe($this->db); + $soc->fetch($selected); + print $soc->getNomUrl($langs); + } + else + { + print " "; + } + } + } + + /** + * Retourne la liste des devises, dans la langue de l'utilisateur + * + * @param string $selected preselected currency code + * @param string $htmlname name of HTML select list + * @return void + */ + function select_currency($selected='',$htmlname='currency_id') + { + print $this->selectCurrency($selected,$htmlname); + } + + /** + * Retourne la liste des devises, dans la langue de l'utilisateur + * + * @param string $selected preselected currency code + * @param string $htmlname name of HTML select list + * @return string + */ + function selectCurrency($selected='',$htmlname='currency_id') + { + global $conf,$langs,$user; + + $langs->loadCacheCurrencies(''); + + $out=''; + + if ($selected=='euro' || $selected=='euros') $selected='EUR'; // Pour compatibilite + + $out.= '<select class="flat maxwidth200onsmartphone minwidth300" name="'.$htmlname.'" id="'.$htmlname.'">'; + foreach ($langs->cache_currencies as $code_iso => $currency) + { + if ($selected && $selected == $code_iso) + { + $out.= '<option value="'.$code_iso.'" selected>'; + } + else + { + $out.= '<option value="'.$code_iso.'">'; + } + $out.= $currency['label']; + $out.= ' ('.$langs->getCurrencySymbol($code_iso).')'; + $out.= '</option>'; + } + $out.= '</select>'; + if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + + // Make select dynamic + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $out .= ajax_combobox($htmlname); + + return $out; + } + + /** + * Return array of currencies in user language + * + * @param string $selected preselected currency code + * @param string $htmlname name of HTML select list + * @param integer $useempty 1=Add empty line + * @return string + */ + function selectMultiCurrency($selected='', $htmlname='multicurrency_code', $useempty=0) + { + global $db,$conf,$langs,$user; + + $langs->loadCacheCurrencies(''); // Load ->cache_currencies + + $TCurrency = array(); + + $sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'multicurrency'; + $sql.= " WHERE entity IN ('".getEntity('mutlicurrency', 0)."')"; + $resql = $db->query($sql); + if ($resql) + { + while ($obj = $db->fetch_object($resql)) $TCurrency[$obj->code] = $obj->code; + } + + $out=''; + $out.= '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">'; + if ($useempty) $out .= '<option value=""></option>'; + // If company current currency not in table, we add it into list. Should always be available. + if (! in_array($conf->currency, $TCurrency)) + { + $TCurrency[$conf->currency] = $conf->currency; + } + if (count($TCurrency) > 0) + { + foreach ($langs->cache_currencies as $code_iso => $currency) + { + if (isset($TCurrency[$code_iso])) + { + if (!empty($selected) && $selected == $code_iso) $out.= '<option value="'.$code_iso.'" selected="selected">'; + else $out.= '<option value="'.$code_iso.'">'; + + $out.= $currency['label']; + $out.= ' ('.$langs->getCurrencySymbol($code_iso).')'; + $out.= '</option>'; + } + } + + } + + $out.= '</select>'; + // Make select dynamic + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $out.= ajax_combobox($htmlname); + + return $out; + } + + /** + * Load into the cache vat rates of a country + * + * @param string $country_code Country code with quotes ("'CA'", or "'CA,IN,...'") + * @return int Nb of loaded lines, 0 if already loaded, <0 if KO + */ + function load_cache_vatrates($country_code) + { + global $langs; + + $num = count($this->cache_vatrates); + if ($num > 0) return $num; // Cache already loaded + + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = "SELECT DISTINCT t.rowid, t.code, t.taux, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.recuperableonly"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; + $sql.= " WHERE t.fk_pays = c.rowid"; + $sql.= " AND t.active > 0"; + $sql.= " AND c.code IN (".$country_code.")"; + $sql.= " ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC"; + + $resql=$this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + if ($num) + { + for ($i = 0; $i < $num; $i++) + { + $obj = $this->db->fetch_object($resql); + $this->cache_vatrates[$i]['rowid'] = $obj->rowid; + $this->cache_vatrates[$i]['code'] = $obj->code; + $this->cache_vatrates[$i]['txtva'] = $obj->taux; + $this->cache_vatrates[$i]['nprtva'] = $obj->recuperableonly; + $this->cache_vatrates[$i]['localtax1'] = $obj->localtax1; + $this->cache_vatrates[$i]['localtax1_type'] = $obj->localtax1_type; + $this->cache_vatrates[$i]['localtax2'] = $obj->localtax2; + $this->cache_vatrates[$i]['localtax2_type'] = $obj->localtax1_type; + + $this->cache_vatrates[$i]['label'] = $obj->taux.'%'.($obj->code?' ('.$obj->code.')':''); // Label must contains only 0-9 , . % or * + $this->cache_vatrates[$i]['labelallrates'] = $obj->taux.'/'.($obj->localtax1?$obj->localtax1:'0').'/'.($obj->localtax2?$obj->localtax2:'0').($obj->code?' ('.$obj->code.')':''); // Must never be used as key, only label + $positiverates=''; + if ($obj->taux) $positiverates.=($positiverates?'/':'').$obj->taux; + if ($obj->localtax1) $positiverates.=($positiverates?'/':'').$obj->localtax1; + if ($obj->localtax2) $positiverates.=($positiverates?'/':'').$obj->localtax2; + if (empty($positiverates)) $positiverates='0'; + $this->cache_vatrates[$i]['labelpositiverates'] = $positiverates.($obj->code?' ('.$obj->code.')':''); // Must never be used as key, only label + } + + return $num; + } + else + { + $this->error = '<font class="error">'.$langs->trans("ErrorNoVATRateDefinedForSellerCountry",$country_code).'</font>'; + return -1; + } + } + else + { + $this->error = '<font class="error">'.$this->db->error().'</font>'; + return -2; + } + } + + /** + * Output an HTML select vat rate. + * The name of this function should be selectVat. We keep bad name for compatibility purpose. + * + * @param string $htmlname Name of HTML select field + * @param float|string $selectedrate Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing. + * @param Societe $societe_vendeuse Thirdparty seller + * @param Societe $societe_acheteuse Thirdparty buyer + * @param int $idprod Id product. O if unknown of NA. + * @param int $info_bits Miscellaneous information on line (1 for NPR) + * @param int|string $type ''=Unknown, 0=Product, 1=Service (Used if idprod not defined) + * Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle. + * Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle. + * Si (vendeur et acheteur dans Communaute europeenne) et bien vendu = moyen de transports neuf (auto, bateau, avion), TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle. + * Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle. + * Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle. + * Sinon la TVA proposee par defaut=0. Fin de regle. + * @param bool $options_only Return HTML options lines only (for ajax treatment) + * @param int $mode 0=Use vat rate as key in combo list, 1=Add VAT code after vat rate into key, -1=Use id of vat line as key + * @return string + */ + function load_tva($htmlname='tauxtva', $selectedrate='', $societe_vendeuse='', $societe_acheteuse='', $idprod=0, $info_bits=0, $type='', $options_only=false, $mode=0) + { + global $langs,$conf,$mysoc; + + $return=''; + + // Define defaultnpr, defaultttx and defaultcode + $defaultnpr=($info_bits & 0x01); + $defaultnpr=(preg_match('/\*/',$selectedrate) ? 1 : $defaultnpr); + $defaulttx=str_replace('*','',$selectedrate); + $defaultcode=''; + if (preg_match('/\((.*)\)/', $defaulttx, $reg)) + { + $defaultcode=$reg[1]; + $defaulttx=preg_replace('/\s*\(.*\)/','',$defaulttx); + } + //var_dump($selectedrate.'-'.$defaulttx.'-'.$defaultnpr.'-'.$defaultcode); + + // Check parameters + if (is_object($societe_vendeuse) && ! $societe_vendeuse->country_code) + { + if ($societe_vendeuse->id == $mysoc->id) + { + $return.= '<font class="error">'.$langs->trans("ErrorYourCountryIsNotDefined").'</div>'; + } + else + { + $return.= '<font class="error">'.$langs->trans("ErrorSupplierCountryIsNotDefined").'</div>'; + } + return $return; + } + + //var_dump($societe_acheteuse); + //print "name=$name, selectedrate=$selectedrate, seller=".$societe_vendeuse->country_code." buyer=".$societe_acheteuse->country_code." buyer is company=".$societe_acheteuse->isACompany()." idprod=$idprod, info_bits=$info_bits type=$type"; + //exit; + + // Define list of countries to use to search VAT rates to show + // First we defined code_country to use to find list + if (is_object($societe_vendeuse)) + { + $code_country="'".$societe_vendeuse->country_code."'"; + } + else + { + $code_country="'".$mysoc->country_code."'"; // Pour compatibilite ascendente + } + if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) // If option to have vat for end customer for services is on + { + if (! $societe_vendeuse->isInEEC() && (! is_object($societe_acheteuse) || ($societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany()))) + { + // We also add the buyer + if (is_numeric($type)) + { + if ($type == 1) // We know product is a service + { + $code_country.=",'".$societe_acheteuse->country_code."'"; + } + } + else if (! $idprod) // We don't know type of product + { + $code_country.=",'".$societe_acheteuse->country_code."'"; + } + else + { + $prodstatic=new Product($this->db); + $prodstatic->fetch($idprod); + if ($prodstatic->type == Product::TYPE_SERVICE) // We know product is a service + { + $code_country.=",'".$societe_acheteuse->country_code."'"; + } + } + } + } + + // Now we get list + $num = $this->load_cache_vatrates($code_country); // If no vat defined, return -1 with message into this->error + + if ($num > 0) + { + // Definition du taux a pre-selectionner (si defaulttx non force et donc vaut -1 ou '') + if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) + { + $tmpthirdparty=new Societe($this->db); + $defaulttx=get_default_tva($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod); + $defaultnpr=get_default_npr($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod); + if (empty($defaulttx)) $defaultnpr=0; + } + + // Si taux par defaut n'a pu etre determine, on prend dernier de la liste. + // Comme ils sont tries par ordre croissant, dernier = plus eleve = taux courant + if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) + { + if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) $defaulttx = $this->cache_vatrates[$num-1]['txtva']; + else $defaulttx=($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS == 'none' ? '' : $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS); + } + + // Disabled if seller is not subject to VAT + $disabled=false; $title=''; + if (is_object($societe_vendeuse) && $societe_vendeuse->id == $mysoc->id && $societe_vendeuse->tva_assuj == "0") + { + $title=' title="'.$langs->trans('VATIsNotUsed').'"'; + $disabled=true; + } + + if (! $options_only) $return.= '<select class="flat minwidth75imp" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').$title.'>'; + + $selectedfound=false; + foreach ($this->cache_vatrates as $rate) + { + // Keep only 0 if seller is not subject to VAT + if ($disabled && $rate['txtva'] != 0) continue; + + // Define key to use into select list + $key = $rate['txtva']; + $key.= $rate['nprtva'] ? '*': ''; + if ($mode > 0 && $rate['code']) $key.=' ('.$rate['code'].')'; + if ($mode < 0) $key = $rate['rowid']; + + $return.= '<option value="'.$key.'"'; + if (! $selectedfound) + { + if ($defaultcode) // If defaultcode is defined, we used it in priority to select combo option instead of using rate+npr flag + { + if ($defaultcode == $rate['code']) + { + $return.= ' selected'; + $selectedfound=true; + } + } + elseif ($rate['txtva'] == $defaulttx && $rate['nprtva'] == $defaultnpr) + { + $return.= ' selected'; + $selectedfound=true; + } + } + $return.= '>'; + //if (! empty($conf->global->MAIN_VAT_SHOW_POSITIVE_RATES)) + if ($mysoc->country_code == 'IN' || ! empty($conf->global->MAIN_VAT_LABEL_IS_POSITIVE_RATES)) + { + $return.= $rate['labelpositiverates']; + } + else + { + $return.= vatrate($rate['label']); + } + //$return.=($rate['code']?' '.$rate['code']:''); + $return.= (empty($rate['code']) && $rate['nprtva']) ? ' *': ''; // We show the * (old behaviour only if new vat code is not used) + + $return.= '</option>'; + } + + if (! $options_only) $return.= '</select>'; + } + else + { + $return.= $this->error; + } + + $this->num = $num; + return $return; + } + + + /** + * Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes. + * Fields are preselected with : + * - set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM') + * - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location) + * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1) + * + * @param timestamp $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date (emptydate must be 0). + * @param string $prefix Prefix for fields name + * @param int $h 1=Show also hours + * @param int $m 1=Show also minutes + * @param int $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only + * @param string $form_name Not used + * @param int $d 1=Show days, month, years + * @param int $addnowlink Add a link "Now" + * @param int $nooutput Do not output html string but return it + * @param int $disabled Disable input fields + * @param int $fullday When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59 + * @param string $addplusone Add a link "+1 hour". Value must be name of another select_date field. + * @param datetime $adddateof Add a link "Date of invoice" using the following date. + * @return string|null Nothing or string if nooutput is 1 + * @see form_date + */ + function select_date($set_time='', $prefix='re', $h=0, $m=0, $empty=0, $form_name="", $d=1, $addnowlink=0, $nooutput=0, $disabled=0, $fullday='', $addplusone='', $adddateof='') + { + global $conf,$langs; + + $retstring=''; + + if($prefix=='') $prefix='re'; + if($h == '') $h=0; + if($m == '') $m=0; + $emptydate=0; + $emptyhours=0; + if ($empty == 1) { $emptydate=1; $emptyhours=1; } + if ($empty == 2) { $emptydate=0; $emptyhours=1; } + $orig_set_time=$set_time; + + if ($set_time === '' && $emptydate == 0) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + $set_time = dol_now('tzuser')-(getServerTimeZoneInt('now')*3600); // set_time must be relative to PHP server timezone + } + + // Analysis of the pre-selection date + if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/',$set_time,$reg)) + { + // Date format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' + $syear = (! empty($reg[1])?$reg[1]:''); + $smonth = (! empty($reg[2])?$reg[2]:''); + $sday = (! empty($reg[3])?$reg[3]:''); + $shour = (! empty($reg[4])?$reg[4]:''); + $smin = (! empty($reg[5])?$reg[5]:''); + } + elseif (strval($set_time) != '' && $set_time != -1) + { + // set_time est un timestamps (0 possible) + $syear = dol_print_date($set_time, "%Y"); + $smonth = dol_print_date($set_time, "%m"); + $sday = dol_print_date($set_time, "%d"); + if ($orig_set_time != '') + { + $shour = dol_print_date($set_time, "%H"); + $smin = dol_print_date($set_time, "%M"); + } + } + else + { + // Date est '' ou vaut -1 + $syear = ''; + $smonth = ''; + $sday = ''; + $shour = !isset($conf->global->MAIN_DEFAULT_DATE_HOUR) ? '' : $conf->global->MAIN_DEFAULT_DATE_HOUR; + $smin = !isset($conf->global->MAIN_DEFAULT_DATE_MIN) ? '' : $conf->global->MAIN_DEFAULT_DATE_MIN; + } + + // You can set MAIN_POPUP_CALENDAR to 'eldy' or 'jquery' + $usecalendar='combo'; + if (! empty($conf->use_javascript_ajax) && (empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR != "none")) $usecalendar=empty($conf->global->MAIN_POPUP_CALENDAR)?'jquery':$conf->global->MAIN_POPUP_CALENDAR; + //if (! empty($conf->browser->phone)) $usecalendar='combo'; + + if ($d) + { + // Show date with popup + if ($usecalendar != 'combo') + { + $formated_date=''; + //print "e".$set_time." t ".$conf->format_date_short; + if (strval($set_time) != '' && $set_time != -1) + { + //$formated_date=dol_print_date($set_time,$conf->format_date_short); + $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShortInput")); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript + } + + // Calendrier popup version eldy + if ($usecalendar == "eldy") + { + // Zone de saisie manuelle de la date + $retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" class="maxwidth75" maxlength="11" value="'.$formated_date.'"'; + $retstring.=($disabled?' disabled':''); + $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript + $retstring.='>'; + + // Icone calendrier + if (! $disabled) + { + $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons"'; + $base=DOL_URL_ROOT.'/core/'; + $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');"'; + $retstring.='>'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').'</button>'; + } + else $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>'; + + $retstring.='<input type="hidden" id="'.$prefix.'day" name="'.$prefix.'day" value="'.$sday.'">'."\n"; + $retstring.='<input type="hidden" id="'.$prefix.'month" name="'.$prefix.'month" value="'.$smonth.'">'."\n"; + $retstring.='<input type="hidden" id="'.$prefix.'year" name="'.$prefix.'year" value="'.$syear.'">'."\n"; + } + elseif ($usecalendar == 'jquery') + { + if (! $disabled) + { + $retstring.="<script type='text/javascript'>"; + $retstring.="$(function(){ $('#".$prefix."').datepicker({ + dateFormat: '".$langs->trans("FormatDateShortJQueryInput")."', + autoclose: true, + todayHighlight: true,"; + if (empty($conf->global->MAIN_POPUP_CALENDAR_ON_FOCUS)) + { + $retstring.=" + showOn: 'button', + buttonImage: '".DOL_URL_ROOT."/theme/".$conf->theme."/img/object_calendarday.png', + buttonImageOnly: true"; + } + $retstring.=" + }) });"; + $retstring.="</script>"; + } + + // Zone de saisie manuelle de la date + $retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" class="maxwidth75" maxlength="11" value="'.$formated_date.'"'; + $retstring.=($disabled?' disabled':''); + $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript + $retstring.='>'; + + // Icone calendrier + if (! $disabled) + { + /* Not required. Managed by option buttonImage of jquery + $retstring.=img_object($langs->trans("SelectDate"),'calendarday','id="'.$prefix.'id" class="datecallink"'); + $retstring.="<script type='text/javascript'>"; + $retstring.="jQuery(document).ready(function() {"; + $retstring.=' jQuery("#'.$prefix.'id").click(function() {'; + $retstring.=" jQuery('#".$prefix."').focus();"; + $retstring.=' });'; + $retstring.='});'; + $retstring.="</script>";*/ + } + else + { + $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>'; + } + + $retstring.='<input type="hidden" id="'.$prefix.'day" name="'.$prefix.'day" value="'.$sday.'">'."\n"; + $retstring.='<input type="hidden" id="'.$prefix.'month" name="'.$prefix.'month" value="'.$smonth.'">'."\n"; + $retstring.='<input type="hidden" id="'.$prefix.'year" name="'.$prefix.'year" value="'.$syear.'">'."\n"; + } + else + { + $retstring.="Bad value of MAIN_POPUP_CALENDAR"; + } + } + // Show date with combo selects + else + { + //$retstring.='<div class="inline-block">'; + // Day + $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50imp" id="'.$prefix.'day" name="'.$prefix.'day">'; + + if ($emptydate || $set_time == -1) + { + $retstring.='<option value="0" selected> </option>'; + } + + for ($day = 1 ; $day <= 31; $day++) + { + $retstring.='<option value="'.$day.'"'.($day == $sday ? ' selected':'').'>'.$day.'</option>'; + } + + $retstring.="</select>"; + + $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'month" name="'.$prefix.'month">'; + if ($emptydate || $set_time == -1) + { + $retstring.='<option value="0" selected> </option>'; + } + + // Month + for ($month = 1 ; $month <= 12 ; $month++) + { + $retstring.='<option value="'.$month.'"'.($month == $smonth?' selected':'').'>'; + $retstring.=dol_print_date(mktime(12,0,0,$month,1,2000),"%b"); + $retstring.="</option>"; + } + $retstring.="</select>"; + + // Year + if ($emptydate || $set_time == -1) + { + $retstring.='<input'.($disabled?' disabled':'').' placeholder="'.dol_escape_htmltag($langs->trans("Year")).'" class="flat maxwidth50imp valignmiddle" type="number" min="0" max="3000" maxlength="4" id="'.$prefix.'year" name="'.$prefix.'year" value="'.$syear.'">'; + } + else + { + $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'year" name="'.$prefix.'year">'; + + for ($year = $syear - 10; $year < $syear + 10 ; $year++) + { + $retstring.='<option value="'.$year.'"'.($year == $syear ? ' selected':'').'>'.$year.'</option>'; + } + $retstring.="</select>\n"; + } + //$retstring.='</div>'; + } + } + + if ($d && $h) $retstring.=($h==2?'<br>':' '); + + if ($h) + { + // Show hour + $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'hour':'').'" id="'.$prefix.'hour" name="'.$prefix.'hour">'; + if ($emptyhours) $retstring.='<option value="-1"> </option>'; + for ($hour = 0; $hour < 24; $hour++) + { + if (strlen($hour) < 2) $hour = "0" . $hour; + $retstring.='<option value="'.$hour.'"'.(($hour == $shour)?' selected':'').'>'.$hour.(empty($conf->dol_optimize_smallscreen)?'':'H').'</option>'; + } + $retstring.='</select>'; + if ($m && empty($conf->dol_optimize_smallscreen)) $retstring.=":"; + } + + if ($m) + { + // Show minutes + $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'min':'').'" id="'.$prefix.'min" name="'.$prefix.'min">'; + if ($emptyhours) $retstring.='<option value="-1"> </option>'; + for ($min = 0; $min < 60 ; $min++) + { + if (strlen($min) < 2) $min = "0" . $min; + $retstring.='<option value="'.$min.'"'.(($min == $smin)?' selected':'').'>'.$min.(empty($conf->dol_optimize_smallscreen)?'':'').'</option>'; + } + $retstring.='</select>'; + } + + // Add a "Now" link + if ($conf->use_javascript_ajax && $addnowlink) + { + // Script which will be inserted in the onClick of the "Now" link + $reset_scripts = ""; + + // Generate the date part, depending on the use or not of the javascript calendar + $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');'; + /*if ($usecalendar == "eldy") + { + $base=DOL_URL_ROOT.'/core/'; + $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');'; + } + else + { + $reset_scripts .= 'this.form.elements[\''.$prefix.'day\'].value=formatDate(new Date(), \'d\'); '; + $reset_scripts .= 'this.form.elements[\''.$prefix.'month\'].value=formatDate(new Date(), \'M\'); '; + $reset_scripts .= 'this.form.elements[\''.$prefix.'year\'].value=formatDate(new Date(), \'yyyy\'); '; + }*/ + // Update the hour part + if ($h) + { + if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; + //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); '; + $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');'; + if ($fullday) $reset_scripts .= ' } '; + } + // Update the minute part + if ($m) + { + if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; + //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); '; + $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');'; + if ($fullday) $reset_scripts .= ' } '; + } + // If reset_scripts is not empty, print the link with the reset_scripts in the onClick + if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) + { + $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonNow" type="button" name="_useless" value="now" onClick="'.$reset_scripts.'">'; + $retstring.=$langs->trans("Now"); + $retstring.='</button> '; + } + } + + // Add a "Plus one hour" link + if ($conf->use_javascript_ajax && $addplusone) + { + // Script which will be inserted in the onClick of the "Add plusone" link + $reset_scripts = ""; + + // Generate the date part, depending on the use or not of the javascript calendar + $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');'; + // Update the hour part + if ($h) + { + if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; + $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');'; + if ($fullday) $reset_scripts .= ' } '; + } + // Update the minute part + if ($m) + { + if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; + $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');'; + if ($fullday) $reset_scripts .= ' } '; + } + // If reset_scripts is not empty, print the link with the reset_scripts in the onClick + if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) + { + $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonPlusOne" type="button" name="_useless2" value="plusone" onClick="'.$reset_scripts.'">'; + $retstring.=$langs->trans("DateStartPlusOne"); + $retstring.='</button> '; } - $out.= $currency['label']; - $out.= ' ('.$langs->getCurrencySymbol($code_iso).')'; - $out.= '</option>'; } - $out.= '</select>'; - if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - // Make select dynamic - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $out .= ajax_combobox($htmlname); + // Add a "Plus one hour" link + if ($conf->use_javascript_ajax && $adddateof) + { + $tmparray=dol_getdate($adddateof); + $retstring.=' - <button class="dpInvisibleButtons datenowlink" id="dateofinvoice" type="button" name="_dateofinvoice" value="now" onclick="jQuery(\'#re\').val(\''.dol_print_date($adddateof,'day').'\');jQuery(\'#reday\').val(\''.$tmparray['mday'].'\');jQuery(\'#remonth\').val(\''.$tmparray['mon'].'\');jQuery(\'#reyear\').val(\''.$tmparray['year'].'\');">'.$langs->trans("DateInvoice").'</a>'; + } - return $out; + if (! empty($nooutput)) return $retstring; + + print $retstring; + return; } /** - * Return array of currencies in user language + * Function to show a form to select a duration on a page * - * @param string $selected preselected currency code - * @param string $htmlname name of HTML select list - * @param integer $useempty 1=Add empty line - * @return string - */ - function selectMultiCurrency($selected='', $htmlname='multicurrency_code', $useempty=0) - { - global $db,$conf,$langs,$user; + * @param string $prefix Prefix for input fields + * @param int $iSecond Default preselected duration (number of seconds or '') + * @param int $disabled Disable the combo box + * @param string $typehour If 'select' then input hour and input min is a combo, + * if 'text' input hour is in text and input min is a text, + * if 'textselect' input hour is in text and input min is a combo + * @param integer $minunderhours If 1, show minutes selection under the hours + * @param int $nooutput Do not output html string but return it + * @return string|null + */ + function select_duration($prefix, $iSecond='', $disabled=0, $typehour='select', $minunderhours=0, $nooutput=0) + { + global $langs; - $langs->loadCacheCurrencies(''); // Load ->cache_currencies + $retstring=''; - $TCurrency = array(); + $hourSelected=0; $minSelected=0; - $sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'multicurrency'; - $sql.= " WHERE entity IN ('".getEntity('mutlicurrency', 0)."')"; - $resql = $db->query($sql); - if ($resql) + // Hours + if ($iSecond != '') { - while ($obj = $db->fetch_object($resql)) $TCurrency[$obj->code] = $obj->code; + require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + + $hourSelected = convertSecondToTime($iSecond,'allhour'); + $minSelected = convertSecondToTime($iSecond,'min'); } - $out=''; - $out.= '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">'; - if ($useempty) $out .= '<option value=""></option>'; - // If company current currency not in table, we add it into list. Should always be available. - if (! in_array($conf->currency, $TCurrency)) + if ($typehour=='select' ) { - $TCurrency[$conf->currency] = $conf->currency; + $retstring.='<select class="flat" name="'.$prefix.'hour"'.($disabled?' disabled':'').'>'; + for ($hour = 0; $hour < 25; $hour++) // For a duration, we allow 24 hours + { + $retstring.='<option value="'.$hour.'"'; + if ($hourSelected == $hour) + { + $retstring.=" selected"; + } + $retstring.=">".$hour."</option>"; + } + $retstring.="</select>"; } - if (count($TCurrency) > 0) + elseif ($typehour=='text' || $typehour=='textselect') { - foreach ($langs->cache_currencies as $code_iso => $currency) - { - if (isset($TCurrency[$code_iso])) - { - if (!empty($selected) && $selected == $code_iso) $out.= '<option value="'.$code_iso.'" selected="selected">'; - else $out.= '<option value="'.$code_iso.'">'; + $retstring.='<input placeholder="'.$langs->trans('HourShort').'" type="number" min="0" size="1" name="'.$prefix.'hour"'.($disabled?' disabled':'').' class="flat maxwidth50 inputhour" value="'.(($hourSelected != '')?((int) $hourSelected):'').'">'; + } + else return 'BadValueForParameterTypeHour'; - $out.= $currency['label']; - $out.= ' ('.$langs->getCurrencySymbol($code_iso).')'; - $out.= '</option>'; - } - } + if ($typehour!='text') $retstring.=' '.$langs->trans('HourShort'); + else $retstring.='<span class="hideonsmartphone">:</span>'; - } + // Minutes + if ($minunderhours) $retstring.='<br>'; + else $retstring.='<span class="hideonsmartphone"> </span>'; - $out.= '</select>'; - // Make select dynamic - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $out.= ajax_combobox($htmlname); + if ($typehour=='select' || $typehour=='textselect') + { + $retstring.='<select class="flat" name="'.$prefix.'min"'.($disabled?' disabled':'').'>'; + for ($min = 0; $min <= 55; $min=$min+5) + { + $retstring.='<option value="'.$min.'"'; + if ($minSelected == $min) $retstring.=' selected'; + $retstring.='>'.$min.'</option>'; + } + $retstring.="</select>"; + } + elseif ($typehour=='text' ) + { + $retstring.='<input placeholder="'.$langs->trans('MinuteShort').'" type="number" min="0" size="1" name="'.$prefix.'min"'.($disabled?' disabled':'').' class="flat maxwidth50 inputminute" value="'.(($minSelected != '')?((int) $minSelected):'').'">'; + } - return $out; - } - - /** - * Load into the cache vat rates of a country - * - * @param string $country_code Country code with quotes ("'CA'", or "'CA,IN,...'") - * @return int Nb of loaded lines, 0 if already loaded, <0 if KO - */ - function load_cache_vatrates($country_code) - { - global $langs; - - $num = count($this->cache_vatrates); - if ($num > 0) return $num; // Cache already loaded - - dol_syslog(__METHOD__, LOG_DEBUG); - - $sql = "SELECT DISTINCT t.rowid, t.code, t.taux, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.recuperableonly"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; - $sql.= " WHERE t.fk_pays = c.rowid"; - $sql.= " AND t.active > 0"; - $sql.= " AND c.code IN (".$country_code.")"; - $sql.= " ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC"; - - $resql=$this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - if ($num) - { - for ($i = 0; $i < $num; $i++) - { - $obj = $this->db->fetch_object($resql); - $this->cache_vatrates[$i]['rowid'] = $obj->rowid; - $this->cache_vatrates[$i]['code'] = $obj->code; - $this->cache_vatrates[$i]['txtva'] = $obj->taux; - $this->cache_vatrates[$i]['nprtva'] = $obj->recuperableonly; - $this->cache_vatrates[$i]['localtax1'] = $obj->localtax1; - $this->cache_vatrates[$i]['localtax1_type'] = $obj->localtax1_type; - $this->cache_vatrates[$i]['localtax2'] = $obj->localtax2; - $this->cache_vatrates[$i]['localtax2_type'] = $obj->localtax1_type; - - $this->cache_vatrates[$i]['label'] = $obj->taux.'%'.($obj->code?' ('.$obj->code.')':''); // Label must contains only 0-9 , . % or * - $this->cache_vatrates[$i]['labelallrates'] = $obj->taux.'/'.($obj->localtax1?$obj->localtax1:'0').'/'.($obj->localtax2?$obj->localtax2:'0').($obj->code?' ('.$obj->code.')':''); // Must never be used as key, only label - $positiverates=''; - if ($obj->taux) $positiverates.=($positiverates?'/':'').$obj->taux; - if ($obj->localtax1) $positiverates.=($positiverates?'/':'').$obj->localtax1; - if ($obj->localtax2) $positiverates.=($positiverates?'/':'').$obj->localtax2; - if (empty($positiverates)) $positiverates='0'; - $this->cache_vatrates[$i]['labelpositiverates'] = $positiverates.($obj->code?' ('.$obj->code.')':''); // Must never be used as key, only label - } - - return $num; - } - else - { - $this->error = '<font class="error">'.$langs->trans("ErrorNoVATRateDefinedForSellerCountry",$country_code).'</font>'; - return -1; - } - } - else - { - $this->error = '<font class="error">'.$this->db->error().'</font>'; - return -2; - } - } - - /** - * Output an HTML select vat rate. - * The name of this function should be selectVat. We keep bad name for compatibility purpose. - * - * @param string $htmlname Name of HTML select field - * @param float|string $selectedrate Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing. - * @param Societe $societe_vendeuse Thirdparty seller - * @param Societe $societe_acheteuse Thirdparty buyer - * @param int $idprod Id product. O if unknown of NA. - * @param int $info_bits Miscellaneous information on line (1 for NPR) - * @param int|string $type ''=Unknown, 0=Product, 1=Service (Used if idprod not defined) - * Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle. - * Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle. - * Si (vendeur et acheteur dans Communaute europeenne) et bien vendu = moyen de transports neuf (auto, bateau, avion), TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle. - * Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle. - * Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle. - * Sinon la TVA proposee par defaut=0. Fin de regle. - * @param bool $options_only Return HTML options lines only (for ajax treatment) - * @param int $mode 0=Use vat rate as key in combo list, 1=Add VAT code after vat rate into key, -1=Use id of vat line as key - * @return string - */ - function load_tva($htmlname='tauxtva', $selectedrate='', $societe_vendeuse='', $societe_acheteuse='', $idprod=0, $info_bits=0, $type='', $options_only=false, $mode=0) - { - global $langs,$conf,$mysoc; - - $return=''; - - // Define defaultnpr, defaultttx and defaultcode - $defaultnpr=($info_bits & 0x01); - $defaultnpr=(preg_match('/\*/',$selectedrate) ? 1 : $defaultnpr); - $defaulttx=str_replace('*','',$selectedrate); - $defaultcode=''; - if (preg_match('/\((.*)\)/', $defaulttx, $reg)) - { - $defaultcode=$reg[1]; - $defaulttx=preg_replace('/\s*\(.*\)/','',$defaulttx); - } - //var_dump($selectedrate.'-'.$defaulttx.'-'.$defaultnpr.'-'.$defaultcode); - - // Check parameters - if (is_object($societe_vendeuse) && ! $societe_vendeuse->country_code) - { - if ($societe_vendeuse->id == $mysoc->id) - { - $return.= '<font class="error">'.$langs->trans("ErrorYourCountryIsNotDefined").'</div>'; - } - else - { - $return.= '<font class="error">'.$langs->trans("ErrorSupplierCountryIsNotDefined").'</div>'; - } - return $return; - } - - //var_dump($societe_acheteuse); - //print "name=$name, selectedrate=$selectedrate, seller=".$societe_vendeuse->country_code." buyer=".$societe_acheteuse->country_code." buyer is company=".$societe_acheteuse->isACompany()." idprod=$idprod, info_bits=$info_bits type=$type"; - //exit; - - // Define list of countries to use to search VAT rates to show - // First we defined code_country to use to find list - if (is_object($societe_vendeuse)) - { - $code_country="'".$societe_vendeuse->country_code."'"; - } - else - { - $code_country="'".$mysoc->country_code."'"; // Pour compatibilite ascendente - } - if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) // If option to have vat for end customer for services is on - { - if (! $societe_vendeuse->isInEEC() && (! is_object($societe_acheteuse) || ($societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany()))) - { - // We also add the buyer - if (is_numeric($type)) - { - if ($type == 1) // We know product is a service - { - $code_country.=",'".$societe_acheteuse->country_code."'"; - } - } - else if (! $idprod) // We don't know type of product - { - $code_country.=",'".$societe_acheteuse->country_code."'"; - } - else - { - $prodstatic=new Product($this->db); - $prodstatic->fetch($idprod); - if ($prodstatic->type == Product::TYPE_SERVICE) // We know product is a service - { - $code_country.=",'".$societe_acheteuse->country_code."'"; - } - } - } - } - - // Now we get list - $num = $this->load_cache_vatrates($code_country); // If no vat defined, return -1 with message into this->error - - if ($num > 0) - { - // Definition du taux a pre-selectionner (si defaulttx non force et donc vaut -1 ou '') - if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) - { - $tmpthirdparty=new Societe($this->db); - $defaulttx=get_default_tva($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod); - $defaultnpr=get_default_npr($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod); - if (empty($defaulttx)) $defaultnpr=0; - } - - // Si taux par defaut n'a pu etre determine, on prend dernier de la liste. - // Comme ils sont tries par ordre croissant, dernier = plus eleve = taux courant - if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) - { - if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) $defaulttx = $this->cache_vatrates[$num-1]['txtva']; - else $defaulttx=($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS == 'none' ? '' : $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS); - } - - // Disabled if seller is not subject to VAT - $disabled=false; $title=''; - if (is_object($societe_vendeuse) && $societe_vendeuse->id == $mysoc->id && $societe_vendeuse->tva_assuj == "0") - { - $title=' title="'.$langs->trans('VATIsNotUsed').'"'; - $disabled=true; - } - - if (! $options_only) $return.= '<select class="flat minwidth75imp" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').$title.'>'; - - $selectedfound=false; - foreach ($this->cache_vatrates as $rate) - { - // Keep only 0 if seller is not subject to VAT - if ($disabled && $rate['txtva'] != 0) continue; - - // Define key to use into select list - $key = $rate['txtva']; - $key.= $rate['nprtva'] ? '*': ''; - if ($mode > 0 && $rate['code']) $key.=' ('.$rate['code'].')'; - if ($mode < 0) $key = $rate['rowid']; - - $return.= '<option value="'.$key.'"'; - if (! $selectedfound) - { - if ($defaultcode) // If defaultcode is defined, we used it in priority to select combo option instead of using rate+npr flag - { - if ($defaultcode == $rate['code']) - { - $return.= ' selected'; - $selectedfound=true; - } - } - elseif ($rate['txtva'] == $defaulttx && $rate['nprtva'] == $defaultnpr) - { - $return.= ' selected'; - $selectedfound=true; - } - } - $return.= '>'; - //if (! empty($conf->global->MAIN_VAT_SHOW_POSITIVE_RATES)) - if ($mysoc->country_code == 'IN' || ! empty($conf->global->MAIN_VAT_LABEL_IS_POSITIVE_RATES)) - { - $return.= $rate['labelpositiverates']; - } - else - { - $return.= vatrate($rate['label']); - } - //$return.=($rate['code']?' '.$rate['code']:''); - $return.= (empty($rate['code']) && $rate['nprtva']) ? ' *': ''; // We show the * (old behaviour only if new vat code is not used) - - $return.= '</option>'; - } - - if (! $options_only) $return.= '</select>'; - } - else - { - $return.= $this->error; - } - - $this->num = $num; - return $return; - } - - - /** - * Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes. - * Fields are preselected with : - * - set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM') - * - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location) - * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1) - * - * @param timestamp $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date (emptydate must be 0). - * @param string $prefix Prefix for fields name - * @param int $h 1=Show also hours - * @param int $m 1=Show also minutes - * @param int $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only - * @param string $form_name Not used - * @param int $d 1=Show days, month, years - * @param int $addnowlink Add a link "Now" - * @param int $nooutput Do not output html string but return it - * @param int $disabled Disable input fields - * @param int $fullday When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59 - * @param string $addplusone Add a link "+1 hour". Value must be name of another select_date field. - * @param datetime $adddateof Add a link "Date of invoice" using the following date. - * @return string|null Nothing or string if nooutput is 1 - * @see form_date - */ - function select_date($set_time='', $prefix='re', $h=0, $m=0, $empty=0, $form_name="", $d=1, $addnowlink=0, $nooutput=0, $disabled=0, $fullday='', $addplusone='', $adddateof='') - { - global $conf,$langs; - - $retstring=''; - - if($prefix=='') $prefix='re'; - if($h == '') $h=0; - if($m == '') $m=0; - $emptydate=0; - $emptyhours=0; - if ($empty == 1) { $emptydate=1; $emptyhours=1; } - if ($empty == 2) { $emptydate=0; $emptyhours=1; } - $orig_set_time=$set_time; + if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); - if ($set_time === '' && $emptydate == 0) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - $set_time = dol_now('tzuser')-(getServerTimeZoneInt('now')*3600); // set_time must be relative to PHP server timezone - } - - // Analysis of the pre-selection date - if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/',$set_time,$reg)) - { - // Date format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' - $syear = (! empty($reg[1])?$reg[1]:''); - $smonth = (! empty($reg[2])?$reg[2]:''); - $sday = (! empty($reg[3])?$reg[3]:''); - $shour = (! empty($reg[4])?$reg[4]:''); - $smin = (! empty($reg[5])?$reg[5]:''); - } - elseif (strval($set_time) != '' && $set_time != -1) - { - // set_time est un timestamps (0 possible) - $syear = dol_print_date($set_time, "%Y"); - $smonth = dol_print_date($set_time, "%m"); - $sday = dol_print_date($set_time, "%d"); - if ($orig_set_time != '') - { - $shour = dol_print_date($set_time, "%H"); - $smin = dol_print_date($set_time, "%M"); - } - } - else - { - // Date est '' ou vaut -1 - $syear = ''; - $smonth = ''; - $sday = ''; - $shour = !isset($conf->global->MAIN_DEFAULT_DATE_HOUR) ? '' : $conf->global->MAIN_DEFAULT_DATE_HOUR; - $smin = !isset($conf->global->MAIN_DEFAULT_DATE_MIN) ? '' : $conf->global->MAIN_DEFAULT_DATE_MIN; - } - - // You can set MAIN_POPUP_CALENDAR to 'eldy' or 'jquery' - $usecalendar='combo'; - if (! empty($conf->use_javascript_ajax) && (empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR != "none")) $usecalendar=empty($conf->global->MAIN_POPUP_CALENDAR)?'jquery':$conf->global->MAIN_POPUP_CALENDAR; - //if (! empty($conf->browser->phone)) $usecalendar='combo'; + //$retstring.=" "; - if ($d) - { - // Show date with popup - if ($usecalendar != 'combo') - { - $formated_date=''; - //print "e".$set_time." t ".$conf->format_date_short; - if (strval($set_time) != '' && $set_time != -1) - { - //$formated_date=dol_print_date($set_time,$conf->format_date_short); - $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShortInput")); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript - } + if (! empty($nooutput)) return $retstring; - // Calendrier popup version eldy - if ($usecalendar == "eldy") - { - // Zone de saisie manuelle de la date - $retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" class="maxwidth75" maxlength="11" value="'.$formated_date.'"'; - $retstring.=($disabled?' disabled':''); - $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript - $retstring.='>'; - - // Icone calendrier - if (! $disabled) - { - $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons"'; - $base=DOL_URL_ROOT.'/core/'; - $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');"'; - $retstring.='>'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').'</button>'; - } - else $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>'; + print $retstring; + return; + } - $retstring.='<input type="hidden" id="'.$prefix.'day" name="'.$prefix.'day" value="'.$sday.'">'."\n"; - $retstring.='<input type="hidden" id="'.$prefix.'month" name="'.$prefix.'month" value="'.$smonth.'">'."\n"; - $retstring.='<input type="hidden" id="'.$prefix.'year" name="'.$prefix.'year" value="'.$syear.'">'."\n"; - } - elseif ($usecalendar == 'jquery') - { - if (! $disabled) - { - $retstring.="<script type='text/javascript'>"; - $retstring.="$(function(){ $('#".$prefix."').datepicker({ - dateFormat: '".$langs->trans("FormatDateShortJQueryInput")."', - autoclose: true, - todayHighlight: true,"; - if (empty($conf->global->MAIN_POPUP_CALENDAR_ON_FOCUS)) - { - $retstring.=" - showOn: 'button', - buttonImage: '".DOL_URL_ROOT."/theme/".$conf->theme."/img/object_calendarday.png', - buttonImageOnly: true"; - } - $retstring.=" - }) });"; - $retstring.="</script>"; - } - - // Zone de saisie manuelle de la date - $retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" class="maxwidth75" maxlength="11" value="'.$formated_date.'"'; - $retstring.=($disabled?' disabled':''); - $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript - $retstring.='>'; - - // Icone calendrier - if (! $disabled) - { - /* Not required. Managed by option buttonImage of jquery - $retstring.=img_object($langs->trans("SelectDate"),'calendarday','id="'.$prefix.'id" class="datecallink"'); - $retstring.="<script type='text/javascript'>"; - $retstring.="jQuery(document).ready(function() {"; - $retstring.=' jQuery("#'.$prefix.'id").click(function() {'; - $retstring.=" jQuery('#".$prefix."').focus();"; - $retstring.=' });'; - $retstring.='});'; - $retstring.="</script>";*/ - } - else - { - $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>'; - } - - $retstring.='<input type="hidden" id="'.$prefix.'day" name="'.$prefix.'day" value="'.$sday.'">'."\n"; - $retstring.='<input type="hidden" id="'.$prefix.'month" name="'.$prefix.'month" value="'.$smonth.'">'."\n"; - $retstring.='<input type="hidden" id="'.$prefix.'year" name="'.$prefix.'year" value="'.$syear.'">'."\n"; - } - else - { - $retstring.="Bad value of MAIN_POPUP_CALENDAR"; - } - } - // Show date with combo selects - else - { - //$retstring.='<div class="inline-block">'; - // Day - $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50imp" id="'.$prefix.'day" name="'.$prefix.'day">'; - if ($emptydate || $set_time == -1) - { - $retstring.='<option value="0" selected> </option>'; - } + /** + * Return a HTML select string, built from an array of key+value. + * Note: Do not apply langs->trans function on returned content, content may be entity encoded twice. + * + * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect + * @param array $array Array (key => value) + * @param string|string[] $id Preselected key or preselected keys for multiselect + * @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (key is -1 and value is '' or ' ' if 1, key is -1 and value is text if string), <0 to add an empty value with key that is this value. + * @param int $key_in_label 1 to show key into label with format "[key] value" + * @param int $value_as_key 1 to use value as key + * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container + * @param int $translate 1=Translate and encode value + * @param int $maxlen Length maximum for labels + * @param int $disabled Html select box is disabled + * @param string $sort 'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order + * @param string $morecss Add more class to css styles + * @param int $addjscombo Add js combo + * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set + * @param int $disablebademail Check if an email is found into value and if not disable and colorize entry + * @param int $nohtmlescape No html escaping. + * @return string HTML select string. + * @see multiselectarray + */ + static function selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='', $addjscombo=0, $moreparamonempty='',$disablebademail=0, $nohtmlescape=0) + { + global $conf, $langs; - for ($day = 1 ; $day <= 31; $day++) - { - $retstring.='<option value="'.$day.'"'.($day == $sday ? ' selected':'').'>'.$day.'</option>'; - } + // Do we want a multiselect ? + //$jsbeautify = 0; + //if (preg_match('/^multi/',$htmlname)) $jsbeautify = 1; + $jsbeautify = 1; - $retstring.="</select>"; + if ($value_as_key) $array=array_combine($array, $array); - $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'month" name="'.$prefix.'month">'; - if ($emptydate || $set_time == -1) - { - $retstring.='<option value="0" selected> </option>'; - } + $out=''; - // Month - for ($month = 1 ; $month <= 12 ; $month++) - { - $retstring.='<option value="'.$month.'"'.($month == $smonth?' selected':'').'>'; - $retstring.=dol_print_date(mktime(12,0,0,$month,1,2000),"%b"); - $retstring.="</option>"; - } - $retstring.="</select>"; + // Add code for jquery to use multiselect + if ($addjscombo && empty($conf->dol_use_jmobile) && $jsbeautify) + { + $minLengthToAutocomplete=0; + $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?(constant('REQUIRE_JQUERY_MULTISELECT')?constant('REQUIRE_JQUERY_MULTISELECT'):'select2'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; - // Year - if ($emptydate || $set_time == -1) - { - $retstring.='<input'.($disabled?' disabled':'').' placeholder="'.dol_escape_htmltag($langs->trans("Year")).'" class="flat maxwidth50imp valignmiddle" type="number" min="0" max="3000" maxlength="4" id="'.$prefix.'year" name="'.$prefix.'year" value="'.$syear.'">'; - } - else - { - $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'year" name="'.$prefix.'year">'; + // Enhance with select2 + if ($conf->use_javascript_ajax) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $comboenhancement = ajax_combobox($htmlname); + $out.=$comboenhancement; + } + } - for ($year = $syear - 10; $year < $syear + 10 ; $year++) - { - $retstring.='<option value="'.$year.'"'.($year == $syear ? ' selected':'').'>'.$year.'</option>'; - } - $retstring.="</select>\n"; - } - //$retstring.='</div>'; - } - } + $out.='<select id="'.preg_replace('/^\./','',$htmlname).'" '.($disabled?'disabled ':'').'class="flat '.(preg_replace('/^\./','',$htmlname)).($morecss?' '.$morecss:'').'" name="'.preg_replace('/^\./','',$htmlname).'" '.($moreparam?$moreparam:'').'>'; - if ($d && $h) $retstring.=($h==2?'<br>':' '); + if ($show_empty) + { + $textforempty=' '; + if (! empty($conf->use_javascript_ajax)) $textforempty=' '; // If we use ajaxcombo, we need here to avoid to have an empty element that is too small. + if (! is_numeric($show_empty)) $textforempty=$show_empty; + $out.='<option class="optiongrey" '.($moreparamonempty?$moreparamonempty.' ':'').'value="'.($show_empty < 0 ? $show_empty : -1).'"'.($id == $show_empty ?' selected':'').'>'.$textforempty.'</option>'."\n"; + } - if ($h) - { - // Show hour - $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'hour':'').'" id="'.$prefix.'hour" name="'.$prefix.'hour">'; - if ($emptyhours) $retstring.='<option value="-1"> </option>'; - for ($hour = 0; $hour < 24; $hour++) - { - if (strlen($hour) < 2) $hour = "0" . $hour; - $retstring.='<option value="'.$hour.'"'.(($hour == $shour)?' selected':'').'>'.$hour.(empty($conf->dol_optimize_smallscreen)?'':'H').'</option>'; - } - $retstring.='</select>'; - if ($m && empty($conf->dol_optimize_smallscreen)) $retstring.=":"; - } - - if ($m) - { - // Show minutes - $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'min':'').'" id="'.$prefix.'min" name="'.$prefix.'min">'; - if ($emptyhours) $retstring.='<option value="-1"> </option>'; - for ($min = 0; $min < 60 ; $min++) - { - if (strlen($min) < 2) $min = "0" . $min; - $retstring.='<option value="'.$min.'"'.(($min == $smin)?' selected':'').'>'.$min.(empty($conf->dol_optimize_smallscreen)?'':'').'</option>'; - } - $retstring.='</select>'; - } - - // Add a "Now" link - if ($conf->use_javascript_ajax && $addnowlink) - { - // Script which will be inserted in the onClick of the "Now" link - $reset_scripts = ""; - - // Generate the date part, depending on the use or not of the javascript calendar - $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');'; - /*if ($usecalendar == "eldy") - { - $base=DOL_URL_ROOT.'/core/'; - $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');'; - } - else - { - $reset_scripts .= 'this.form.elements[\''.$prefix.'day\'].value=formatDate(new Date(), \'d\'); '; - $reset_scripts .= 'this.form.elements[\''.$prefix.'month\'].value=formatDate(new Date(), \'M\'); '; - $reset_scripts .= 'this.form.elements[\''.$prefix.'year\'].value=formatDate(new Date(), \'yyyy\'); '; - }*/ - // Update the hour part - if ($h) - { - if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; - //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); '; - $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');'; - if ($fullday) $reset_scripts .= ' } '; - } - // Update the minute part - if ($m) - { - if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; - //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); '; - $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');'; - if ($fullday) $reset_scripts .= ' } '; - } - // If reset_scripts is not empty, print the link with the reset_scripts in the onClick - if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) - { - $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonNow" type="button" name="_useless" value="now" onClick="'.$reset_scripts.'">'; - $retstring.=$langs->trans("Now"); - $retstring.='</button> '; - } - } - - // Add a "Plus one hour" link - if ($conf->use_javascript_ajax && $addplusone) - { - // Script which will be inserted in the onClick of the "Add plusone" link - $reset_scripts = ""; - - // Generate the date part, depending on the use or not of the javascript calendar - $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');'; - // Update the hour part - if ($h) - { - if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; - $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');'; - if ($fullday) $reset_scripts .= ' } '; - } - // Update the minute part - if ($m) - { - if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; - $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');'; - if ($fullday) $reset_scripts .= ' } '; - } - // If reset_scripts is not empty, print the link with the reset_scripts in the onClick - if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) - { - $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonPlusOne" type="button" name="_useless2" value="plusone" onClick="'.$reset_scripts.'">'; - $retstring.=$langs->trans("DateStartPlusOne"); - $retstring.='</button> '; - } - } - - // Add a "Plus one hour" link - if ($conf->use_javascript_ajax && $adddateof) - { - $tmparray=dol_getdate($adddateof); - $retstring.=' - <button class="dpInvisibleButtons datenowlink" id="dateofinvoice" type="button" name="_dateofinvoice" value="now" onclick="jQuery(\'#re\').val(\''.dol_print_date($adddateof,'day').'\');jQuery(\'#reday\').val(\''.$tmparray['mday'].'\');jQuery(\'#remonth\').val(\''.$tmparray['mon'].'\');jQuery(\'#reyear\').val(\''.$tmparray['year'].'\');">'.$langs->trans("DateInvoice").'</a>'; - } - - if (! empty($nooutput)) return $retstring; - - print $retstring; - return; - } - - /** - * Function to show a form to select a duration on a page - * - * @param string $prefix Prefix for input fields - * @param int $iSecond Default preselected duration (number of seconds or '') - * @param int $disabled Disable the combo box - * @param string $typehour If 'select' then input hour and input min is a combo, - * if 'text' input hour is in text and input min is a text, - * if 'textselect' input hour is in text and input min is a combo - * @param integer $minunderhours If 1, show minutes selection under the hours - * @param int $nooutput Do not output html string but return it - * @return string|null - */ - function select_duration($prefix, $iSecond='', $disabled=0, $typehour='select', $minunderhours=0, $nooutput=0) - { - global $langs; - - $retstring=''; - - $hourSelected=0; $minSelected=0; - - // Hours - if ($iSecond != '') - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - - $hourSelected = convertSecondToTime($iSecond,'allhour'); - $minSelected = convertSecondToTime($iSecond,'min'); - } - - if ($typehour=='select' ) - { - $retstring.='<select class="flat" name="'.$prefix.'hour"'.($disabled?' disabled':'').'>'; - for ($hour = 0; $hour < 25; $hour++) // For a duration, we allow 24 hours - { - $retstring.='<option value="'.$hour.'"'; - if ($hourSelected == $hour) - { - $retstring.=" selected"; - } - $retstring.=">".$hour."</option>"; - } - $retstring.="</select>"; - } - elseif ($typehour=='text' || $typehour=='textselect') - { - $retstring.='<input placeholder="'.$langs->trans('HourShort').'" type="number" min="0" size="1" name="'.$prefix.'hour"'.($disabled?' disabled':'').' class="flat maxwidth50 inputhour" value="'.(($hourSelected != '')?((int) $hourSelected):'').'">'; - } - else return 'BadValueForParameterTypeHour'; - - if ($typehour!='text') $retstring.=' '.$langs->trans('HourShort'); - else $retstring.='<span class="hideonsmartphone">:</span>'; - - // Minutes - if ($minunderhours) $retstring.='<br>'; - else $retstring.='<span class="hideonsmartphone"> </span>'; - - if ($typehour=='select' || $typehour=='textselect') - { - $retstring.='<select class="flat" name="'.$prefix.'min"'.($disabled?' disabled':'').'>'; - for ($min = 0; $min <= 55; $min=$min+5) - { - $retstring.='<option value="'.$min.'"'; - if ($minSelected == $min) $retstring.=' selected'; - $retstring.='>'.$min.'</option>'; - } - $retstring.="</select>"; - } - elseif ($typehour=='text' ) - { - $retstring.='<input placeholder="'.$langs->trans('MinuteShort').'" type="number" min="0" size="1" name="'.$prefix.'min"'.($disabled?' disabled':'').' class="flat maxwidth50 inputminute" value="'.(($minSelected != '')?((int) $minSelected):'').'">'; - } - - if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); - - //$retstring.=" "; - - if (! empty($nooutput)) return $retstring; - - print $retstring; - return; - } - - - /** - * Return a HTML select string, built from an array of key+value. - * Note: Do not apply langs->trans function on returned content, content may be entity encoded twice. - * - * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect - * @param array $array Array (key => value) - * @param string|string[] $id Preselected key or preselected keys for multiselect - * @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (key is -1 and value is '' or ' ' if 1, key is -1 and value is text if string), <0 to add an empty value with key that is this value. - * @param int $key_in_label 1 to show key into label with format "[key] value" - * @param int $value_as_key 1 to use value as key - * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container - * @param int $translate 1=Translate and encode value - * @param int $maxlen Length maximum for labels - * @param int $disabled Html select box is disabled - * @param string $sort 'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order - * @param string $morecss Add more class to css styles - * @param int $addjscombo Add js combo - * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set - * @param int $disablebademail Check if an email is found into value and if not disable and colorize entry - * @param int $nohtmlescape No html escaping. - * @return string HTML select string. - * @see multiselectarray - */ - static function selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='', $addjscombo=0, $moreparamonempty='',$disablebademail=0, $nohtmlescape=0) - { - global $conf, $langs; - - // Do we want a multiselect ? - //$jsbeautify = 0; - //if (preg_match('/^multi/',$htmlname)) $jsbeautify = 1; - $jsbeautify = 1; + if (is_array($array)) + { + // Translate + if ($translate) + { + foreach($array as $key => $value) + { + $array[$key]=$langs->trans($value); + } + } - if ($value_as_key) $array=array_combine($array, $array); - - $out=''; - - // Add code for jquery to use multiselect - if ($addjscombo && empty($conf->dol_use_jmobile) && $jsbeautify) - { - $minLengthToAutocomplete=0; - $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?(constant('REQUIRE_JQUERY_MULTISELECT')?constant('REQUIRE_JQUERY_MULTISELECT'):'select2'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; - - // Enhance with select2 - if ($conf->use_javascript_ajax) - { - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement = ajax_combobox($htmlname); - $out.=$comboenhancement; - } - } - - $out.='<select id="'.preg_replace('/^\./','',$htmlname).'" '.($disabled?'disabled ':'').'class="flat '.(preg_replace('/^\./','',$htmlname)).($morecss?' '.$morecss:'').'" name="'.preg_replace('/^\./','',$htmlname).'" '.($moreparam?$moreparam:'').'>'; - - if ($show_empty) - { - $textforempty=' '; - if (! empty($conf->use_javascript_ajax)) $textforempty=' '; // If we use ajaxcombo, we need here to avoid to have an empty element that is too small. - if (! is_numeric($show_empty)) $textforempty=$show_empty; - $out.='<option class="optiongrey" '.($moreparamonempty?$moreparamonempty.' ':'').'value="'.($show_empty < 0 ? $show_empty : -1).'"'.($id == $show_empty ?' selected':'').'>'.$textforempty.'</option>'."\n"; - } - - if (is_array($array)) - { - // Translate - if ($translate) - { - foreach($array as $key => $value) - { - $array[$key]=$langs->trans($value); - } - } - - // Sort + // Sort if ($sort == 'ASC') asort($array); elseif ($sort == 'DESC') arsort($array); - foreach($array as $key => $value) - { - $disabled=''; $style=''; - if (! empty($disablebademail)) - { - if (! preg_match('/<.+@.+>/', $value)) - { - //$value=preg_replace('/'.preg_quote($a,'/').'/', $b, $value); - $disabled=' disabled'; - $style=' class="warning"'; - } - } - $out.='<option value="'.$key.'"'; - $out.=$style.$disabled; - if ($id != '' && $id == $key && ! $disabled) $out.=' selected'; // To preselect a value - $out.='>'; - - if ($key_in_label) - { - if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value)); - else $selectOptionValue = $key.' - '.($maxlen?dol_trunc($value,$maxlen):$value); - } - else - { - if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value); - else $selectOptionValue = $maxlen?dol_trunc($value,$maxlen):$value; - if ($value == '' || $value == '-') $selectOptionValue=' '; - } - //var_dump($selectOptionValue); - $out.=$selectOptionValue; - $out.="</option>\n"; - } - } - - $out.="</select>"; - return $out; - } - - - /** - * Return a HTML select string, built from an array of key+value but content returned into select come from an Ajax call of an URL. - * Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice. - * - * @param string $htmlname Name of html select area - * @param string $url Url. Must return a json_encode of array(key=>array('text'=>'A text', 'url'=>'An url'), ...) - * @param string $id Preselected key - * @param string $moreparam Add more parameters onto the select tag - * @param string $moreparamtourl Add more parameters onto the Ajax called URL - * @param int $disabled Html select box is disabled - * @param int $minimumInputLength Minimum Input Length - * @param string $morecss Add more class to css styles - * @param int $callurlonselect If set to 1, some code is added so an url return by the ajax is called when value is selected. - * @param string $placeholder String to use as placeholder - * @param integer $acceptdelayedhtml 1 if caller request to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) - * @return string HTML select string - */ - static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0) - { - global $conf, $langs; - global $delayedhtmlcontent; - - // TODO Use an internal dolibarr component instead of select2 - if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && ! defined('REQUIRE_JQUERY_MULTISELECT')) return ''; - - $out='<input type="text" class="'.$htmlname.($morecss?' '.$morecss:'').'" '.($moreparam?$moreparam.' ':'').'name="'.$htmlname.'">'; - - $tmpplugin='select2'; - $outdelayed="\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' --> + foreach($array as $key => $value) + { + $disabled=''; $style=''; + if (! empty($disablebademail)) + { + if (! preg_match('/<.+@.+>/', $value)) + { + //$value=preg_replace('/'.preg_quote($a,'/').'/', $b, $value); + $disabled=' disabled'; + $style=' class="warning"'; + } + } + $out.='<option value="'.$key.'"'; + $out.=$style.$disabled; + if ($id != '' && $id == $key && ! $disabled) $out.=' selected'; // To preselect a value + $out.='>'; + + if ($key_in_label) + { + if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value)); + else $selectOptionValue = $key.' - '.($maxlen?dol_trunc($value,$maxlen):$value); + } + else + { + if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value); + else $selectOptionValue = $maxlen?dol_trunc($value,$maxlen):$value; + if ($value == '' || $value == '-') $selectOptionValue=' '; + } + //var_dump($selectOptionValue); + $out.=$selectOptionValue; + $out.="</option>\n"; + } + } + + $out.="</select>"; + return $out; + } + + + /** + * Return a HTML select string, built from an array of key+value but content returned into select come from an Ajax call of an URL. + * Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice. + * + * @param string $htmlname Name of html select area + * @param string $url Url. Must return a json_encode of array(key=>array('text'=>'A text', 'url'=>'An url'), ...) + * @param string $id Preselected key + * @param string $moreparam Add more parameters onto the select tag + * @param string $moreparamtourl Add more parameters onto the Ajax called URL + * @param int $disabled Html select box is disabled + * @param int $minimumInputLength Minimum Input Length + * @param string $morecss Add more class to css styles + * @param int $callurlonselect If set to 1, some code is added so an url return by the ajax is called when value is selected. + * @param string $placeholder String to use as placeholder + * @param integer $acceptdelayedhtml 1 if caller request to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) + * @return string HTML select string + */ + static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0) + { + global $conf, $langs; + global $delayedhtmlcontent; + + // TODO Use an internal dolibarr component instead of select2 + if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && ! defined('REQUIRE_JQUERY_MULTISELECT')) return ''; + + $out='<input type="text" class="'.$htmlname.($morecss?' '.$morecss:'').'" '.($moreparam?$moreparam.' ':'').'name="'.$htmlname.'">'; + + $tmpplugin='select2'; + $outdelayed="\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' --> <script type="text/javascript"> $(document).ready(function () { @@ -5304,41 +5304,41 @@ class Form if ($acceptdelayedhtml) { - $delayedhtmlcontent.=$outdelayed; + $delayedhtmlcontent.=$outdelayed; } else { - $out.=$outdelayed; + $out.=$outdelayed; } return $out; - } - - /** - * Show a multiselect form from an array. - * - * @param string $htmlname Name of select - * @param array $array Array with key+value - * @param array $selected Array with key+value preselected - * @param int $key_in_label 1 pour afficher la key dans la valeur "[key] value" - * @param int $value_as_key 1 to use value as key - * @param string $morecss Add more css style - * @param int $translate Translate and encode value - * @param int $width Force width of select box. May be used only when using jquery couch. Example: 250, 95% - * @param string $moreattrib Add more options on select component. Example: 'disabled' - * @param string $elemtype Type of element we show ('category', ...) - * @return string HTML multiselect string - * @see selectarray - */ - static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $morecss='', $translate=0, $width=0, $moreattrib='',$elemtype='') - { - global $conf, $langs; - - $out = ''; - - // Add code for jquery to use multiselect - if (! empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT')) - { - $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; + } + + /** + * Show a multiselect form from an array. + * + * @param string $htmlname Name of select + * @param array $array Array with key+value + * @param array $selected Array with key+value preselected + * @param int $key_in_label 1 pour afficher la key dans la valeur "[key] value" + * @param int $value_as_key 1 to use value as key + * @param string $morecss Add more css style + * @param int $translate Translate and encode value + * @param int $width Force width of select box. May be used only when using jquery couch. Example: 250, 95% + * @param string $moreattrib Add more options on select component. Example: 'disabled' + * @param string $elemtype Type of element we show ('category', ...) + * @return string HTML multiselect string + * @see selectarray + */ + static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $morecss='', $translate=0, $width=0, $moreattrib='',$elemtype='') + { + global $conf, $langs; + + $out = ''; + + // Add code for jquery to use multiselect + if (! empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT')) + { + $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; $out.="\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' --> <script type="text/javascript"> function formatResult(record) {'."\n"; @@ -5375,89 +5375,89 @@ class Form }); }); </script>'; - } + } - // Try also magic suggest + // Try also magic suggest $out .= '<select id="'.$htmlname.'" class="multiselect'.($morecss?' '.$morecss:'').'" multiple name="'.$htmlname.'[]"'.($moreattrib?' '.$moreattrib:'').($width?' style="width: '.(preg_match('/%/',$width)?$width:$width.'px').'"':'').'>'."\n"; - if (is_array($array) && ! empty($array)) - { - if ($value_as_key) $array=array_combine($array, $array); - - if (! empty($array)) - { - foreach ($array as $key => $value) - { - $out.= '<option value="'.$key.'"'; - if (is_array($selected) && ! empty($selected) && in_array($key, $selected) && !empty($key)) - { - $out.= ' selected'; - } - $out.= '>'; - - $newval = ($translate ? $langs->trans($value) : $value); - $newval = ($key_in_label ? $key.' - '.$newval : $newval); - $out.= dol_htmlentitiesbr($newval); - $out.= '</option>'."\n"; - } - } - } - $out.= '</select>'."\n"; - - return $out; - } - - - /** - * Show a multiselect form from an array. - * - * @param string $htmlname Name of select - * @param array $array Array with array of fields we could show. This array may be modified according to setup of user. - * @param string $varpage Id of context for page. Can be set with $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; - * @return string HTML multiselect string - * @see selectarray - */ - static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage) - { - global $conf,$langs,$user; - - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return ''; - - $tmpvar="MAIN_SELECTEDFIELDS_".$varpage; - if (! empty($user->conf->$tmpvar)) - { - $tmparray=explode(',', $user->conf->$tmpvar); - foreach($array as $key => $val) - { - //var_dump($key); - //var_dump($tmparray); - if (in_array($key, $tmparray)) $array[$key]['checked']=1; - else $array[$key]['checked']=0; - } - } - //var_dump($array); + if (is_array($array) && ! empty($array)) + { + if ($value_as_key) $array=array_combine($array, $array); + + if (! empty($array)) + { + foreach ($array as $key => $value) + { + $out.= '<option value="'.$key.'"'; + if (is_array($selected) && ! empty($selected) && in_array($key, $selected) && !empty($key)) + { + $out.= ' selected'; + } + $out.= '>'; + + $newval = ($translate ? $langs->trans($value) : $value); + $newval = ($key_in_label ? $key.' - '.$newval : $newval); + $out.= dol_htmlentitiesbr($newval); + $out.= '</option>'."\n"; + } + } + } + $out.= '</select>'."\n"; + + return $out; + } - $lis=''; - $listcheckedstring=''; - foreach($array as $key => $val) - { - /* var_dump($val); + /** + * Show a multiselect form from an array. + * + * @param string $htmlname Name of select + * @param array $array Array with array of fields we could show. This array may be modified according to setup of user. + * @param string $varpage Id of context for page. Can be set with $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + * @return string HTML multiselect string + * @see selectarray + */ + static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage) + { + global $conf,$langs,$user; + + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return ''; + + $tmpvar="MAIN_SELECTEDFIELDS_".$varpage; + if (! empty($user->conf->$tmpvar)) + { + $tmparray=explode(',', $user->conf->$tmpvar); + foreach($array as $key => $val) + { + //var_dump($key); + //var_dump($tmparray); + if (in_array($key, $tmparray)) $array[$key]['checked']=1; + else $array[$key]['checked']=0; + } + } + //var_dump($array); + + $lis=''; + $listcheckedstring=''; + + foreach($array as $key => $val) + { + /* var_dump($val); var_dump(array_key_exists('enabled', $val)); var_dump(!$val['enabled']);*/ - if (array_key_exists('enabled', $val) && isset($val['enabled']) && ! $val['enabled']) - { - unset($array[$key]); // We don't want this field - continue; - } - if ($val['label']) - { - $lis.='<li><input type="checkbox" value="'.$key.'"'.(empty($val['checked'])?'':' checked="checked"').'/>'.dol_escape_htmltag($langs->trans($val['label'])).'</li>'; - $listcheckedstring.=(empty($val['checked'])?'':$key.','); - } - } - - $out ='<!-- Component multiSelectArrayWithCheckbox '.$htmlname.' --> + if (array_key_exists('enabled', $val) && isset($val['enabled']) && ! $val['enabled']) + { + unset($array[$key]); // We don't want this field + continue; + } + if ($val['label']) + { + $lis.='<li><input type="checkbox" value="'.$key.'"'.(empty($val['checked'])?'':' checked="checked"').'/>'.dol_escape_htmltag($langs->trans($val['label'])).'</li>'; + $listcheckedstring.=(empty($val['checked'])?'':$key.','); + } + } + + $out ='<!-- Component multiSelectArrayWithCheckbox '.$htmlname.' --> <dl class="dropdown"> <dt> @@ -5494,15 +5494,15 @@ class Form </script> '; - return $out; - } + return $out; + } /** * Render list of categories linked to object with id $id and type $type * * @param int $id Id of object - * @param string $type Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated. - * @param int $rendermode 0=Default, use multiselect. 1=Emulate multiselect (recommended) + * @param string $type Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated. + * @param int $rendermode 0=Default, use multiselect. 1=Emulate multiselect (recommended) * @return string String with categories */ function showCategories($id, $type, $rendermode=0) @@ -5542,145 +5542,145 @@ class Form } - /** - * Show linked object block. - * - * @param CommonObject $object Object we want to show links to - * @param string $morehtmlright More html to show on right of title - * @return int <0 if KO, >=0 if OK - */ - function showLinkedObjectBlock($object, $morehtmlright='') - { - global $conf,$langs,$hookmanager; - global $bc; + /** + * Show linked object block. + * + * @param CommonObject $object Object we want to show links to + * @param string $morehtmlright More html to show on right of title + * @return int <0 if KO, >=0 if OK + */ + function showLinkedObjectBlock($object, $morehtmlright='') + { + global $conf,$langs,$hookmanager; + global $bc; - $object->fetchObjectLinked(); + $object->fetchObjectLinked(); - // Bypass the default method - $hookmanager->initHooks(array('commonobject')); - $parameters=array(); - $reshook=$hookmanager->executeHooks('showLinkedObjectBlock',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + // Bypass the default method + $hookmanager->initHooks(array('commonobject')); + $parameters=array(); + $reshook=$hookmanager->executeHooks('showLinkedObjectBlock',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook)) - { - $nbofdifferenttypes = count($object->linkedObjects); + if (empty($reshook)) + { + $nbofdifferenttypes = count($object->linkedObjects); - print '<!-- showLinkedObjectBlock -->'; - print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '', 0, 0, 'showlinkedobjectblock'); + print '<!-- showLinkedObjectBlock -->'; + print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '', 0, 0, 'showlinkedobjectblock'); - print '<div class="div-table-responsive-no-min">'; - print '<table class="noborder allwidth">'; + print '<div class="div-table-responsive-no-min">'; + print '<table class="noborder allwidth">'; - print '<tr class="liste_titre">'; - print '<td>'.$langs->trans("Type").'</td>'; - print '<td>'.$langs->trans("Ref").'</td>'; - print '<td align="center"></td>'; - print '<td align="center">'.$langs->trans("Date").'</td>'; - print '<td align="right">'.$langs->trans("AmountHTShort").'</td>'; - print '<td align="right">'.$langs->trans("Status").'</td>'; - print '<td></td>'; - print '</tr>'; + print '<tr class="liste_titre">'; + print '<td>'.$langs->trans("Type").'</td>'; + print '<td>'.$langs->trans("Ref").'</td>'; + print '<td align="center"></td>'; + print '<td align="center">'.$langs->trans("Date").'</td>'; + print '<td align="right">'.$langs->trans("AmountHTShort").'</td>'; + print '<td align="right">'.$langs->trans("Status").'</td>'; + print '<td></td>'; + print '</tr>'; - $nboftypesoutput=0; + $nboftypesoutput=0; - foreach($object->linkedObjects as $objecttype => $objects) - { - $tplpath = $element = $subelement = $objecttype; + foreach($object->linkedObjects as $objecttype => $objects) + { + $tplpath = $element = $subelement = $objecttype; - if ($objecttype != 'supplier_proposal' && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - $tplpath = $element.'/'.$subelement; - } - $tplname='linkedobjectblock'; + if ($objecttype != 'supplier_proposal' && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + $tplpath = $element.'/'.$subelement; + } + $tplname='linkedobjectblock'; - // To work with non standard path - if ($objecttype == 'facture') { - $tplpath = 'compta/'.$element; - if (empty($conf->facture->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'facturerec') { - $tplpath = 'compta/facture'; - $tplname = 'linkedobjectblockForRec'; - if (empty($conf->facture->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'propal') { - $tplpath = 'comm/'.$element; - if (empty($conf->propal->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'supplier_proposal') { - if (empty($conf->supplier_proposal->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'shipping' || $objecttype == 'shipment') { - $tplpath = 'expedition'; - if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'delivery') { - $tplpath = 'livraison'; - if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'invoice_supplier') { - $tplpath = 'fourn/facture'; - } - else if ($objecttype == 'order_supplier') { - $tplpath = 'fourn/commande'; - } - else if ($objecttype == 'expensereport') { - $tplpath = 'expensereport'; - } - else if ($objecttype == 'subscription') { - $tplpath = 'adherents'; - } + // To work with non standard path + if ($objecttype == 'facture') { + $tplpath = 'compta/'.$element; + if (empty($conf->facture->enabled)) continue; // Do not show if module disabled + } + else if ($objecttype == 'facturerec') { + $tplpath = 'compta/facture'; + $tplname = 'linkedobjectblockForRec'; + if (empty($conf->facture->enabled)) continue; // Do not show if module disabled + } + else if ($objecttype == 'propal') { + $tplpath = 'comm/'.$element; + if (empty($conf->propal->enabled)) continue; // Do not show if module disabled + } + else if ($objecttype == 'supplier_proposal') { + if (empty($conf->supplier_proposal->enabled)) continue; // Do not show if module disabled + } + else if ($objecttype == 'shipping' || $objecttype == 'shipment') { + $tplpath = 'expedition'; + if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled + } + else if ($objecttype == 'delivery') { + $tplpath = 'livraison'; + if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled + } + else if ($objecttype == 'invoice_supplier') { + $tplpath = 'fourn/facture'; + } + else if ($objecttype == 'order_supplier') { + $tplpath = 'fourn/commande'; + } + else if ($objecttype == 'expensereport') { + $tplpath = 'expensereport'; + } + else if ($objecttype == 'subscription') { + $tplpath = 'adherents'; + } - global $linkedObjectBlock; - $linkedObjectBlock = $objects; + global $linkedObjectBlock; + $linkedObjectBlock = $objects; - // Output template part (modules that overwrite templates must declare this into descriptor) - $dirtpls=array_merge($conf->modules_parts['tpl'],array('/'.$tplpath.'/tpl')); - foreach($dirtpls as $reldir) - { - if ($nboftypesoutput == ($nbofdifferenttypes - 1)) // No more type to show after - { - global $noMoreLinkedObjectBlockAfter; - $noMoreLinkedObjectBlockAfter=1; - } - - $res=@include dol_buildpath($reldir.'/'.$tplname.'.tpl.php'); - if ($res) - { - $nboftypesoutput++; - break; - } - } - } + // Output template part (modules that overwrite templates must declare this into descriptor) + $dirtpls=array_merge($conf->modules_parts['tpl'],array('/'.$tplpath.'/tpl')); + foreach($dirtpls as $reldir) + { + if ($nboftypesoutput == ($nbofdifferenttypes - 1)) // No more type to show after + { + global $noMoreLinkedObjectBlockAfter; + $noMoreLinkedObjectBlockAfter=1; + } - if (! $nboftypesoutput) - { - print '<tr><td class="impair opacitymedium" colspan="7">'.$langs->trans("None").'</td></tr>'; - } + $res=@include dol_buildpath($reldir.'/'.$tplname.'.tpl.php'); + if ($res) + { + $nboftypesoutput++; + break; + } + } + } - print '</table>'; + if (! $nboftypesoutput) + { + print '<tr><td class="impair opacitymedium" colspan="7">'.$langs->trans("None").'</td></tr>'; + } + + print '</table>'; print '</div>'; - return $nbofdifferenttypes; - } - } - - /** - * Show block with links to link to other objects. - * - * @param CommonObject $object Object we want to show links to - * @param array $restrictlinksto Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction. - * @param array $excludelinksto Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion. - * @return string <0 if KO, >0 if OK - */ - function showLinkToObjectBlock($object, $restrictlinksto=array(), $excludelinksto=array()) - { - global $conf, $langs, $hookmanager; - global $bc; + return $nbofdifferenttypes; + } + } + + /** + * Show block with links to link to other objects. + * + * @param CommonObject $object Object we want to show links to + * @param array $restrictlinksto Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction. + * @param array $excludelinksto Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion. + * @return string <0 if KO, >0 if OK + */ + function showLinkToObjectBlock($object, $restrictlinksto=array(), $excludelinksto=array()) + { + global $conf, $langs, $hookmanager; + global $bc; $linktoelem=''; $linktoelemlist=''; @@ -5690,8 +5690,8 @@ class Form $possiblelinks=array(); if (is_object($object->thirdparty) && ! empty($object->thirdparty->id) && $object->thirdparty->id > 0) { - $listofidcompanytoscan=$object->thirdparty->id; - if (($object->thirdparty->parent > 0) && ! empty($conf->global->THIRDPARTY_INCLUDE_PARENT_IN_LINKTO)) $listofidcompanytoscan.=','.$object->thirdparty->parent; + $listofidcompanytoscan=$object->thirdparty->id; + if (($object->thirdparty->parent > 0) && ! empty($conf->global->THIRDPARTY_INCLUDE_PARENT_IN_LINKTO)) $listofidcompanytoscan.=','.$object->thirdparty->parent; if (($object->fk_project > 0) && ! empty($conf->global->THIRDPARTY_INCLUDE_PROJECT_THIRDPARY_IN_LINKTO)) { include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; @@ -5701,16 +5701,16 @@ class Form unset($tmpproject); } - $possiblelinks=array( - 'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('propal').')'), - 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande').')'), - 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture').')'), - 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('contract').')'), - 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('intervention').')'), - 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('supplier_proposal').')'), - 'order_supplier'=>array('enabled'=>$conf->supplier_order->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande_fournisseur').')'), - 'invoice_supplier'=>array('enabled'=>$conf->supplier_invoice->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture_fourn').')') - ); + $possiblelinks=array( + 'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('propal').')'), + 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande').')'), + 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture').')'), + 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('contract').')'), + 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('intervention').')'), + 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('supplier_proposal').')'), + 'order_supplier'=>array('enabled'=>$conf->supplier_order->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande_fournisseur').')'), + 'invoice_supplier'=>array('enabled'=>$conf->supplier_invoice->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture_fourn').')') + ); } global $action; @@ -5721,17 +5721,17 @@ class Form $reshook=$hookmanager->executeHooks('showLinkToObjectBlock',$parameters,$object,$action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { - if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) - { - $possiblelinks=array_merge($possiblelinks, $hookmanager->resArray); - } + if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) + { + $possiblelinks=array_merge($possiblelinks, $hookmanager->resArray); + } } else if ($reshook > 0) { - if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) - { - $possiblelinks=$hookmanager->resArray; - } + if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) + { + $possiblelinks=$hookmanager->resArray; + } } foreach($possiblelinks as $key => $possiblelink) @@ -5801,7 +5801,7 @@ class Form if ($linktoelemlist) { - $linktoelem=' + $linktoelem=' <dl class="dropdown" id="linktoobjectname"> <dt><a href="#linktoobjectname">'.$langs->trans("LinkTo").'...</a></dt> <dd> @@ -5814,7 +5814,7 @@ class Form } else { - $linktoelem=''; + $linktoelem=''; } print '<!-- Add js to show linkto box --> @@ -5830,180 +5830,180 @@ class Form '; return $linktoelem; - } - - /** - * Return an html string with a select combo box to choose yes or no - * - * @param string $htmlname Name of html select field - * @param string $value Pre-selected value - * @param int $option 0 return yes/no, 1 return 1/0 - * @param bool $disabled true or false - * @param int $useempty 1=Add empty line - * @return string See option - */ - function selectyesno($htmlname, $value='', $option=0, $disabled=false, $useempty='') - { - global $langs; - - $yes="yes"; $no="no"; - if ($option) - { - $yes="1"; - $no="0"; - } - - $disabled = ($disabled ? ' disabled' : ''); - - $resultyesno = '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'"'.$disabled.'>'."\n"; - if ($useempty) $resultyesno .= '<option value="-1"'.(($value < 0)?' selected':'').'> </option>'."\n"; - if (("$value" == 'yes') || ($value == 1)) - { - $resultyesno .= '<option value="'.$yes.'" selected>'.$langs->trans("Yes").'</option>'."\n"; - $resultyesno .= '<option value="'.$no.'">'.$langs->trans("No").'</option>'."\n"; - } - else - { - $selected=(($useempty && $value != '0' && $value != 'no')?'':' selected'); - $resultyesno .= '<option value="'.$yes.'">'.$langs->trans("Yes").'</option>'."\n"; - $resultyesno .= '<option value="'.$no.'"'.$selected.'>'.$langs->trans("No").'</option>'."\n"; - } - $resultyesno .= '</select>'."\n"; - return $resultyesno; - } - - - - /** - * Return list of export templates - * - * @param string $selected Id modele pre-selectionne - * @param string $htmlname Name of HTML select - * @param string $type Type of searched templates - * @param int $useempty Affiche valeur vide dans liste - * @return void - */ - function select_export_model($selected='',$htmlname='exportmodelid',$type='',$useempty=0) - { - - $sql = "SELECT rowid, label"; - $sql.= " FROM ".MAIN_DB_PREFIX."export_model"; - $sql.= " WHERE type = '".$type."'"; - $sql.= " ORDER BY rowid"; - $result = $this->db->query($sql); - if ($result) - { - print '<select class="flat" name="'.$htmlname.'">'; - if ($useempty) - { - print '<option value="-1"> </option>'; - } + } - $num = $this->db->num_rows($result); - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($result); - if ($selected == $obj->rowid) - { - print '<option value="'.$obj->rowid.'" selected>'; - } - else - { - print '<option value="'.$obj->rowid.'">'; - } - print $obj->label; - print '</option>'; - $i++; - } - print "</select>"; - } - else { - dol_print_error($this->db); - } - } - - /** - * Return a HTML area with the reference of object and a navigation bar for a business object - * Note: To add a particular filter on select, you can have $object->next_prev_filter set to add SQL criterias. - * - * @param object $object Object to show. - * @param string $paramid Name of parameter to use to name the id into the URL next/previous link. - * @param string $morehtml More html content to output just before the nav bar. - * @param int $shownav Show Condition (navigation is shown if value is 1). - * @param string $fieldid Name of field id into database to use for select next and previous (we make the select max and min on this field). Use 'none' to disable next/prev. - * @param string $fieldref Name of field ref of object (object->ref) to show or 'none' to not show ref. - * @param string $morehtmlref More html to show after ref. - * @param string $moreparam More param to add in nav link url. Must start with '&...'. - * @param int $nodbprefix Do not include DB prefix to forge table name. - * @param string $morehtmlleft More html code to show before ref. - * @param string $morehtmlstatus More html code to show under navigation arrows (status place). - * @param string $morehtmlright More html code to show after ref. - * @return string Portion HTML with ref + navigation buttons - */ + /** + * Return an html string with a select combo box to choose yes or no + * + * @param string $htmlname Name of html select field + * @param string $value Pre-selected value + * @param int $option 0 return yes/no, 1 return 1/0 + * @param bool $disabled true or false + * @param int $useempty 1=Add empty line + * @return string See option + */ + function selectyesno($htmlname, $value='', $option=0, $disabled=false, $useempty='') + { + global $langs; + + $yes="yes"; $no="no"; + if ($option) + { + $yes="1"; + $no="0"; + } + + $disabled = ($disabled ? ' disabled' : ''); + + $resultyesno = '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'"'.$disabled.'>'."\n"; + if ($useempty) $resultyesno .= '<option value="-1"'.(($value < 0)?' selected':'').'> </option>'."\n"; + if (("$value" == 'yes') || ($value == 1)) + { + $resultyesno .= '<option value="'.$yes.'" selected>'.$langs->trans("Yes").'</option>'."\n"; + $resultyesno .= '<option value="'.$no.'">'.$langs->trans("No").'</option>'."\n"; + } + else + { + $selected=(($useempty && $value != '0' && $value != 'no')?'':' selected'); + $resultyesno .= '<option value="'.$yes.'">'.$langs->trans("Yes").'</option>'."\n"; + $resultyesno .= '<option value="'.$no.'"'.$selected.'>'.$langs->trans("No").'</option>'."\n"; + } + $resultyesno .= '</select>'."\n"; + return $resultyesno; + } + + + + /** + * Return list of export templates + * + * @param string $selected Id modele pre-selectionne + * @param string $htmlname Name of HTML select + * @param string $type Type of searched templates + * @param int $useempty Affiche valeur vide dans liste + * @return void + */ + function select_export_model($selected='',$htmlname='exportmodelid',$type='',$useempty=0) + { + + $sql = "SELECT rowid, label"; + $sql.= " FROM ".MAIN_DB_PREFIX."export_model"; + $sql.= " WHERE type = '".$type."'"; + $sql.= " ORDER BY rowid"; + $result = $this->db->query($sql); + if ($result) + { + print '<select class="flat" name="'.$htmlname.'">'; + if ($useempty) + { + print '<option value="-1"> </option>'; + } + + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + if ($selected == $obj->rowid) + { + print '<option value="'.$obj->rowid.'" selected>'; + } + else + { + print '<option value="'.$obj->rowid.'">'; + } + print $obj->label; + print '</option>'; + $i++; + } + print "</select>"; + } + else { + dol_print_error($this->db); + } + } + + /** + * Return a HTML area with the reference of object and a navigation bar for a business object + * Note: To add a particular filter on select, you can have $object->next_prev_filter set to add SQL criterias. + * + * @param object $object Object to show. + * @param string $paramid Name of parameter to use to name the id into the URL next/previous link. + * @param string $morehtml More html content to output just before the nav bar. + * @param int $shownav Show Condition (navigation is shown if value is 1). + * @param string $fieldid Name of field id into database to use for select next and previous (we make the select max and min on this field). Use 'none' to disable next/prev. + * @param string $fieldref Name of field ref of object (object->ref) to show or 'none' to not show ref. + * @param string $morehtmlref More html to show after ref. + * @param string $moreparam More param to add in nav link url. Must start with '&...'. + * @param int $nodbprefix Do not include DB prefix to forge table name. + * @param string $morehtmlleft More html code to show before ref. + * @param string $morehtmlstatus More html code to show under navigation arrows (status place). + * @param string $morehtmlright More html code to show after ref. + * @return string Portion HTML with ref + navigation buttons + */ function showrefnav($object,$paramid,$morehtml='',$shownav=1,$fieldid='rowid',$fieldref='ref',$morehtmlref='',$moreparam='',$nodbprefix=0,$morehtmlleft='',$morehtmlstatus='',$morehtmlright='') { global $langs,$conf,$hookmanager; $ret=''; - if (empty($fieldid)) $fieldid='rowid'; - if (empty($fieldref)) $fieldref='ref'; - - // Add where from hooks - if (is_object($hookmanager)) - { - $parameters=array(); - $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters, $object); // Note that $action and $object may have been modified by hook - $object->next_prev_filter.=$hookmanager->resPrint; - } - - $previous_ref = $next_ref = ''; - if ($shownav) - { - //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam"; - $object->load_previous_next_ref((isset($object->next_prev_filter)?$object->next_prev_filter:''),$fieldid,$nodbprefix); - - $navurl = $_SERVER["PHP_SELF"]; - // Special case for project/task page - if ($paramid == 'project_ref') - { - $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document)\.php/','/tasks.php',$navurl); - $paramid='ref'; - } - $previous_ref = $object->ref_previous?'<a href="'.$navurl.'?'.$paramid.'='.urlencode($object->ref_previous).$moreparam.'"><i class="fa fa-chevron-left"></i></a>':'<span class="inactive"><i class="fa fa-chevron-left opacitymedium"></i></span>'; - $next_ref = $object->ref_next?'<a href="'.$navurl.'?'.$paramid.'='.urlencode($object->ref_next).$moreparam.'"><i class="fa fa-chevron-right"></i></a>':'<span class="inactive"><i class="fa fa-chevron-right opacitymedium"></i></span>'; - } - - //print "xx".$previous_ref."x".$next_ref; - $ret.='<!-- Start banner content --><div style="vertical-align: middle">'; - - // Right part of banner + if (empty($fieldid)) $fieldid='rowid'; + if (empty($fieldref)) $fieldref='ref'; + + // Add where from hooks + if (is_object($hookmanager)) + { + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters, $object); // Note that $action and $object may have been modified by hook + $object->next_prev_filter.=$hookmanager->resPrint; + } + + $previous_ref = $next_ref = ''; + if ($shownav) + { + //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam"; + $object->load_previous_next_ref((isset($object->next_prev_filter)?$object->next_prev_filter:''),$fieldid,$nodbprefix); + + $navurl = $_SERVER["PHP_SELF"]; + // Special case for project/task page + if ($paramid == 'project_ref') + { + $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document)\.php/','/tasks.php',$navurl); + $paramid='ref'; + } + $previous_ref = $object->ref_previous?'<a href="'.$navurl.'?'.$paramid.'='.urlencode($object->ref_previous).$moreparam.'"><i class="fa fa-chevron-left"></i></a>':'<span class="inactive"><i class="fa fa-chevron-left opacitymedium"></i></span>'; + $next_ref = $object->ref_next?'<a href="'.$navurl.'?'.$paramid.'='.urlencode($object->ref_next).$moreparam.'"><i class="fa fa-chevron-right"></i></a>':'<span class="inactive"><i class="fa fa-chevron-right opacitymedium"></i></span>'; + } + + //print "xx".$previous_ref."x".$next_ref; + $ret.='<!-- Start banner content --><div style="vertical-align: middle">'; + + // Right part of banner if ($morehtmlright) $ret.='<div class="inline-block floatleft">'.$morehtmlright.'</div>'; if ($previous_ref || $next_ref || $morehtml) { $ret.='<div class="pagination paginationref"><ul class="right">'; } - if ($morehtml) - { - $ret.='<li class="noborder litext">'.$morehtml.'</li>'; - } - if ($shownav && ($previous_ref || $next_ref)) - { - $ret.='<li class="pagination">'.$previous_ref.'</li>'; - $ret.='<li class="pagination">'.$next_ref.'</li>'; - } - if ($previous_ref || $next_ref || $morehtml) - { - $ret.='</ul></div>'; - } + if ($morehtml) + { + $ret.='<li class="noborder litext">'.$morehtml.'</li>'; + } + if ($shownav && ($previous_ref || $next_ref)) + { + $ret.='<li class="pagination">'.$previous_ref.'</li>'; + $ret.='<li class="pagination">'.$next_ref.'</li>'; + } + if ($previous_ref || $next_ref || $morehtml) + { + $ret.='</ul></div>'; + } if ($morehtmlstatus) $ret.='<div class="statusref">'.$morehtmlstatus.'</div>'; - // Left part of banner + // Left part of banner if ($morehtmlleft) { - if ($conf->browser->layout == 'phone') $ret.='<div class="floatleft">'.$morehtmlleft.'</div>'; // class="center" to have photo in middle - else $ret.='<div class="inline-block floatleft">'.$morehtmlleft.'</div>'; + if ($conf->browser->layout == 'phone') $ret.='<div class="floatleft">'.$morehtmlleft.'</div>'; // class="center" to have photo in middle + else $ret.='<div class="inline-block floatleft">'.$morehtmlleft.'</div>'; } //if ($conf->browser->layout == 'phone') $ret.='<div class="clearboth"></div>'; @@ -6012,15 +6012,15 @@ class Form // For thirdparty, contact, user, member, the ref is the id, so we show something else if ($object->element == 'societe') { - $ret.=dol_htmlentities($object->name); + $ret.=dol_htmlentities($object->name); } else if (in_array($object->element, array('contact', 'user', 'usergroup', 'member'))) { - $ret.=dol_htmlentities($object->getFullName($langs)); + $ret.=dol_htmlentities($object->getFullName($langs)); } else if (in_array($object->element, array('action', 'agenda'))) { - $ret.=$object->ref.'<br>'.$object->label; + $ret.=$object->ref.'<br>'.$object->label; } else if (in_array($object->element, array('adherent_type'))) { @@ -6035,159 +6035,159 @@ class Form if ($morehtmlref) { - $ret.=' '.$morehtmlref; + $ret.=' '.$morehtmlref; } $ret.='</div>'; $ret.='</div><!-- End banner content -->'; - return $ret; - } - - - /** - * Return HTML code to output a barcode - * - * @param Object $object Object containing data to retrieve file name - * @param int $width Width of photo - * @return string HTML code to output barcode - */ - function showbarcode(&$object,$width=100) - { - global $conf; - - //Check if barcode is filled in the card - if (empty($object->barcode)) return ''; - - // Complete object if not complete - if (empty($object->barcode_type_code) || empty($object->barcode_type_coder)) - { - $result = $object->fetch_barcode(); - //Check if fetch_barcode() failed - if ($result < 1) return '<!-- ErrorFetchBarcode -->'; - } - - // Barcode image - $url=DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&generator='.urlencode($object->barcode_type_coder).'&code='.urlencode($object->barcode).'&encoding='.urlencode($object->barcode_type_code); - $out ='<!-- url barcode = '.$url.' -->'; - $out.='<img src="'.$url.'">'; - return $out; - } - - /** - * Return HTML code to output a photo - * - * @param string $modulepart Key to define module concerned ('societe', 'userphoto', 'memberphoto') - * @param object $object Object containing data to retrieve file name - * @param int $width Width of photo - * @param int $height Height of photo (auto if 0) - * @param int $caneditfield Add edit fields - * @param string $cssclass CSS name to use on img for photo - * @param string $imagesize 'mini', 'small' or '' (original) - * @param int $addlinktofullsize Add link to fullsize image - * @param int $cache 1=Accept to use image in cache - * @return string HTML code to output photo - */ - static function showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0) - { - global $conf,$langs; - - $entity = (! empty($object->entity) ? $object->entity : $conf->entity); - $id = (! empty($object->id) ? $object->id : $object->rowid); - - $ret='';$dir='';$file='';$originalfile='';$altfile='';$email=''; - if ($modulepart=='societe') - { - $dir=$conf->societe->multidir_output[$entity]; - if (! empty($object->logo)) - { - if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_mini'); // getImageFileNameForSize include the thumbs - else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_small'); - else $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo; - $originalfile=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo; - } - $email=$object->email; - } - else if ($modulepart=='contact') - { - $dir=$conf->societe->multidir_output[$entity].'/contact'; - if (! empty($object->photo)) - { - if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_mini'); - else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_small'); - else $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo; - $originalfile=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo; - } - $email=$object->email; - } - else if ($modulepart=='userphoto') - { - $dir=$conf->user->dir_output; - if (! empty($object->photo)) - { - if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_mini'); - else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_small'); - else $file=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo; - $originalfile=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo; - } - if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg"; // For backward compatibility - $email=$object->email; - } - else if ($modulepart=='memberphoto') - { - $dir=$conf->adherent->dir_output; - if (! empty($object->photo)) - { - if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_mini'); - else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_small'); - else $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; - $originalfile=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; - } - if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg"; // For backward compatibility - $email=$object->email; - } - else - { - // Generic case to show photos - $dir=$conf->$modulepart->dir_output; - if (! empty($object->photo)) - { - if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_mini'); - else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_small'); - else $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; - $originalfile=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; - } - if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg"; // For backward compatibility - $email=$object->email; - } - - if ($dir) - { - if ($file && file_exists($dir."/".$file)) - { - if ($addlinktofullsize) - { - $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity='.$entity); - if ($urladvanced) $ret.='<a href="'.$urladvanced.'">'; - else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">'; - } - $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="Photo" id="photologo'.(preg_replace('/[^a-z]/i','_',$file)).'" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($file).'&cache='.$cache.'">'; - if ($addlinktofullsize) $ret.='</a>'; - } - else if ($altfile && file_exists($dir."/".$altfile)) - { - if ($addlinktofullsize) - { - $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity='.$entity); - if ($urladvanced) $ret.='<a href="'.$urladvanced.'">'; - else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">'; - } - $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="Photo alt" id="photologo'.(preg_replace('/[^a-z]/i','_',$file)).'" class="'.$cssclass.'" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($altfile).'&cache='.$cache.'">'; - if ($addlinktofullsize) $ret.='</a>'; - } - else + return $ret; + } + + + /** + * Return HTML code to output a barcode + * + * @param Object $object Object containing data to retrieve file name + * @param int $width Width of photo + * @return string HTML code to output barcode + */ + function showbarcode(&$object,$width=100) + { + global $conf; + + //Check if barcode is filled in the card + if (empty($object->barcode)) return ''; + + // Complete object if not complete + if (empty($object->barcode_type_code) || empty($object->barcode_type_coder)) + { + $result = $object->fetch_barcode(); + //Check if fetch_barcode() failed + if ($result < 1) return '<!-- ErrorFetchBarcode -->'; + } + + // Barcode image + $url=DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&generator='.urlencode($object->barcode_type_coder).'&code='.urlencode($object->barcode).'&encoding='.urlencode($object->barcode_type_code); + $out ='<!-- url barcode = '.$url.' -->'; + $out.='<img src="'.$url.'">'; + return $out; + } + + /** + * Return HTML code to output a photo + * + * @param string $modulepart Key to define module concerned ('societe', 'userphoto', 'memberphoto') + * @param object $object Object containing data to retrieve file name + * @param int $width Width of photo + * @param int $height Height of photo (auto if 0) + * @param int $caneditfield Add edit fields + * @param string $cssclass CSS name to use on img for photo + * @param string $imagesize 'mini', 'small' or '' (original) + * @param int $addlinktofullsize Add link to fullsize image + * @param int $cache 1=Accept to use image in cache + * @return string HTML code to output photo + */ + static function showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0) + { + global $conf,$langs; + + $entity = (! empty($object->entity) ? $object->entity : $conf->entity); + $id = (! empty($object->id) ? $object->id : $object->rowid); + + $ret='';$dir='';$file='';$originalfile='';$altfile='';$email=''; + if ($modulepart=='societe') + { + $dir=$conf->societe->multidir_output[$entity]; + if (! empty($object->logo)) + { + if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_mini'); // getImageFileNameForSize include the thumbs + else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_small'); + else $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo; + $originalfile=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo; + } + $email=$object->email; + } + else if ($modulepart=='contact') + { + $dir=$conf->societe->multidir_output[$entity].'/contact'; + if (! empty($object->photo)) + { + if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_mini'); + else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_small'); + else $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo; + $originalfile=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo; + } + $email=$object->email; + } + else if ($modulepart=='userphoto') + { + $dir=$conf->user->dir_output; + if (! empty($object->photo)) + { + if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_mini'); + else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_small'); + else $file=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo; + $originalfile=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo; + } + if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg"; // For backward compatibility + $email=$object->email; + } + else if ($modulepart=='memberphoto') + { + $dir=$conf->adherent->dir_output; + if (! empty($object->photo)) + { + if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_mini'); + else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_small'); + else $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; + $originalfile=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; + } + if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg"; // For backward compatibility + $email=$object->email; + } + else + { + // Generic case to show photos + $dir=$conf->$modulepart->dir_output; + if (! empty($object->photo)) + { + if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_mini'); + else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_small'); + else $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; + $originalfile=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; + } + if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg"; // For backward compatibility + $email=$object->email; + } + + if ($dir) + { + if ($file && file_exists($dir."/".$file)) + { + if ($addlinktofullsize) + { + $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity='.$entity); + if ($urladvanced) $ret.='<a href="'.$urladvanced.'">'; + else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">'; + } + $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="Photo" id="photologo'.(preg_replace('/[^a-z]/i','_',$file)).'" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($file).'&cache='.$cache.'">'; + if ($addlinktofullsize) $ret.='</a>'; + } + else if ($altfile && file_exists($dir."/".$altfile)) + { + if ($addlinktofullsize) + { + $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity='.$entity); + if ($urladvanced) $ret.='<a href="'.$urladvanced.'">'; + else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">'; + } + $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="Photo alt" id="photologo'.(preg_replace('/[^a-z]/i','_',$file)).'" class="'.$cssclass.'" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($altfile).'&cache='.$cache.'">'; + if ($addlinktofullsize) $ret.='</a>'; + } + else { - $nophoto='/public/theme/common/nophoto.png'; + $nophoto='/public/theme/common/nophoto.png'; if (in_array($modulepart,array('userphoto','contact'))) // For module that are "physical" users { $nophoto='/public/theme/common/user_anonymous.png'; @@ -6196,174 +6196,174 @@ class Form } if (! empty($conf->gravatar->enabled) && $email) - { - /** - * @see https://gravatar.com/site/implement/images/php/ - */ - global $dolibarr_main_url_root; - $ret.='<!-- Put link to gravatar -->'; - //$defaultimg=urlencode(dol_buildpath($nophoto,3)); - $defaultimg='mm'; - $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="Gravatar avatar" title="'.$email.' Gravatar avatar" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="https://www.gravatar.com/avatar/'.dol_hash(strtolower(trim($email)),3).'?s='.$width.'&d='.$defaultimg.'">'; // gravatar need md5 hash - } - else { - $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="No photo" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.$nophoto.'">'; - } - } + /** + * @see https://gravatar.com/site/implement/images/php/ + */ + global $dolibarr_main_url_root; + $ret.='<!-- Put link to gravatar -->'; + //$defaultimg=urlencode(dol_buildpath($nophoto,3)); + $defaultimg='mm'; + $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="Gravatar avatar" title="'.$email.' Gravatar avatar" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="https://www.gravatar.com/avatar/'.dol_hash(strtolower(trim($email)),3).'?s='.$width.'&d='.$defaultimg.'">'; // gravatar need md5 hash + } + else + { + $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="No photo" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.$nophoto.'">'; + } + } - if ($caneditfield) - { - if ($object->photo) $ret.="<br>\n"; - $ret.='<table class="nobordernopadding centpercent">'; - if ($object->photo) $ret.='<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> '.$langs->trans("Delete").'<br><br></td></tr>'; - $ret.='<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"></td></tr>'; - $ret.='</table>'; - } + if ($caneditfield) + { + if ($object->photo) $ret.="<br>\n"; + $ret.='<table class="nobordernopadding centpercent">'; + if ($object->photo) $ret.='<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> '.$langs->trans("Delete").'<br><br></td></tr>'; + $ret.='<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"></td></tr>'; + $ret.='</table>'; + } + + } + else dol_print_error('','Call of showphoto with wrong parameters modulepart='.$modulepart); + + return $ret; + } + + /** + * Return select list of groups + * + * @param string $selected Id group preselected + * @param string $htmlname Field name in form + * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue + * @param string $exclude Array list of groups id to exclude + * @param int $disabled If select list must be disabled + * @param string $include Array list of groups id to include + * @param int $enableonly Array list of groups id to be enabled. All other must be disabled + * @param int $force_entity 0 or Id of environment to force + * @return string + * @see select_dolusers + */ + function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0) + { + global $conf,$user,$langs; + + // Permettre l'exclusion de groupes + if (is_array($exclude)) $excludeGroups = implode("','",$exclude); + // Permettre l'inclusion de groupes + if (is_array($include)) $includeGroups = implode("','",$include); + + $out=''; + + // On recherche les groupes + $sql = "SELECT ug.rowid, ug.nom as name"; + if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + $sql.= ", e.label"; + } + $sql.= " FROM ".MAIN_DB_PREFIX."usergroup as ug "; + if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entity as e ON e.rowid=ug.entity"; + if ($force_entity) $sql.= " WHERE ug.entity IN (0,".$force_entity.")"; + else $sql.= " WHERE ug.entity IS NOT NULL"; + } + else + { + $sql.= " WHERE ug.entity IN (0,".$conf->entity.")"; + } + if (is_array($exclude) && $excludeGroups) $sql.= " AND ug.rowid NOT IN ('".$excludeGroups."')"; + if (is_array($include) && $includeGroups) $sql.= " AND ug.rowid IN ('".$includeGroups."')"; + $sql.= " ORDER BY ug.nom ASC"; - } - else dol_print_error('','Call of showphoto with wrong parameters modulepart='.$modulepart); - - return $ret; - } - - /** - * Return select list of groups - * - * @param string $selected Id group preselected - * @param string $htmlname Field name in form - * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue - * @param string $exclude Array list of groups id to exclude - * @param int $disabled If select list must be disabled - * @param string $include Array list of groups id to include - * @param int $enableonly Array list of groups id to be enabled. All other must be disabled - * @param int $force_entity 0 or Id of environment to force - * @return string - * @see select_dolusers - */ - function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0) - { - global $conf,$user,$langs; - - // Permettre l'exclusion de groupes - if (is_array($exclude)) $excludeGroups = implode("','",$exclude); - // Permettre l'inclusion de groupes - if (is_array($include)) $includeGroups = implode("','",$include); - - $out=''; - - // On recherche les groupes - $sql = "SELECT ug.rowid, ug.nom as name"; - if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - $sql.= ", e.label"; - } - $sql.= " FROM ".MAIN_DB_PREFIX."usergroup as ug "; - if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entity as e ON e.rowid=ug.entity"; - if ($force_entity) $sql.= " WHERE ug.entity IN (0,".$force_entity.")"; - else $sql.= " WHERE ug.entity IS NOT NULL"; - } - else - { - $sql.= " WHERE ug.entity IN (0,".$conf->entity.")"; - } - if (is_array($exclude) && $excludeGroups) $sql.= " AND ug.rowid NOT IN ('".$excludeGroups."')"; - if (is_array($include) && $includeGroups) $sql.= " AND ug.rowid IN ('".$includeGroups."')"; - $sql.= " ORDER BY ug.nom ASC"; - - dol_syslog(get_class($this)."::select_dolgroups", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - // Enhance with select2 - if ($conf->use_javascript_ajax) - { + dol_syslog(get_class($this)."::select_dolgroups", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + // Enhance with select2 + if ($conf->use_javascript_ajax) + { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement = ajax_combobox($htmlname); - $out.= $comboenhancement; - } + $comboenhancement = ajax_combobox($htmlname); + $out.= $comboenhancement; + } - $out.= '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>'; + $out.= '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>'; - $num = $this->db->num_rows($resql); - $i = 0; - if ($num) - { - if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'> </option>'."\n"; + $num = $this->db->num_rows($resql); + $i = 0; + if ($num) + { + if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'> </option>'."\n"; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $disableline=0; - if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=1; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $disableline=0; + if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=1; - $out.= '<option value="'.$obj->rowid.'"'; - if ($disableline) $out.= ' disabled'; - if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid)) - { - $out.= ' selected'; - } - $out.= '>'; + $out.= '<option value="'.$obj->rowid.'"'; + if ($disableline) $out.= ' disabled'; + if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid)) + { + $out.= ' selected'; + } + $out.= '>'; - $out.= $obj->name; - if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1) - { - $out.= " (".$obj->label.")"; - } + $out.= $obj->name; + if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1) + { + $out.= " (".$obj->label.")"; + } - $out.= '</option>'; - $i++; - } - } - else - { - if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'></option>'."\n"; - $out.= '<option value="" disabled>'.$langs->trans("NoUserGroupDefined").'</option>'; - } - $out.= '</select>'; - } - else - { - dol_print_error($this->db); - } - - return $out; - } - - - /** - * Return HTML to show the search and clear seach button - * - * @return string - */ - function showFilterButtons() - { - global $conf, $langs; - - $out='<div class="nowrap">'; - $out.='<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"),'search.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">'; - $out.='<input type="image" class="liste_titre" name="button_removefilter" src="'.img_picto($langs->trans("Search"),'searchclear.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'" title="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'">'; - $out.='</div>'; - - return $out; - } - - /** - * Return HTML to show the search and clear seach button - * - * @param string $cssclass CSS class - * @param int $calljsfunction 0=default. 1=call function initCheckForSelect() after changing status of checkboxes - * @return string - */ - function showCheckAddButtons($cssclass='checkforaction', $calljsfunction=0) - { - global $conf, $langs; - - $out=''; - if (! empty($conf->use_javascript_ajax)) $out.='<div class="inline-block checkallactions"><input type="checkbox" id="checkallactions" name="checkallactions" class="checkallactions"></div>'; - $out.='<script type="text/javascript"> + $out.= '</option>'; + $i++; + } + } + else + { + if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'></option>'."\n"; + $out.= '<option value="" disabled>'.$langs->trans("NoUserGroupDefined").'</option>'; + } + $out.= '</select>'; + } + else + { + dol_print_error($this->db); + } + + return $out; + } + + + /** + * Return HTML to show the search and clear seach button + * + * @return string + */ + function showFilterButtons() + { + global $conf, $langs; + + $out='<div class="nowrap">'; + $out.='<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"),'search.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">'; + $out.='<input type="image" class="liste_titre" name="button_removefilter" src="'.img_picto($langs->trans("Search"),'searchclear.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'" title="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'">'; + $out.='</div>'; + + return $out; + } + + /** + * Return HTML to show the search and clear seach button + * + * @param string $cssclass CSS class + * @param int $calljsfunction 0=default. 1=call function initCheckForSelect() after changing status of checkboxes + * @return string + */ + function showCheckAddButtons($cssclass='checkforaction', $calljsfunction=0) + { + global $conf, $langs; + + $out=''; + if (! empty($conf->use_javascript_ajax)) $out.='<div class="inline-block checkallactions"><input type="checkbox" id="checkallactions" name="checkallactions" class="checkallactions"></div>'; + $out.='<script type="text/javascript"> $(document).ready(function() { $("#checkallactions").click(function() { if($(this).is(\':checked\')){ @@ -6375,43 +6375,43 @@ class Form console.log("We uncheck all"); $(".'.$cssclass.'").prop(\'checked\', false); }'."\n"; - if ($calljsfunction) $out.='if (typeof initCheckForSelect == \'function\') { initCheckForSelect(); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }'; - $out.=' }); + if ($calljsfunction) $out.='if (typeof initCheckForSelect == \'function\') { initCheckForSelect(); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }'; + $out.=' }); }); </script>'; - return $out; - } - - /** - * Return HTML to show the search and clear seach button - * - * @param int $addcheckuncheckall Add the check all/uncheck all checkbox (use javascript) and code to manage this - * @param string $cssclass CSS class - * @param int $calljsfunction 0=default. 1=call function initCheckForSelect() after changing status of checkboxes - * @return string - */ - function showFilterAndCheckAddButtons($addcheckuncheckall=0, $cssclass='checkforaction', $calljsfunction=0) - { - $out.=$this->showFilterButtons(); - if ($addcheckuncheckall) - { - $out.=$this->showCheckAddButtons($cssclass, $calljsfunction); - } - return $out; - } + return $out; + } + + /** + * Return HTML to show the search and clear seach button + * + * @param int $addcheckuncheckall Add the check all/uncheck all checkbox (use javascript) and code to manage this + * @param string $cssclass CSS class + * @param int $calljsfunction 0=default. 1=call function initCheckForSelect() after changing status of checkboxes + * @return string + */ + function showFilterAndCheckAddButtons($addcheckuncheckall=0, $cssclass='checkforaction', $calljsfunction=0) + { + $out.=$this->showFilterButtons(); + if ($addcheckuncheckall) + { + $out.=$this->showCheckAddButtons($cssclass, $calljsfunction); + } + return $out; + } /** * Return HTML to show the select categories of expense category * * @param string $selected preselected category - * @param string $htmlname name of HTML select list - * @param integer $useempty 1=Add empty line - * @param array $excludeid id to exclude - * @param string $target htmlname of target select to bind event - * @param int $default_selected default category to select if fk_c_type_fees change = EX_KME - * @param array $params param to give - * @return string + * @param string $htmlname name of HTML select list + * @param integer $useempty 1=Add empty line + * @param array $excludeid id to exclude + * @param string $target htmlname of target select to bind event + * @param int $default_selected default category to select if fk_c_type_fees change = EX_KME + * @param array $params param to give + * @return string */ function selectExpenseCategories($selected='', $htmlname='fk_c_exp_tax_cat', $useempty=0, $excludeid=array(), $target='', $default_selected=0, $params=array()) { @@ -6497,9 +6497,9 @@ class Form * Return HTML to show the select ranges of expense range * * @param string $selected preselected category - * @param string $htmlname name of HTML select list - * @param integer $useempty 1=Add empty line - * @return string + * @param string $htmlname name of HTML select list + * @param integer $useempty 1=Add empty line + * @return string */ function selectExpenseRanges($selected='', $htmlname='fk_range', $useempty=0) { @@ -6532,11 +6532,11 @@ class Form * Return HTML to show a select of expense * * @param string $selected preselected category - * @param string $htmlname name of HTML select list - * @param integer $useempty 1=Add empty choice + * @param string $htmlname name of HTML select list + * @param integer $useempty 1=Add empty choice * @param integer $allchoice 1=Add all choice * @param integer $useid 0=use 'code' as key, 1=use 'id' as key - * @return string + * @return string */ function selectExpense($selected='', $htmlname='fk_c_type_fees', $useempty=0, $allchoice=1, $useid=0) { diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 930a9f109976af69a6e7bce120c27f8f73269343..20a9b85cf867f8d40a039fecc49d2115c55be4d9 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -92,8 +92,8 @@ class Ldap /** - * The internal LDAP connection handle - */ + * The internal LDAP connection handle + */ var $connection; /** * Result of any connections etc. @@ -749,7 +749,7 @@ class Ldap // Attribute methods ----------------------------------------------------- - /** + /** * Add a LDAP attribute in entry * Ldap object connect and bind must have been done * @@ -801,7 +801,7 @@ class Ldap } } - /** + /** * Update a LDAP attribute in entry * Ldap object connect and bind must have been done * @@ -853,7 +853,7 @@ class Ldap } } - /** + /** * Delete a LDAP attribute in entry * Ldap object connect and bind must have been done * @@ -905,7 +905,7 @@ class Ldap } } - /** + /** * Returns an array containing attributes and values for first record * * @param string $dn DN entry key @@ -1262,7 +1262,7 @@ class Ldap $i=0; while ($i <= 2) { - dol_syslog(get_class($this)."::fetch search with searchDN=".$searchDN." filter=".$filter); + dol_syslog(get_class($this)."::fetch search with searchDN=".$searchDN." filter=".$filter); $this->result = @ldap_search($this->connection, $searchDN, $filter); if ($this->result) { @@ -1273,9 +1273,9 @@ class Ldap } else { - $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection); - dol_syslog(get_class($this)."::fetch search fails"); - return -1; + $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection); + dol_syslog(get_class($this)."::fetch search fails"); + return -1; } if (! $result) @@ -1324,7 +1324,7 @@ class Ldap $this->domainFQDN = $domain; // Set ldapUserDn (each user can have a different dn) - //var_dump($result[0]);exit; + //var_dump($result[0]);exit; $this->ldapUserDN=$result[0]['dn']; ldap_free_result($this->result); @@ -1350,11 +1350,11 @@ class Ldap } /** - * UserAccountControl Flgs to more human understandable form... - * - * @param string $uacf UACF - * @return void - */ + * UserAccountControl Flgs to more human understandable form... + * + * @param string $uacf UACF + * @return void + */ function parseUACF($uacf) { //All flags array @@ -1396,11 +1396,11 @@ class Ldap } /** - * SamAccountType value to text - * - * @param string $samtype SamType - * @return string Sam string - */ + * SamAccountType value to text + * + * @param string $samtype SamType + * @return string Sam string + */ function parseSAT($samtype) { $stypes = array( @@ -1443,7 +1443,7 @@ class Ldap /** * Convert a string into output/memory charset - * + * * @param string $str String to convert * @param string $pagecodefrom Page code of src string * @return string Converted string @@ -1458,7 +1458,7 @@ class Ldap /** * Convert a string from output/memory charset - * + * * @param string $str String to convert * @param string $pagecodeto Page code for result string * @return string Converted string diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 81842e65c234a73a70726a5db5bd753f58da7326..d40fcadc17cf565c8b47552523956b853b7ac3bc 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -30,56 +30,56 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/CMailFile.class.php'; */ class Notify { - var $id; - var $db; - var $error; - var $errors=array(); - - var $author; - var $ref; - var $date; - var $duree; - var $note; - var $fk_project; + var $id; + var $db; + var $error; + var $errors=array(); + + var $author; + var $ref; + var $date; + var $duree; + var $note; + var $fk_project; // Les codes actions sont definis dans la table llx_notify_def - // codes actions supported are - public $arrayofnotifsupported = array( - 'BILL_VALIDATE', - 'BILL_PAYED', - 'ORDER_VALIDATE', - 'PROPAL_VALIDATE', - 'PROPAL_CLOSE_SIGNED', - 'FICHINTER_VALIDATE', - 'FICHINTER_ADD_CONTACT', - 'ORDER_SUPPLIER_VALIDATE', - 'ORDER_SUPPLIER_APPROVE', - 'ORDER_SUPPLIER_REFUSE', - 'SHIPPING_VALIDATE' - ); - - - /** + // codes actions supported are + public $arrayofnotifsupported = array( + 'BILL_VALIDATE', + 'BILL_PAYED', + 'ORDER_VALIDATE', + 'PROPAL_VALIDATE', + 'PROPAL_CLOSE_SIGNED', + 'FICHINTER_VALIDATE', + 'FICHINTER_ADD_CONTACT', + 'ORDER_SUPPLIER_VALIDATE', + 'ORDER_SUPPLIER_APPROVE', + 'ORDER_SUPPLIER_REFUSE', + 'SHIPPING_VALIDATE' + ); + + + /** * Constructor * * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - } - - - /** - * Return message that say how many notification (and to which email) will occurs on requested event. - * This is to show confirmation messages before event is recorded. - * - * @param string $action Id of action in llx_c_action_trigger - * @param int $socid Id of third party - * @param Object $object Object the notification is about - * @return string Message - */ + */ + function __construct($db) + { + $this->db = $db; + } + + + /** + * Return message that say how many notification (and to which email) will occurs on requested event. + * This is to show confirmation messages before event is recorded. + * + * @param string $action Id of action in llx_c_action_trigger + * @param int $socid Id of third party + * @param Object $object Object the notification is about + * @return string Message + */ function confirmMessage($action,$socid,$object) { global $langs; @@ -96,175 +96,175 @@ class Notify if (is_array($listofnotiftodo)) { - $i=0; - foreach ($listofnotiftodo as $key => $val) - { - if ($i) $texte.=', '; - else $texte.=' ('; - if ($val['isemailvalid']) $texte.=$val['email']; - else $texte.=$val['emaildesc']; - $i++; - } - if ($i) $texte.=')'; + $i=0; + foreach ($listofnotiftodo as $key => $val) + { + if ($i) $texte.=', '; + else $texte.=' ('; + if ($val['isemailvalid']) $texte.=$val['email']; + else $texte.=$val['emaildesc']; + $i++; + } + if ($i) $texte.=')'; } return $texte; } - /** - * Return number of notifications activated for action code (and third party) - * - * @param string $notifcode Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage) - * @param int $socid Id of third party or 0 for all thirdparties or -1 for no thirdparties - * @param Object $object Object the notification is about (need it to check threshold value of some notifications) - * @param int $userid Id of user or 0 for all users or -1 for no users - * @param array $scope Scope where to search - * @return array|int <0 if KO, array of notifications to send if OK - */ + /** + * Return number of notifications activated for action code (and third party) + * + * @param string $notifcode Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage) + * @param int $socid Id of third party or 0 for all thirdparties or -1 for no thirdparties + * @param Object $object Object the notification is about (need it to check threshold value of some notifications) + * @param int $userid Id of user or 0 for all users or -1 for no users + * @param array $scope Scope where to search + * @return array|int <0 if KO, array of notifications to send if OK + */ function getNotificationsArray($notifcode, $socid=0, $object=null, $userid=0, $scope=array('thirdparty', 'user', 'global')) { global $conf, $user; $error=0; - $resarray=array(); - - $valueforthreshold = 0; - if (is_object($object)) $valueforthreshold = $object->total_ht; - - if (! $error) - { - if ($socid >= 0 && in_array('thirdparty', $scope)) - { - $sql = "SELECT a.code, c.email, c.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; - $sql.= " ".MAIN_DB_PREFIX."socpeople as c,"; - $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE n.fk_contact = c.rowid"; - $sql.= " AND a.rowid = n.fk_action"; - $sql.= " AND n.fk_soc = s.rowid"; - if ($notifcode) - { - if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage - else $sql.= " AND a.code = '".$notifcode."'"; // New usage - } - $sql.= " AND s.entity IN (".getEntity('societe').")"; - if ($socid > 0) $sql.= " AND s.rowid = ".$socid; - - dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG); - - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i=0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - if ($obj) - { - $newval2=trim($obj->email); - $isvalid=isValidEmail($newval2); - if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'tocontact', 'code'=>trim($obj->code), 'emaildesc'=>'Contact id '.$obj->rowid, 'email'=>$newval2, 'contactid'=>$obj->rowid, 'isemailvalid'=>$isvalid); - } - $i++; - } - } - else - { - $error++; - $this->error=$this->db->lasterror(); - } - } - } - - if (! $error) - { - if ($userid >= 0 && in_array('user', $scope)) - { - $sql = "SELECT a.code, c.email, c.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; - $sql.= " ".MAIN_DB_PREFIX."user as c,"; - $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a"; - $sql.= " WHERE n.fk_user = c.rowid"; - $sql.= " AND a.rowid = n.fk_action"; - if ($notifcode) - { - if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage - else $sql.= " AND a.code = '".$notifcode."'"; // New usage - } - $sql.= " AND c.entity IN (".getEntity('user').")"; - if ($userid > 0) $sql.= " AND c.rowid = ".$userid; - - dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG); - - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i=0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - if ($obj) - { - $newval2=trim($obj->email); - $isvalid=isValidEmail($newval2); - if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'touser', 'code'=>trim($obj->code), 'emaildesc'=>'User id '.$obj->rowid, 'email'=>$newval2, 'userid'=>$obj->rowid, 'isemailvalid'=>$isvalid); - } - $i++; - } - } - else - { - $error++; - $this->error=$this->db->lasterror(); - } - } - } + $resarray=array(); + + $valueforthreshold = 0; + if (is_object($object)) $valueforthreshold = $object->total_ht; if (! $error) { - if (in_array('global', $scope)) - { - // List of notifications enabled for fixed email - foreach($conf->global as $key => $val) - { - if ($notifcode) - { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; - } - else - { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; - } - - $threshold = (float) $reg[1]; - if ($valueforthreshold < $threshold) continue; - - $tmpemail=explode(',',$val); - foreach($tmpemail as $key2 => $val2) - { - $newval2=trim($val2); - if ($newval2 == '__SUPERVISOREMAIL__') - { - if ($user->fk_user > 0) - { - $tmpuser=new User($this->db); - $tmpuser->fetch($user->fk_user); - if ($tmpuser->email) $newval2=trim($tmpuser->email); - else $newval2=''; - } - else $newval2=''; - } - if ($newval2) - { - $isvalid=isValidEmail($newval2, 0); - if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid); - } - } - } - } + if ($socid >= 0 && in_array('thirdparty', $scope)) + { + $sql = "SELECT a.code, c.email, c.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; + $sql.= " ".MAIN_DB_PREFIX."socpeople as c,"; + $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + $sql.= " WHERE n.fk_contact = c.rowid"; + $sql.= " AND a.rowid = n.fk_action"; + $sql.= " AND n.fk_soc = s.rowid"; + if ($notifcode) + { + if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage + else $sql.= " AND a.code = '".$notifcode."'"; // New usage + } + $sql.= " AND s.entity IN (".getEntity('societe').")"; + if ($socid > 0) $sql.= " AND s.rowid = ".$socid; + + dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG); + + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + if ($obj) + { + $newval2=trim($obj->email); + $isvalid=isValidEmail($newval2); + if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'tocontact', 'code'=>trim($obj->code), 'emaildesc'=>'Contact id '.$obj->rowid, 'email'=>$newval2, 'contactid'=>$obj->rowid, 'isemailvalid'=>$isvalid); + } + $i++; + } + } + else + { + $error++; + $this->error=$this->db->lasterror(); + } + } + } + + if (! $error) + { + if ($userid >= 0 && in_array('user', $scope)) + { + $sql = "SELECT a.code, c.email, c.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; + $sql.= " ".MAIN_DB_PREFIX."user as c,"; + $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a"; + $sql.= " WHERE n.fk_user = c.rowid"; + $sql.= " AND a.rowid = n.fk_action"; + if ($notifcode) + { + if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage + else $sql.= " AND a.code = '".$notifcode."'"; // New usage + } + $sql.= " AND c.entity IN (".getEntity('user').")"; + if ($userid > 0) $sql.= " AND c.rowid = ".$userid; + + dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG); + + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + if ($obj) + { + $newval2=trim($obj->email); + $isvalid=isValidEmail($newval2); + if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'touser', 'code'=>trim($obj->code), 'emaildesc'=>'User id '.$obj->rowid, 'email'=>$newval2, 'userid'=>$obj->rowid, 'isemailvalid'=>$isvalid); + } + $i++; + } + } + else + { + $error++; + $this->error=$this->db->lasterror(); + } + } + } + + if (! $error) + { + if (in_array('global', $scope)) + { + // List of notifications enabled for fixed email + foreach($conf->global as $key => $val) + { + if ($notifcode) + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } + else + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } + + $threshold = (float) $reg[1]; + if ($valueforthreshold < $threshold) continue; + + $tmpemail=explode(',',$val); + foreach($tmpemail as $key2 => $val2) + { + $newval2=trim($val2); + if ($newval2 == '__SUPERVISOREMAIL__') + { + if ($user->fk_user > 0) + { + $tmpuser=new User($this->db); + $tmpuser->fetch($user->fk_user); + if ($tmpuser->email) $newval2=trim($tmpuser->email); + else $newval2=''; + } + else $newval2=''; + } + if ($newval2) + { + $isvalid=isValidEmail($newval2, 0); + if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid); + } + } + } + } } if ($error) return -1; @@ -273,47 +273,47 @@ class Notify return $resarray; } - /** - * Check if notification are active for couple action/company. - * If yes, send mail and save trace into llx_notify. - * - * @param string $notifcode Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage) - * @param Object $object Object the notification deals on - * @return int <0 if KO, or number of changes if OK - */ - function send($notifcode, $object) - { - global $user,$conf,$langs,$mysoc; - global $hookmanager; - global $dolibarr_main_url_root; + /** + * Check if notification are active for couple action/company. + * If yes, send mail and save trace into llx_notify. + * + * @param string $notifcode Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage) + * @param Object $object Object the notification deals on + * @return int <0 if KO, or number of changes if OK + */ + function send($notifcode, $object) + { + global $user,$conf,$langs,$mysoc; + global $hookmanager; + global $dolibarr_main_url_root; if (! in_array($notifcode, $this->arrayofnotifsupported)) return 0; - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('notification')); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('notification')); - dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object=".$object->id); + dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object=".$object->id); - $langs->load("other"); + $langs->load("other"); // Define $urlwithroot - $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current // Define some vars - $application = 'Dolibarr'; - if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $application = $conf->global->MAIN_APPLICATION_TITLE; - $replyto = $conf->notification->email_from; - $filename = basename($file); - $mimefile = dol_mimetype($file); + $application = 'Dolibarr'; + if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $application = $conf->global->MAIN_APPLICATION_TITLE; + $replyto = $conf->notification->email_from; + $filename = basename($file); + $mimefile = dol_mimetype($file); $object_type = ''; - $link = ''; + $link = ''; $num = 0; $oldref=(empty($object->oldref)?$object->ref:$object->oldref); @@ -322,56 +322,56 @@ class Notify // Check notification per third party $sql = "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,"; $sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,"; - $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,"; - $sql.= " ".MAIN_DB_PREFIX."notify_def as n,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action"; - $sql.= " AND n.fk_soc = s.rowid"; - if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage - else $sql.= " AND a.code = '".$notifcode."'"; // New usage - $sql .= " AND s.rowid = ".$object->socid; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,"; + $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,"; + $sql.= " ".MAIN_DB_PREFIX."notify_def as n,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + $sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action"; + $sql.= " AND n.fk_soc = s.rowid"; + if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage + else $sql.= " AND a.code = '".$notifcode."'"; // New usage + $sql .= " AND s.rowid = ".$object->socid; // Check notification per user - $sql.= "\nUNION\n"; - - $sql.= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,"; - $sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type"; - $sql.= " FROM ".MAIN_DB_PREFIX."user as c,"; - $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,"; - $sql.= " ".MAIN_DB_PREFIX."notify_def as n"; - $sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action"; - if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage - else $sql.= " AND a.code = '".$notifcode."'"; // New usage - - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - - if ($num > 0) - { - $i = 0; - while ($i < $num && ! $error) // For each notification couple defined (third party/actioncode) - { - $obj = $this->db->fetch_object($result); - - $sendto = dolGetFirstLastname($obj->firstname,$obj->lastname) . " <".$obj->email.">"; + $sql.= "\nUNION\n"; + + $sql.= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,"; + $sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as c,"; + $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,"; + $sql.= " ".MAIN_DB_PREFIX."notify_def as n"; + $sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action"; + if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage + else $sql.= " AND a.code = '".$notifcode."'"; // New usage + + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + + if ($num > 0) + { + $i = 0; + while ($i < $num && ! $error) // For each notification couple defined (third party/actioncode) + { + $obj = $this->db->fetch_object($result); + + $sendto = dolGetFirstLastname($obj->firstname,$obj->lastname) . " <".$obj->email.">"; $notifcodedefid = $obj->adid; - if (dol_strlen($obj->email)) - { - // Set output language - $outputlangs = $langs; - if ($obj->default_lang && $obj->default_lang != $langs->defaultlang) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($obj->default_lang); - } + if (dol_strlen($obj->email)) + { + // Set output language + $outputlangs = $langs; + if ($obj->default_lang && $obj->default_lang != $langs->defaultlang) + { + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang($obj->default_lang); + } - $subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification"); + $subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification"); - switch ($notifcode) { + switch ($notifcode) { case 'BILL_VALIDATE': $link='/compta/facture/card.php?facid='.$object->id; $dir_output = $conf->facture->dir_output; @@ -396,12 +396,12 @@ class Notify $object_type = 'propal'; $mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated",$newref); break; - case 'PROPAL_CLOSE_SIGNED': - $link='/comm/propal/card.php?id='.$object->id; - $dir_output = $conf->propal->dir_output; - $object_type = 'propal'; - $mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref); - break; + case 'PROPAL_CLOSE_SIGNED': + $link='/comm/propal/card.php?id='.$object->id; + $dir_output = $conf->propal->dir_output; + $object_type = 'propal'; + $mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref); + break; case 'FICHINTER_ADD_CONTACT': $link='/fichinter/card.php?id='.$object->id; $dir_output = $conf->facture->dir_output; @@ -444,7 +444,7 @@ class Notify $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref); break; } - $ref = dol_sanitizeFileName($newref); + $ref = dol_sanitizeFileName($newref); $pdf_path = $dir_output."/".$ref."/".$ref.".pdf"; if (! dol_is_file($pdf_path)) { @@ -456,104 +456,104 @@ class Notify $filepdf = $pdf_path; } - $message = $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n"; - $message.= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n"; - $message.= "\n"; - $message.= $mesg; - if ($link) $message=dol_concatdesc($message,$urlwithroot.$link); - - $parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$file, 'mimefile'=>$mimefile, 'filename'=>$filename); - $reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject']; - if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message']; - } - - $mailfile = new CMailFile( - $subject, - $sendto, - $replyto, - $message, - array($file), - array($mimefile), - array($filename[count($filename)-1]), - '', - '', - 0, - -1 - ); - - if ($mailfile->sendfile()) - { - if ($obj->type_target == 'touserid') { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_user, type, objet_type, type_target, objet_id, email)"; - $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')"; - - } - else { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, objet_type, type_target, objet_id, email)"; - $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')"; - - } - if (! $this->db->query($sql)) - { - dol_print_error($this->db); - } - } - else + $message = $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n"; + $message.= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n"; + $message.= "\n"; + $message.= $mesg; + if ($link) $message=dol_concatdesc($message,$urlwithroot.$link); + + $parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$file, 'mimefile'=>$mimefile, 'filename'=>$filename); + $reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject']; + if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message']; + } + + $mailfile = new CMailFile( + $subject, + $sendto, + $replyto, + $message, + array($file), + array($mimefile), + array($filename[count($filename)-1]), + '', + '', + 0, + -1 + ); + + if ($mailfile->sendfile()) + { + if ($obj->type_target == 'touserid') { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_user, type, objet_type, type_target, objet_id, email)"; + $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')"; + + } + else { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, objet_type, type_target, objet_id, email)"; + $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')"; + + } + if (! $this->db->query($sql)) + { + dol_print_error($this->db); + } + } + else { $error++; - $this->errors[]=$mailfile->error; - } - } - else - { - dol_syslog("No notification sent for ".$sendto." because email is empty"); - } - $i++; - } - } - else + $this->errors[]=$mailfile->error; + } + } + else + { + dol_syslog("No notification sent for ".$sendto." because email is empty"); + } + $i++; + } + } + else { - dol_syslog("No notification to thirdparty sent, nothing into notification setup for the thirdparty socid = ".$object->socid); + dol_syslog("No notification to thirdparty sent, nothing into notification setup for the thirdparty socid = ".$object->socid); } - } - else - { - $error++; - $this->errors[]=$this->db->lasterror(); - dol_syslog("Failed to get list of notification to send ".$this->db->lasterror(), LOG_ERR); - return -1; - } - - // Check notification using fixed email - if (! $error) - { - foreach($conf->global as $key => $val) - { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; - - $threshold = (float) $reg[1]; - if (!empty($object->total_ht) && $object->total_ht <= $threshold) - { - dol_syslog("A notification is requested for notifcode = ".$notifcode." but amount = ".$object->total_ht." so lower than threshold = ".$threshold.". We discard this notification"); - continue; - } - - $param='NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_'.$reg[1]; - - $sendto = $conf->global->$param; - $notifcodedefid = dol_getIdFromCode($this->db, $notifcode, 'c_action_trigger', 'code', 'rowid'); - if ($notifcodedefid <= 0) dol_print_error($this->db, 'Failed to get id from code'); - - $object_type = ''; - $link = ''; - $num++; - - $subject = '['.$mysoc->name.'] '.$langs->transnoentitiesnoconv("DolibarrNotification"); - - switch ($notifcode) { + } + else + { + $error++; + $this->errors[]=$this->db->lasterror(); + dol_syslog("Failed to get list of notification to send ".$this->db->lasterror(), LOG_ERR); + return -1; + } + + // Check notification using fixed email + if (! $error) + { + foreach($conf->global as $key => $val) + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + + $threshold = (float) $reg[1]; + if (!empty($object->total_ht) && $object->total_ht <= $threshold) + { + dol_syslog("A notification is requested for notifcode = ".$notifcode." but amount = ".$object->total_ht." so lower than threshold = ".$threshold.". We discard this notification"); + continue; + } + + $param='NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_'.$reg[1]; + + $sendto = $conf->global->$param; + $notifcodedefid = dol_getIdFromCode($this->db, $notifcode, 'c_action_trigger', 'code', 'rowid'); + if ($notifcodedefid <= 0) dol_print_error($this->db, 'Failed to get id from code'); + + $object_type = ''; + $link = ''; + $num++; + + $subject = '['.$mysoc->name.'] '.$langs->transnoentitiesnoconv("DolibarrNotification"); + + switch ($notifcode) { case 'BILL_VALIDATE': $link='/compta/facture/card.php?facid='.$object->id; $dir_output = $conf->facture->dir_output; @@ -578,32 +578,32 @@ class Notify $object_type = 'propal'; $mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated",$newref); break; - case 'PROPAL_CLOSE_SIGNED': - $link='/comm/propal/card.php?id='.$object->id; - $dir_output = $conf->propal->dir_output; - $object_type = 'propal'; - $mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref); - break; - case 'FICHINTER_ADD_CONTACT': - $link='/fichinter/card.php?id='.$object->id; - $dir_output = $conf->facture->dir_output; - $object_type = 'ficheinter'; - $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$newref); - break; + case 'PROPAL_CLOSE_SIGNED': + $link='/comm/propal/card.php?id='.$object->id; + $dir_output = $conf->propal->dir_output; + $object_type = 'propal'; + $mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref); + break; + case 'FICHINTER_ADD_CONTACT': + $link='/fichinter/card.php?id='.$object->id; + $dir_output = $conf->facture->dir_output; + $object_type = 'ficheinter'; + $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$newref); + break; case 'FICHINTER_VALIDATE': $link='/fichinter/card.php?id='.$object->id; $dir_output = $conf->facture->dir_output; $object_type = 'ficheinter'; $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionValidated",$newref); break; - case 'ORDER_SUPPLIER_VALIDATE': - $link='/fourn/commande/card.php?id='.$object->id; - $dir_output = $conf->fournisseur->commande->dir_output; - $object_type = 'order_supplier'; - $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n"; - $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$newref,$user->getFullName($langs)); - $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n"; - break; + case 'ORDER_SUPPLIER_VALIDATE': + $link='/fourn/commande/card.php?id='.$object->id; + $dir_output = $conf->fournisseur->commande->dir_output; + $object_type = 'order_supplier'; + $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n"; + $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$newref,$user->getFullName($langs)); + $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n"; + break; case 'ORDER_SUPPLIER_APPROVE': $link='/fourn/commande/card.php?id='.$object->id; $dir_output = $conf->fournisseur->commande->dir_output; @@ -646,73 +646,73 @@ class Notify $filepdf = $pdf_path; } - $message = $langs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n"; - $message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n"; - $message.= "\n"; - $message.= $mesg; - if ($link) $message=dol_concatdesc($message,$urlwithroot.$link); - - // Replace keyword __SUPERVISOREMAIL__ - if (preg_match('/__SUPERVISOREMAIL__/', $sendto)) - { - $newval=''; - if ($user->fk_user > 0) - { - $supervisoruser=new User($this->db); - $supervisoruser->fetch($user->fk_user); - if ($supervisoruser->email) $newval=trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>'); - } - dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval); - $sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto); - $sendto = preg_replace('/^[\s,]+/','',$sendto); // Clean start of string - $sendto = preg_replace('/[\s,]+$/','',$sendto); // Clean end of string - } - - if ($sendto) - { - $parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$file, 'mimefile'=>$mimefile, 'filename'=>$filename); - $reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject']; - if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message']; - } - - $mailfile = new CMailFile( - $subject, - $sendto, - $replyto, - $message, - array($file), - array($mimefile), - array($filename[count($filename)-1]), - '', - '', - 0, - -1 - ); - - if ($mailfile->sendfile()) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, type_target, objet_type, objet_id, email)"; - $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", null, 'email', 'tofixedemail', '".$object_type."', ".$object->id.", '".$this->db->escape($conf->global->$param)."')"; - if (! $this->db->query($sql)) - { - dol_print_error($this->db); - } - } - else - { - $error++; - $this->errors[]=$mailfile->error; - } - } - } - } + $message = $langs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n"; + $message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n"; + $message.= "\n"; + $message.= $mesg; + if ($link) $message=dol_concatdesc($message,$urlwithroot.$link); + + // Replace keyword __SUPERVISOREMAIL__ + if (preg_match('/__SUPERVISOREMAIL__/', $sendto)) + { + $newval=''; + if ($user->fk_user > 0) + { + $supervisoruser=new User($this->db); + $supervisoruser->fetch($user->fk_user); + if ($supervisoruser->email) $newval=trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>'); + } + dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval); + $sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto); + $sendto = preg_replace('/^[\s,]+/','',$sendto); // Clean start of string + $sendto = preg_replace('/[\s,]+$/','',$sendto); // Clean end of string + } + + if ($sendto) + { + $parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$file, 'mimefile'=>$mimefile, 'filename'=>$filename); + $reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject']; + if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message']; + } + + $mailfile = new CMailFile( + $subject, + $sendto, + $replyto, + $message, + array($file), + array($mimefile), + array($filename[count($filename)-1]), + '', + '', + 0, + -1 + ); + + if ($mailfile->sendfile()) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, type_target, objet_type, objet_id, email)"; + $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", null, 'email', 'tofixedemail', '".$object_type."', ".$object->id.", '".$this->db->escape($conf->global->$param)."')"; + if (! $this->db->query($sql)) + { + dol_print_error($this->db); + } + } + else + { + $error++; + $this->errors[]=$mailfile->error; + } + } + } + } if (! $error) return $num; else return -1 * $error; - } + } } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 710fb15ae564d57e2f221e47f9a0a4e1319709d4..44a404c6c672a1892402b5198859edce0b33bb5a 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -34,7 +34,7 @@ */ function dol_basename($pathfile) { - return preg_replace('/^.*\/([^\/]+)$/','$1',rtrim($pathfile,'/')); + return preg_replace('/^.*\/([^\/]+)$/','$1',rtrim($pathfile,'/')); } /** @@ -75,9 +75,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil if (is_object($hookmanager) && ! $nohook) { - $hookmanager->resArray=array(); + $hookmanager->resArray=array(); - $hookmanager->initHooks(array('fileslib')); + $hookmanager->initHooks(array('fileslib')); $parameters=array( 'path' => $newpath, @@ -221,66 +221,66 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil */ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0) { - global $conf, $db; - - $sql=" SELECT rowid, label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position"; - if ($mode) $sql.=", description"; - $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files"; - $sql.=" WHERE filepath = '".$db->escape($path)."'"; - $sql.=" AND entity = ".$conf->entity; - - $resql = $db->query($sql); - if ($resql) - { - $file_list=array(); - $num = $db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $db->fetch_object($resql); - if ($obj) - { - preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg); - $level1name=(isset($reg[1])?$reg[1]:''); - $file_list[] = array( - "rowid" => $obj->rowid, - "label" => $obj->label, // md5 - "name" => $obj->filename, - "path" => DOL_DATA_ROOT.'/'.$obj->filepath, - "level1name" => $level1name, - "fullname" => DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename, - "fullpath_orig" => $obj->fullpath_orig, - "date_c" => $db->jdate($obj->date_c), - "date_m" => $db->jdate($obj->date_m), - "type" => 'file', - "keywords" => $obj->keywords, - "cover" => $obj->cover, - "position" => (int) $obj->position, - "acl" => $obj->acl - ); - } - $i++; - } - - // Obtain a list of columns - if (! empty($sortcriteria)) - { - $myarray=array(); - foreach ($file_list as $key => $row) - { - $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:''); - } - // Sort the data - if ($sortorder) array_multisort($myarray, $sortorder, $file_list); - } - - return $file_list; - } - else - { - dol_print_error($db); - return array(); - } + global $conf, $db; + + $sql=" SELECT rowid, label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position"; + if ($mode) $sql.=", description"; + $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files"; + $sql.=" WHERE filepath = '".$db->escape($path)."'"; + $sql.=" AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) + { + $file_list=array(); + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg); + $level1name=(isset($reg[1])?$reg[1]:''); + $file_list[] = array( + "rowid" => $obj->rowid, + "label" => $obj->label, // md5 + "name" => $obj->filename, + "path" => DOL_DATA_ROOT.'/'.$obj->filepath, + "level1name" => $level1name, + "fullname" => DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename, + "fullpath_orig" => $obj->fullpath_orig, + "date_c" => $db->jdate($obj->date_c), + "date_m" => $db->jdate($obj->date_m), + "type" => 'file', + "keywords" => $obj->keywords, + "cover" => $obj->cover, + "position" => (int) $obj->position, + "acl" => $obj->acl + ); + } + $i++; + } + + // Obtain a list of columns + if (! empty($sortcriteria)) + { + $myarray=array(); + foreach ($file_list as $key => $row) + { + $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:''); + } + // Sort the data + if ($sortorder) array_multisort($myarray, $sortorder, $file_list); + } + + return $file_list; + } + else + { + dol_print_error($db); + return array(); + } } @@ -411,9 +411,9 @@ function dol_compare_file($a, $b) */ function dol_is_dir($folder) { - $newfolder=dol_osencode($folder); - if (is_dir($newfolder)) return true; - else return false; + $newfolder=dol_osencode($folder); + if (is_dir($newfolder)) return true; + else return false; } /** @@ -424,8 +424,8 @@ function dol_is_dir($folder) */ function dol_is_file($pathoffile) { - $newpathoffile=dol_osencode($pathoffile); - return is_file($newpathoffile); + $newpathoffile=dol_osencode($pathoffile); + return is_file($newpathoffile); } /** @@ -436,12 +436,12 @@ function dol_is_file($pathoffile) */ function dol_is_url($url) { - $tmpprot=array('file','http','https','ftp','zlib','data','ssh','ssh2','ogg','expect'); - foreach($tmpprot as $prot) - { - if (preg_match('/^'.$prot.':/i',$url)) return true; - } - return false; + $tmpprot=array('file','http','https','ftp','zlib','data','ssh','ssh2','ogg','expect'); + foreach($tmpprot as $prot) + { + if (preg_match('/^'.$prot.':/i',$url)) return true; + } + return false; } /** @@ -456,14 +456,14 @@ function dol_dir_is_emtpy($folder) if (is_dir($newfolder)) { $handle = opendir($newfolder); - $folder_content = ''; + $folder_content = ''; while ((gettype($name = readdir($handle)) != "boolean")) { $name_array[] = $name; } foreach($name_array as $temp) $folder_content .= $temp; - closedir($handle); + closedir($handle); if ($folder_content == "...") return true; else return false; @@ -491,7 +491,7 @@ function dol_count_nb_of_line($file) while (!feof($fp)) { $line=fgets($fp); - // We increase count only if read was success. We need test because feof return true only after fgets so we do n+1 fgets for a file with n lines. + // We increase count only if read was success. We need test because feof return true only after fgets so we do n+1 fgets for a file with n lines. if (! $line === false) $nb++; } fclose($fp); @@ -542,61 +542,61 @@ function dol_filemtime($pathoffile) */ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0) { - global $conf; + global $conf; - dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase); + dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase); - if (empty($srcfile)) return -1; - if (empty($destfile)) $destfile=$srcfile; + if (empty($srcfile)) return -1; + if (empty($destfile)) $destfile=$srcfile; - $destexists=dol_is_file($destfile); - if (($destfile != $srcfile) && $destexists) return 0; + $destexists=dol_is_file($destfile); + if (($destfile != $srcfile) && $destexists) return 0; - $tmpdestfile=$destfile.'.tmp'; + $tmpdestfile=$destfile.'.tmp'; - $newpathofsrcfile=dol_osencode($srcfile); - $newpathoftmpdestfile=dol_osencode($tmpdestfile); - $newpathofdestfile=dol_osencode($destfile); - $newdirdestfile=dirname($newpathofdestfile); + $newpathofsrcfile=dol_osencode($srcfile); + $newpathoftmpdestfile=dol_osencode($tmpdestfile); + $newpathofdestfile=dol_osencode($destfile); + $newdirdestfile=dirname($newpathofdestfile); - if ($destexists && ! is_writable($newpathofdestfile)) - { - dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to overwrite target file", LOG_WARNING); - return -1; - } - if (! is_writable($newdirdestfile)) - { - dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING); - return -2; - } + if ($destexists && ! is_writable($newpathofdestfile)) + { + dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to overwrite target file", LOG_WARNING); + return -1; + } + if (! is_writable($newdirdestfile)) + { + dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING); + return -2; + } - dol_delete_file($tmpdestfile); + dol_delete_file($tmpdestfile); - // Create $newpathoftmpdestfile from $newpathofsrcfile - $content=file_get_contents($newpathofsrcfile, 'r'); + // Create $newpathoftmpdestfile from $newpathofsrcfile + $content=file_get_contents($newpathofsrcfile, 'r'); - $content = make_substitutions($content, $arrayreplacement, null); + $content = make_substitutions($content, $arrayreplacement, null); - file_put_contents($newpathoftmpdestfile, $content); - @chmod($newpathoftmpdestfile, octdec($newmask)); + file_put_contents($newpathoftmpdestfile, $content); + @chmod($newpathoftmpdestfile, octdec($newmask)); - // Rename - $result=dol_move($newpathoftmpdestfile, $newpathofdestfile, $newmask, (($destfile == $srcfile)?1:0), 0, $indexdatabase); - if (! $result) - { - dol_syslog("files.lib.php::dolReplaceInFile failed to move tmp file to final dest", LOG_WARNING); - return -3; - } - if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK; - if (empty($newmask)) // This should no happen - { - dol_syslog("Warning: dolReplaceInFile called with empty value for newmask and no default value defined", LOG_WARNING); - $newmask='0664'; - } + // Rename + $result=dol_move($newpathoftmpdestfile, $newpathofdestfile, $newmask, (($destfile == $srcfile)?1:0), 0, $indexdatabase); + if (! $result) + { + dol_syslog("files.lib.php::dolReplaceInFile failed to move tmp file to final dest", LOG_WARNING); + return -3; + } + if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK; + if (empty($newmask)) // This should no happen + { + dol_syslog("Warning: dolReplaceInFile called with empty value for newmask and no default value defined", LOG_WARNING); + $newmask='0664'; + } - @chmod($newpathofdestfile, octdec($newmask)); + @chmod($newpathofdestfile, octdec($newmask)); - return 1; + return 1; } /** @@ -638,26 +638,26 @@ function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1) if (! $overwriteifexists && $destexists) return 0; $newpathofsrcfile=dol_osencode($srcfile); - $newpathofdestfile=dol_osencode($destfile); - $newdirdestfile=dirname($newpathofdestfile); - - if ($destexists && ! is_writable($newpathofdestfile)) - { - dol_syslog("files.lib.php::dol_copy failed Permission denied to overwrite target file", LOG_WARNING); - return -1; - } - if (! is_writable($newdirdestfile)) - { - dol_syslog("files.lib.php::dol_copy failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING); - return -2; - } - // Copy with overwriting if exists - $result=@copy($newpathofsrcfile, $newpathofdestfile); + $newpathofdestfile=dol_osencode($destfile); + $newdirdestfile=dirname($newpathofdestfile); + + if ($destexists && ! is_writable($newpathofdestfile)) + { + dol_syslog("files.lib.php::dol_copy failed Permission denied to overwrite target file", LOG_WARNING); + return -1; + } + if (! is_writable($newdirdestfile)) + { + dol_syslog("files.lib.php::dol_copy failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING); + return -2; + } + // Copy with overwriting if exists + $result=@copy($newpathofsrcfile, $newpathofdestfile); //$result=copy($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @ if (! $result) { - dol_syslog("files.lib.php::dol_copy failed to copy", LOG_WARNING); - return -3; + dol_syslog("files.lib.php::dol_copy failed to copy", LOG_WARNING); + return -3; } if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK; if (empty($newmask)) // This should no happen @@ -695,33 +695,33 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep $destexists=dol_is_dir($destfile); //if (! $overwriteifexists && $destexists) return 0; // The overwriteifexists is for files only, so propagated to dol_copy only. - if (! $destexists) - { - // We must set mask just before creating dir, becaause it can be set differently by dol_copy - umask(0); - $dirmaskdec=octdec($newmask); - if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $dirmaskdec=octdec($conf->global->MAIN_UMASK); - $dirmaskdec |= octdec('0200'); // Set w bit required to be able to create content for recursive subdirs files - dol_mkdir($destfile, '', decoct($dirmaskdec)); - } + if (! $destexists) + { + // We must set mask just before creating dir, becaause it can be set differently by dol_copy + umask(0); + $dirmaskdec=octdec($newmask); + if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $dirmaskdec=octdec($conf->global->MAIN_UMASK); + $dirmaskdec |= octdec('0200'); // Set w bit required to be able to create content for recursive subdirs files + dol_mkdir($destfile, '', decoct($dirmaskdec)); + } $ossrcfile=dol_osencode($srcfile); $osdestfile=dol_osencode($destfile); - // Recursive function to copy all subdirectories and contents: + // Recursive function to copy all subdirectories and contents: if (is_dir($ossrcfile)) { - $dir_handle=opendir($ossrcfile); - while ($file=readdir($dir_handle)) - { - if ($file != "." && $file != ".." && ! is_link($ossrcfile."/".$file)) - { - if (is_dir($ossrcfile."/".$file)) - { - //var_dump("xxx dolCopyDir $srcfile/$file, $destfile/$file, $newmask, $overwriteifexists"); - $tmpresult=dolCopyDir($srcfile."/".$file, $destfile."/".$file, $newmask, $overwriteifexists, $arrayreplacement); - } - else + $dir_handle=opendir($ossrcfile); + while ($file=readdir($dir_handle)) + { + if ($file != "." && $file != ".." && ! is_link($ossrcfile."/".$file)) + { + if (is_dir($ossrcfile."/".$file)) + { + //var_dump("xxx dolCopyDir $srcfile/$file, $destfile/$file, $newmask, $overwriteifexists"); + $tmpresult=dolCopyDir($srcfile."/".$file, $destfile."/".$file, $newmask, $overwriteifexists, $arrayreplacement); + } + else { $newfile = $file; // Replace destination filename with a new one @@ -732,30 +732,30 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep $newfile = str_replace($key, $val, $newfile); } } - $tmpresult=dol_copy($srcfile."/".$file, $destfile."/".$newfile, $newmask, $overwriteifexists); - } - // Set result - if ($result > 0 && $tmpresult >= 0) - { - // Do nothing, so we don't set result to 0 if tmpresult is 0 and result was success in a previous pass - } - else - { - $result=$tmpresult; - } - if ($result < 0) break; + $tmpresult=dol_copy($srcfile."/".$file, $destfile."/".$newfile, $newmask, $overwriteifexists); + } + // Set result + if ($result > 0 && $tmpresult >= 0) + { + // Do nothing, so we don't set result to 0 if tmpresult is 0 and result was success in a previous pass + } + else + { + $result=$tmpresult; + } + if ($result < 0) break; - } - } - closedir($dir_handle); - } - else + } + } + closedir($dir_handle); + } + else { // Source directory does not exists - $result = -2; - } + $result = -2; + } - return $result; + return $result; } @@ -777,123 +777,123 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep */ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1) { - global $user, $db, $conf; - $result=false; - - dol_syslog("files.lib.php::dol_move srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwritifexists=".$overwriteifexists); - $srcexists=dol_is_file($srcfile); - $destexists=dol_is_file($destfile); - - if (! $srcexists) - { - dol_syslog("files.lib.php::dol_move srcfile does not exists. we ignore the move request."); - return false; - } - - if ($overwriteifexists || ! $destexists) - { - $newpathofsrcfile=dol_osencode($srcfile); - $newpathofdestfile=dol_osencode($destfile); - - // Check virus - $testvirusarray=array(); - if ($testvirus) - { - $testvirusarray=dolCheckVirus($newpathofsrcfile); - if (count($testvirusarray)) - { - dol_syslog("files.lib.php::dol_move canceled because a virus was found into source file. we ignore the move request.", LOG_WARNING); - return false; - } - } - - $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @ - if (! $result) - { - if ($destexists) - { - dol_syslog("files.lib.php::dol_move Failed. We try to delete target first and move after.", LOG_WARNING); - // We force delete and try again. Rename function sometimes fails to replace dest file with some windows NTFS partitions. - dol_delete_file($destfile); - $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @ - } - else dol_syslog("files.lib.php::dol_move Failed.", LOG_WARNING); - } - - // Move ok - if ($result && $indexdatabase) - { - // Rename entry into ecm database - $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $srcfile); - $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile); - if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file - { - $rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore); - $rel_filetorenameafter = preg_replace('/^[\\/]/', '', $rel_filetorenameafter); - //var_dump($rel_filetorenamebefore.' - '.$rel_filetorenameafter); - - dol_syslog("Try to rename also entries in database for full relative path before = ".$rel_filetorenamebefore." after = ".$rel_filetorenameafter, LOG_DEBUG); - include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; - - $ecmfiletarget=new EcmFiles($db); - $resultecmtarget = $ecmfiletarget->fetch(0, '', $rel_filetorenameafter); - if ($resultecmtarget > 0) // An entry for target name already exists for target, we delete it, a new one will be created. - { - $ecmfiletarget->delete($user); - } - - $ecmfile=new EcmFiles($db); - $resultecm = $ecmfile->fetch(0, '', $rel_filetorenamebefore); - if ($resultecm > 0) // If an entry was found for src file, we use it to move entry - { - $filename = basename($rel_filetorenameafter); - $rel_dir = dirname($rel_filetorenameafter); - $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); - $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); - - $ecmfile->filepath = $rel_dir; - $ecmfile->filename = $filename; - $resultecm = $ecmfile->update($user); - } - elseif ($resultecm == 0) // If no entry were found for src files, create/update target file - { - $filename = basename($rel_filetorenameafter); - $rel_dir = dirname($rel_filetorenameafter); - $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); - $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); - - $ecmfile->filepath = $rel_dir; - $ecmfile->filename = $filename; - $ecmfile->label = md5_file(dol_osencode($destfile)); // $destfile is a full path to file - $ecmfile->fullpath_orig = $srcfile; - $ecmfile->gen_or_uploaded = 'unknown'; - $ecmfile->description = ''; // indexed content - $ecmfile->keyword = ''; // keyword content - $resultecm = $ecmfile->create($user); - if ($resultecm < 0) - { - setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); - } - } - elseif ($resultecm < 0) - { - setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); - } - - if ($resultecm > 0) $result=true; - else $result = false; - } - } + global $user, $db, $conf; + $result=false; - if (empty($newmask)) $newmask=empty($conf->global->MAIN_UMASK)?'0755':$conf->global->MAIN_UMASK; - $newmaskdec=octdec($newmask); - // Currently method is restricted to files (dol_delete_files previously used is for files, and mask usage if for files too) - // to allow mask usage for dir, we shoul introduce a new param "isdir" to 1 to complete newmask like this - // if ($isdir) $newmaskdec |= octdec('0111'); // Set x bit required for directories - @chmod($newpathofdestfile, $newmaskdec); - } + dol_syslog("files.lib.php::dol_move srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwritifexists=".$overwriteifexists); + $srcexists=dol_is_file($srcfile); + $destexists=dol_is_file($destfile); + + if (! $srcexists) + { + dol_syslog("files.lib.php::dol_move srcfile does not exists. we ignore the move request."); + return false; + } + + if ($overwriteifexists || ! $destexists) + { + $newpathofsrcfile=dol_osencode($srcfile); + $newpathofdestfile=dol_osencode($destfile); + + // Check virus + $testvirusarray=array(); + if ($testvirus) + { + $testvirusarray=dolCheckVirus($newpathofsrcfile); + if (count($testvirusarray)) + { + dol_syslog("files.lib.php::dol_move canceled because a virus was found into source file. we ignore the move request.", LOG_WARNING); + return false; + } + } + + $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @ + if (! $result) + { + if ($destexists) + { + dol_syslog("files.lib.php::dol_move Failed. We try to delete target first and move after.", LOG_WARNING); + // We force delete and try again. Rename function sometimes fails to replace dest file with some windows NTFS partitions. + dol_delete_file($destfile); + $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @ + } + else dol_syslog("files.lib.php::dol_move Failed.", LOG_WARNING); + } + + // Move ok + if ($result && $indexdatabase) + { + // Rename entry into ecm database + $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $srcfile); + $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile); + if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file + { + $rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore); + $rel_filetorenameafter = preg_replace('/^[\\/]/', '', $rel_filetorenameafter); + //var_dump($rel_filetorenamebefore.' - '.$rel_filetorenameafter); + + dol_syslog("Try to rename also entries in database for full relative path before = ".$rel_filetorenamebefore." after = ".$rel_filetorenameafter, LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + + $ecmfiletarget=new EcmFiles($db); + $resultecmtarget = $ecmfiletarget->fetch(0, '', $rel_filetorenameafter); + if ($resultecmtarget > 0) // An entry for target name already exists for target, we delete it, a new one will be created. + { + $ecmfiletarget->delete($user); + } + + $ecmfile=new EcmFiles($db); + $resultecm = $ecmfile->fetch(0, '', $rel_filetorenamebefore); + if ($resultecm > 0) // If an entry was found for src file, we use it to move entry + { + $filename = basename($rel_filetorenameafter); + $rel_dir = dirname($rel_filetorenameafter); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $resultecm = $ecmfile->update($user); + } + elseif ($resultecm == 0) // If no entry were found for src files, create/update target file + { + $filename = basename($rel_filetorenameafter); + $rel_dir = dirname($rel_filetorenameafter); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $ecmfile->label = md5_file(dol_osencode($destfile)); // $destfile is a full path to file + $ecmfile->fullpath_orig = $srcfile; + $ecmfile->gen_or_uploaded = 'unknown'; + $ecmfile->description = ''; // indexed content + $ecmfile->keyword = ''; // keyword content + $resultecm = $ecmfile->create($user); + if ($resultecm < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } + elseif ($resultecm < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + + if ($resultecm > 0) $result=true; + else $result = false; + } + } - return $result; + if (empty($newmask)) $newmask=empty($conf->global->MAIN_UMASK)?'0755':$conf->global->MAIN_UMASK; + $newmaskdec=octdec($newmask); + // Currently method is restricted to files (dol_delete_files previously used is for files, and mask usage if for files too) + // to allow mask usage for dir, we shoul introduce a new param "isdir" to 1 to complete newmask like this + // if ($isdir) $newmaskdec |= octdec('0111'); // Set x bit required for directories + @chmod($newpathofdestfile, $newmaskdec); + } + + return $result; } /** @@ -920,22 +920,22 @@ function dol_unescapefile($filename) */ function dolCheckVirus($src_file) { - global $conf; - - if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) - { - if (! class_exists('AntiVir')) { - require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php'; - } - $antivir=new AntiVir($db); - $result = $antivir->dol_avscan_file($src_file); - if ($result < 0) // If virus or error, we stop here - { - $reterrors=$antivir->errors; - return $reterrors; - } - } - return array(); + global $conf; + + if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) + { + if (! class_exists('AntiVir')) { + require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php'; + } + $antivir=new AntiVir($db); + $result = $antivir->dol_avscan_file($src_file); + if ($result < 0) // If virus or error, we stop here + { + $reterrors=$antivir->errors; + return $reterrors; + } + } + return array(); } @@ -975,68 +975,68 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable if (empty($reshook)) { - // If an upload error has been reported - if ($uploaderrorcode) - { - switch($uploaderrorcode) - { - case UPLOAD_ERR_INI_SIZE: // 1 - return 'ErrorFileSizeTooLarge'; - break; - case UPLOAD_ERR_FORM_SIZE: // 2 - return 'ErrorFileSizeTooLarge'; - break; - case UPLOAD_ERR_PARTIAL: // 3 - return 'ErrorPartialFile'; - break; - case UPLOAD_ERR_NO_TMP_DIR: // - return 'ErrorNoTmpDir'; - break; - case UPLOAD_ERR_CANT_WRITE: - return 'ErrorFailedToWriteInDir'; - break; - case UPLOAD_ERR_EXTENSION: - return 'ErrorUploadBlockedByAddon'; - break; - default: - break; - } - } - - // If we need to make a virus scan - if (empty($disablevirusscan) && file_exists($src_file)) - { - $checkvirusarray=dolCheckVirus($src_file); - if (count($checkvirusarray)) - { - dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: result='.$result.' errors='.join(',',$checkvirusarray), LOG_WARNING); - return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray); - } - } - - // Security: - // Disallow file with some extensions. We rename them. - // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. - if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$dest_file) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) - { - $file_name.= '.noexe'; - } - - // Security: - // We refuse cache files/dirs, upload using .. and pipes into filenames. - if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file)) - { - dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING); - return -1; - } - - // Security: - // On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans les noms de fichiers. - if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file)) - { - dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING); - return -2; - } + // If an upload error has been reported + if ($uploaderrorcode) + { + switch($uploaderrorcode) + { + case UPLOAD_ERR_INI_SIZE: // 1 + return 'ErrorFileSizeTooLarge'; + break; + case UPLOAD_ERR_FORM_SIZE: // 2 + return 'ErrorFileSizeTooLarge'; + break; + case UPLOAD_ERR_PARTIAL: // 3 + return 'ErrorPartialFile'; + break; + case UPLOAD_ERR_NO_TMP_DIR: // + return 'ErrorNoTmpDir'; + break; + case UPLOAD_ERR_CANT_WRITE: + return 'ErrorFailedToWriteInDir'; + break; + case UPLOAD_ERR_EXTENSION: + return 'ErrorUploadBlockedByAddon'; + break; + default: + break; + } + } + + // If we need to make a virus scan + if (empty($disablevirusscan) && file_exists($src_file)) + { + $checkvirusarray=dolCheckVirus($src_file); + if (count($checkvirusarray)) + { + dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: result='.$result.' errors='.join(',',$checkvirusarray), LOG_WARNING); + return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray); + } + } + + // Security: + // Disallow file with some extensions. We rename them. + // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. + if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$dest_file) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) + { + $file_name.= '.noexe'; + } + + // Security: + // We refuse cache files/dirs, upload using .. and pipes into filenames. + if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file)) + { + dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING); + return -1; + } + + // Security: + // On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans les noms de fichiers. + if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file)) + { + dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING); + return -2; + } } if ($reshook < 0) // At least one blocking error returned by one hook @@ -1108,8 +1108,8 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n // We refuse transversal using .. and pipes into filenames. if (preg_match('/\.\./',$file) || preg_match('/[<>|]/',$file)) { - dol_syslog("Refused to delete file ".$file, LOG_WARNING); - return False; + dol_syslog("Refused to delete file ".$file, LOG_WARNING); + return False; } if (empty($nohook)) @@ -1150,27 +1150,27 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n else $ok=unlink($filename); if ($ok) { - dol_syslog("Removed file ".$filename, LOG_DEBUG); - - // Delete entry into ecm database - $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); - if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file - { - $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); - - dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG); - include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; - $ecmfile=new EcmFiles($db); - $result = $ecmfile->fetch(0, '', $rel_filetodelete); - if ($result >= 0 && $ecmfile->id > 0) - { - $result = $ecmfile->delete($user); - } - if ($result < 0) - { - setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); - } - } + dol_syslog("Removed file ".$filename, LOG_DEBUG); + + // Delete entry into ecm database + $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); + if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file + { + $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); + + dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', $rel_filetodelete); + if ($result >= 0 && $ecmfile->id > 0) + { + $result = $ecmfile->delete($user); + } + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } } else dol_syslog("Failed to remove file ".$filename, LOG_WARNING); // TODO Failure to remove can be because file was already removed or because of permission @@ -1207,12 +1207,12 @@ function dol_delete_dir($dir,$nophperrors=0) // We refuse transversal using .. and pipes into filenames. if (preg_match('/\.\./',$dir) || preg_match('/[<>|]/',$dir)) { - dol_syslog("Refused to delete dir ".$dir, LOG_WARNING); - return False; + dol_syslog("Refused to delete dir ".$dir, LOG_WARNING); + return False; } - $dir_osencoded=dol_osencode($dir); - return ($nophperrors?@rmdir($dir_osencoded):rmdir($dir_osencoded)); + $dir_osencoded=dol_osencode($dir); + return ($nophperrors?@rmdir($dir_osencoded):rmdir($dir_osencoded)); } /** @@ -1227,42 +1227,42 @@ function dol_delete_dir($dir,$nophperrors=0) */ function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0) { - dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir,LOG_DEBUG); - if (dol_is_dir($dir)) - { - $dir_osencoded=dol_osencode($dir); - if ($handle = opendir("$dir_osencoded")) - { - while (false !== ($item = readdir($handle))) - { - if (! utf8_check($item)) $item=utf8_encode($item); // should be useless - - if ($item != "." && $item != "..") - { - if (is_dir(dol_osencode("$dir/$item")) && ! is_link(dol_osencode("$dir/$item"))) - { - $count=dol_delete_dir_recursive("$dir/$item", $count, $nophperrors, 0, $countdeleted); - } - else - { - $result=dol_delete_file("$dir/$item", 1, $nophperrors); - $count++; - if ($result) $countdeleted++; - } - } - } - closedir($handle); + dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir,LOG_DEBUG); + if (dol_is_dir($dir)) + { + $dir_osencoded=dol_osencode($dir); + if ($handle = opendir("$dir_osencoded")) + { + while (false !== ($item = readdir($handle))) + { + if (! utf8_check($item)) $item=utf8_encode($item); // should be useless - if (empty($onlysub)) - { - $result=dol_delete_dir($dir, $nophperrors); - $count++; - if ($result) $countdeleted++; - } - } - } + if ($item != "." && $item != "..") + { + if (is_dir(dol_osencode("$dir/$item")) && ! is_link(dol_osencode("$dir/$item"))) + { + $count=dol_delete_dir_recursive("$dir/$item", $count, $nophperrors, 0, $countdeleted); + } + else + { + $result=dol_delete_file("$dir/$item", 1, $nophperrors); + $count++; + if ($result) $countdeleted++; + } + } + } + closedir($handle); - return $count; + if (empty($onlysub)) + { + $result=dol_delete_dir($dir, $nophperrors); + $count++; + if ($result) $countdeleted++; + } + } + } + + return $count; } @@ -1279,15 +1279,15 @@ function dol_delete_preview($object) // Define parent dir of elements $element = $object->element; - if ($object->element == 'order_supplier') $dir = $conf->fournisseur->commande->dir_output; - elseif ($object->element == 'invoice_supplier') $dir = $conf->fournisseur->facture->dir_output; - elseif ($object->element == 'project') $dir = $conf->projet->dir_output; - elseif ($object->element == 'shipping') $dir = $conf->expedition->dir_output.'/sending'; - elseif ($object->element == 'delivery') $dir = $conf->expedition->dir_output.'/receipt'; - elseif ($object->element == 'fichinter') $dir = $conf->ficheinter->dir_output; - else $dir=empty($conf->$element->dir_output)?'':$conf->$element->dir_output; + if ($object->element == 'order_supplier') $dir = $conf->fournisseur->commande->dir_output; + elseif ($object->element == 'invoice_supplier') $dir = $conf->fournisseur->facture->dir_output; + elseif ($object->element == 'project') $dir = $conf->projet->dir_output; + elseif ($object->element == 'shipping') $dir = $conf->expedition->dir_output.'/sending'; + elseif ($object->element == 'delivery') $dir = $conf->expedition->dir_output.'/receipt'; + elseif ($object->element == 'fichinter') $dir = $conf->ficheinter->dir_output; + else $dir=empty($conf->$element->dir_output)?'':$conf->$element->dir_output; - if (empty($dir)) return 'ErrorObjectNoSupportedByFunction'; + if (empty($dir)) return 'ErrorObjectNoSupportedByFunction'; $refsan = dol_sanitizeFileName($object->ref); $dir = $dir . "/" . $refsan ; @@ -1425,7 +1425,7 @@ function dol_init_file_process($pathtoscan='', $trackid='') $listofmimes[]=dol_mimetype($val['name']); } } - $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; + $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths); $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames); $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes); @@ -1500,14 +1500,14 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio { if (image_format_supported($destfull) == 1) { - // Create thumbs - // We can't use $object->addThumbs here because there is no $object known - - // Used on logon for example - $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); - // Create mini thumbs for image (Ratio is near 16/9) - // Used on menu or for setup page for example - $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); + // Create thumbs + // We can't use $object->addThumbs here because there is no $object known + + // Used on logon for example + $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); + // Create mini thumbs for image (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); } } @@ -1523,29 +1523,29 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio // Update table of files if ($donotupdatesession) { - $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); - - if (! preg_match('/[\\/]temp[\\/]|[\\/]thumbs|\.meta$/', $rel_dir)) // If not a tmp dir - { - $filename = basename($destfile); - $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); - $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); - - include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; - $ecmfile=new EcmFiles($db); - $ecmfile->filepath = $rel_dir; - $ecmfile->filename = $filename; - $ecmfile->label = md5_file(dol_osencode($destfull)); // MD5 of file content - $ecmfile->fullpath_orig = $TFile['name'][$i]; - $ecmfile->gen_or_uploaded = 'uploaded'; - $ecmfile->description = ''; // indexed content - $ecmfile->keyword = ''; // keyword content - $result = $ecmfile->create($user); - if ($result < 0) - { - setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); - } - } + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); + + if (! preg_match('/[\\/]temp[\\/]|[\\/]thumbs|\.meta$/', $rel_dir)) // If not a tmp dir + { + $filename = basename($destfile); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $ecmfile->label = md5_file(dol_osencode($destfull)); // MD5 of file content + $ecmfile->fullpath_orig = $TFile['name'][$i]; + $ecmfile->gen_or_uploaded = 'uploaded'; + $ecmfile->description = ''; // indexed content + $ecmfile->keyword = ''; // keyword content + $result = $ecmfile->create($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } } $res = 1; @@ -1616,7 +1616,7 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= $listofpaths=array(); $listofnames=array(); $listofmimes=array(); - $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; + $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]); if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]); if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]); @@ -1706,48 +1706,48 @@ function dol_convert_file($fileinput, $ext='png', $fileoutput='') */ function dol_compress_file($inputfile, $outputfile, $mode="gz") { - $foundhandler=0; - - try - { - $data = implode("", file(dol_osencode($inputfile))); - if ($mode == 'gz') { $foundhandler=1; $compressdata = gzencode($data, 9); } - elseif ($mode == 'bz') { $foundhandler=1; $compressdata = bzcompress($data, 9); } - elseif ($mode == 'zip') - { - if (defined('ODTPHP_PATHTOPCLZIP')) - { - $foundhandler=1; + $foundhandler=0; - include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; - $archive = new PclZip($outputfile); - $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile)); - //$archive->add($inputfile); - return 1; - } - } - - if ($foundhandler) - { - $fp = fopen($outputfile, "w"); - fwrite($fp, $compressdata); - fclose($fp); - return 1; - } - else - { - dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); - return -2; - } - } - catch (Exception $e) - { - global $langs, $errormsg; - $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); - $errormsg=$langs->trans("ErrorFailedToWriteInDir"); - return -1; - } + try + { + $data = implode("", file(dol_osencode($inputfile))); + if ($mode == 'gz') { $foundhandler=1; $compressdata = gzencode($data, 9); } + elseif ($mode == 'bz') { $foundhandler=1; $compressdata = bzcompress($data, 9); } + elseif ($mode == 'zip') + { + if (defined('ODTPHP_PATHTOPCLZIP')) + { + $foundhandler=1; + + include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; + $archive = new PclZip($outputfile); + $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile)); + //$archive->add($inputfile); + return 1; + } + } + + if ($foundhandler) + { + $fp = fopen($outputfile, "w"); + fwrite($fp, $compressdata); + fclose($fp); + return 1; + } + else + { + dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); + return -2; + } + } + catch (Exception $e) + { + global $langs, $errormsg; + $langs->load("errors"); + dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + $errormsg=$langs->trans("ErrorFailedToWriteInDir"); + return -1; + } } /** @@ -1759,17 +1759,17 @@ function dol_compress_file($inputfile, $outputfile, $mode="gz") */ function dol_uncompress($inputfile,$outputdir) { - global $langs; - - if (defined('ODTPHP_PATHTOPCLZIP')) - { - dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir); - include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; - $archive = new PclZip($inputfile); - $result=$archive->extract(PCLZIP_OPT_PATH, $outputdir); - //var_dump($result); - if (! is_array($result) && $result <= 0) return array('error'=>$archive->errorInfo(true)); - else + global $langs; + + if (defined('ODTPHP_PATHTOPCLZIP')) + { + dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir); + include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; + $archive = new PclZip($inputfile); + $result=$archive->extract(PCLZIP_OPT_PATH, $outputdir); + //var_dump($result); + if (! is_array($result) && $result <= 0) return array('error'=>$archive->errorInfo(true)); + else { $ok=1; $errmsg=''; // Loop on each file to check result for unzipping file @@ -1787,26 +1787,26 @@ function dol_uncompress($inputfile,$outputdir) if ($ok) return array(); else return array('error'=>$errmsg); } - } - - if (class_exists('ZipArchive')) - { - dol_syslog("Class ZipArchive is set so we unzip using ZipArchive to unzip into ".$outputdir); - $zip = new ZipArchive; - $res = $zip->open($inputfile); - if ($res === TRUE) - { - $zip->extractTo($outputdir.'/'); - $zip->close(); - return array(); - } - else - { - return array('error'=>'ErrUnzipFails'); - } - } - - return array('error'=>'ErrNoZipEngine'); + } + + if (class_exists('ZipArchive')) + { + dol_syslog("Class ZipArchive is set so we unzip using ZipArchive to unzip into ".$outputdir); + $zip = new ZipArchive; + $res = $zip->open($inputfile); + if ($res === TRUE) + { + $zip->extractTo($outputdir.'/'); + $zip->close(); + return array(); + } + else + { + return array('error'=>'ErrUnzipFails'); + } + } + + return array('error'=>'ErrNoZipEngine'); } @@ -1820,25 +1820,25 @@ function dol_uncompress($inputfile,$outputdir) */ function dol_compress_dir($inputdir, $outputfile, $mode="zip") { - $foundhandler=0; + $foundhandler=0; - dol_syslog("Try to zip dir ".$inputdir." into ".$outputdir." mode=".$mode); + dol_syslog("Try to zip dir ".$inputdir." into ".$outputdir." mode=".$mode); - if (! dol_is_dir(dirname($outputfile)) || ! is_writable(dirname($outputfile))) - { - global $langs, $errormsg; - $langs->load("errors"); - $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); + if (! dol_is_dir(dirname($outputfile)) || ! is_writable(dirname($outputfile))) + { + global $langs, $errormsg; + $langs->load("errors"); + $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); return -3; - } - - try - { - if ($mode == 'gz') { $foundhandler=0; } - elseif ($mode == 'bz') { $foundhandler=0; } - elseif ($mode == 'zip') - { - /*if (defined('ODTPHP_PATHTOPCLZIP')) + } + + try + { + if ($mode == 'gz') { $foundhandler=0; } + elseif ($mode == 'bz') { $foundhandler=0; } + elseif ($mode == 'zip') + { + /*if (defined('ODTPHP_PATHTOPCLZIP')) { $foundhandler=0; // TODO implement this @@ -1849,61 +1849,61 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") return 1; } else*/ - if (class_exists('ZipArchive')) - { - $foundhandler=1; - - // Initialize archive object - $zip = new ZipArchive(); - $result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); - - // Create recursive directory iterator - /** @var SplFileInfo[] $files */ - $files = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($inputdir), - RecursiveIteratorIterator::LEAVES_ONLY - ); - - foreach ($files as $name => $file) - { - // Skip directories (they would be added automatically) - if (!$file->isDir()) - { - // Get real and relative path for current file - $filePath = $file->getRealPath(); - $relativePath = substr($filePath, strlen($inputdir) + 1); - - // Add current file to archive - $zip->addFile($filePath, $relativePath); - } - } - - // Zip archive will be created only after closing object - $zip->close(); + if (class_exists('ZipArchive')) + { + $foundhandler=1; - return 1; - } - } - - if (! $foundhandler) - { - dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); - return -2; - } - else - { - return 0; - } - } - catch (Exception $e) - { - global $langs, $errormsg; - $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile, LOG_ERR); - dol_syslog($e->getMessage(), LOG_ERR); - $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); - return -1; - } + // Initialize archive object + $zip = new ZipArchive(); + $result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); + + // Create recursive directory iterator + /** @var SplFileInfo[] $files */ + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($inputdir), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($files as $name => $file) + { + // Skip directories (they would be added automatically) + if (!$file->isDir()) + { + // Get real and relative path for current file + $filePath = $file->getRealPath(); + $relativePath = substr($filePath, strlen($inputdir) + 1); + + // Add current file to archive + $zip->addFile($filePath, $relativePath); + } + } + + // Zip archive will be created only after closing object + $zip->close(); + + return 1; + } + } + + if (! $foundhandler) + { + dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); + return -2; + } + else + { + return 0; + } + } + catch (Exception $e) + { + global $langs, $errormsg; + $langs->load("errors"); + dol_syslog("Failed to open file ".$outputfile, LOG_ERR); + dol_syslog($e->getMessage(), LOG_ERR); + $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); + return -1; + } } @@ -1920,8 +1920,8 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") */ function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta|_preview.*\.png)$','^\.'),$nohook=false,$mode='') { - $tmparray=dol_dir_list($dir,'files',0,$regexfilter,$excludefilter,'date',SORT_DESC,$mode,$nohook); - return $tmparray[0]; + $tmparray=dol_dir_list($dir,'files',0,$regexfilter,$excludefilter,'date',SORT_DESC,$mode,$nohook); + return $tmparray[0]; } /** @@ -1951,7 +1951,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $sqlprotectagainstexternals=''; $ret=array(); - // Find the subdirectory name as the reference. For exemple original_file='10/myfile.pdf' -> refname='10' + // Find the subdirectory name as the reference. For exemple original_file='10/myfile.pdf' -> refname='10' if (empty($refname)) $refname=basename(dirname($original_file)."/"); $relative_original_file = $original_file; @@ -1960,20 +1960,20 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $lire='lire'; $read='read'; $download='download'; if ($mode == 'write') { - $lire='creer'; $read='write'; $download='upload'; + $lire='creer'; $read='write'; $download='upload'; } // Wrapping for miscellaneous medias files if ($modulepart == 'medias' && !empty($dolibarr_main_data_root)) { - $accessallowed=1; - $original_file=$conf->medias->multidir_output[$entity].'/'.$original_file; + $accessallowed=1; + $original_file=$conf->medias->multidir_output[$entity].'/'.$original_file; } // Wrapping for *.log files, like when used with url http://.../document.php?modulepart=logs&file=dolibarr.log elseif ($modulepart == 'logs' && !empty($dolibarr_main_data_root)) { - $accessallowed=($user->admin && basename($original_file) == $original_file && preg_match('/^dolibarr.*\.log$/', basename($original_file))); - $original_file=$dolibarr_main_data_root.'/'.$original_file; + $accessallowed=($user->admin && basename($original_file) == $original_file && preg_match('/^dolibarr.*\.log$/', basename($original_file))); + $original_file=$dolibarr_main_data_root.'/'.$original_file; } // Wrapping for *.zip files, like when used with url http://.../document.php?modulepart=packages&file=module_myfile.zip elseif ($modulepart == 'packages' && !empty($dolibarr_main_data_root)) @@ -1982,8 +1982,8 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $tmp=explode(',', $dolibarr_main_document_root_alt); $dirins = $tmp[0]; - $accessallowed=($user->admin && preg_match('/^module_.*\.zip$/', basename($original_file))); - $original_file=$dirins.'/'.$original_file; + $accessallowed=($user->admin && preg_match('/^module_.*\.zip$/', basename($original_file))); + $original_file=$dirins.'/'.$original_file; } // Wrapping for some images elseif (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output)) @@ -2024,38 +2024,38 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping pour les apercu intervention elseif (($modulepart == 'apercufichinter' || $modulepart == 'apercuficheinter') && !empty($conf->ficheinter->dir_output)) { - if ($fuser->rights->ficheinter->{$lire}) $accessallowed=1; - $original_file=$conf->ficheinter->dir_output.'/'.$original_file; + if ($fuser->rights->ficheinter->{$lire}) $accessallowed=1; + $original_file=$conf->ficheinter->dir_output.'/'.$original_file; } // Wrapping pour les apercu conat elseif (($modulepart == 'apercucontract') && !empty($conf->contrat->dir_output)) { - if ($fuser->rights->contrat->{$lire}) $accessallowed=1; - $original_file=$conf->contrat->dir_output.'/'.$original_file; + if ($fuser->rights->contrat->{$lire}) $accessallowed=1; + $original_file=$conf->contrat->dir_output.'/'.$original_file; } // Wrapping pour les apercu supplier proposal elseif (($modulepart == 'apercusupplier_proposal' || $modulepart == 'apercusupplier_proposal') && !empty($conf->supplier_proposal->dir_output)) { - if ($fuser->rights->supplier_proposal->{$lire}) $accessallowed=1; - $original_file=$conf->supplier_proposal->dir_output.'/'.$original_file; + if ($fuser->rights->supplier_proposal->{$lire}) $accessallowed=1; + $original_file=$conf->supplier_proposal->dir_output.'/'.$original_file; } // Wrapping pour les apercu supplier order elseif (($modulepart == 'apercusupplier_order' || $modulepart == 'apercusupplier_order') && !empty($conf->fournisseur->commande->dir_output)) { - if ($fuser->rights->fournisseur->commande->{$lire}) $accessallowed=1; - $original_file=$conf->fournisseur->commande->dir_output.'/'.$original_file; + if ($fuser->rights->fournisseur->commande->{$lire}) $accessallowed=1; + $original_file=$conf->fournisseur->commande->dir_output.'/'.$original_file; } // Wrapping pour les apercu supplier invoice elseif (($modulepart == 'apercusupplier_invoice' || $modulepart == 'apercusupplier_invoice') && !empty($conf->fournisseur->facture->dir_output)) { - if ($fuser->rights->fournisseur->facture->{$lire}) $accessallowed=1; - $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file; + if ($fuser->rights->fournisseur->facture->{$lire}) $accessallowed=1; + $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file; } // Wrapping pour les apercu supplier invoice elseif (($modulepart == 'apercuexpensereport') && !empty($conf->expensereport->dir_output)) { - if ($fuser->rights->expensereport->{$lire}) $accessallowed=1; - $original_file=$conf->expensereport->dir_output.'/'.$original_file; + if ($fuser->rights->expensereport->{$lire}) $accessallowed=1; + $original_file=$conf->expensereport->dir_output.'/'.$original_file; } // Wrapping pour les images des stats propales elseif ($modulepart == 'propalstats' && !empty($conf->propal->dir_temp)) @@ -2181,13 +2181,13 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping for users else if ($modulepart == 'user' && !empty($conf->user->dir_output)) { - $canreaduser=(! empty($fuser->admin) || $fuser->rights->user->user->{$lire}); - if ($fuser->id == (int) $refname) { $canreaduser=1; } // A user can always read its own card - if ($canreaduser || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->user->dir_output.'/'.$original_file; + $canreaduser=(! empty($fuser->admin) || $fuser->rights->user->user->{$lire}); + if ($fuser->id == (int) $refname) { $canreaduser=1; } // A user can always read its own card + if ($canreaduser || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->user->dir_output.'/'.$original_file; } // Wrapping for third parties @@ -2224,67 +2224,67 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping for mass actions else if ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->dir_output)) { - if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->propal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->propal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_orders') { - if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_invoices') { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_expensereport') { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_interventions') { - if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->ficheinter->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->ficheinter->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->propal->dir_output)) { - if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->supplier_proposal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->supplier_proposal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_supplier_order') { - if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_supplier_invoice') { - if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) - { - $accessallowed=1; - } - $original_file=$conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else if ($modulepart == 'massfilesarea_contract' && !empty($conf->contrat->dir_output)) { @@ -2577,15 +2577,15 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file; } - // GENERIC Wrapping - // If modulepart=module_user_temp Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp/iduser - // If modulepart=module_temp Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp - // If modulepart=module_user Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/iduser - // If modulepart=module Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart - else + // GENERIC Wrapping + // If modulepart=module_user_temp Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp/iduser + // If modulepart=module_temp Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp + // If modulepart=module_user Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/iduser + // If modulepart=module Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart + else { - if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a file called specimen. Test must be done before changing $original_file int full path. - if ($fuser->admin) $accessallowed=1; // If user is admin + if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a file called specimen. Test must be done before changing $original_file int full path. + if ($fuser->admin) $accessallowed=1; // If user is admin // Define $accessallowed if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg)) @@ -2595,7 +2595,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } - if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; + if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$fuser->id.'/'.$original_file; } else if (preg_match('/^([a-z]+)_temp$/i',$modulepart,$reg)) @@ -2605,7 +2605,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } - if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; + if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$original_file; } else if (preg_match('/^([a-z]+)_user$/i',$modulepart,$reg)) @@ -2615,7 +2615,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } - if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; + if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file; } else @@ -2679,10 +2679,10 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, */ function dol_filecache($directory, $filename, $object) { - if (! dol_is_dir($directory)) dol_mkdir($directory); - $cachefile = $directory . $filename; - file_put_contents($cachefile, serialize($object), LOCK_EX); - @chmod($cachefile, 0644); + if (! dol_is_dir($directory)) dol_mkdir($directory); + $cachefile = $directory . $filename; + file_put_contents($cachefile, serialize($object), LOCK_EX); + @chmod($cachefile, 0644); } /** @@ -2695,10 +2695,10 @@ function dol_filecache($directory, $filename, $object) */ function dol_cache_refresh($directory, $filename, $cachetime) { - $now = dol_now(); - $cachefile = $directory . $filename; - $refresh = !file_exists($cachefile) || ($now-$cachetime) > dol_filemtime($cachefile); - return $refresh; + $now = dol_now(); + $cachefile = $directory . $filename; + $refresh = !file_exists($cachefile) || ($now-$cachetime) > dol_filemtime($cachefile); + return $refresh; } /** @@ -2710,7 +2710,7 @@ function dol_cache_refresh($directory, $filename, $cachetime) */ function dol_readcachefile($directory, $filename) { - $cachefile = $directory . $filename; - $object = unserialize(file_get_contents($cachefile)); - return $object; + $cachefile = $directory . $filename; + $object = unserialize(file_get_contents($cachefile)); + return $object; } diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 3f6d5269bae30e1a444c1c0af6c447dc100be09b..e6c4949276916776dac2ccfa9296bf04bcfc0fc6 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -44,7 +44,7 @@ function project_prepare_head($object) $head[$h][2] = 'project'; $h++; - $nbContact = count($object->liste_contact(-1,'internal')) + count($object->liste_contact(-1,'external')); + $nbContact = count($object->liste_contact(-1,'internal')) + count($object->liste_contact(-1,'external')); $head[$h][0] = DOL_URL_ROOT.'/projet/contact.php?id='.$object->id; $head[$h][1] = $langs->trans("ProjectContact"); if ($nbContact > 0) $head[$h][1].= ' <span class="badge">'.$nbContact.'</span>'; @@ -69,22 +69,22 @@ function project_prepare_head($object) if (empty($conf->global->MAIN_DISABLE_NOTES_TAB)) - { - $nbNote = 0; - if(!empty($object->note_private)) $nbNote++; + { + $nbNote = 0; + if(!empty($object->note_private)) $nbNote++; if(!empty($object->note_public)) $nbNote++; $head[$h][0] = DOL_URL_ROOT.'/projet/note.php?id='.$object->id; $head[$h][1] = $langs->trans('Notes'); if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>'; $head[$h][2] = 'notes'; $h++; - } + } require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; $upload_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($object->ref); $nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview.*\.png)$')); - $nbLinks=Link::count($db, $object->element, $object->id); + $nbLinks=Link::count($db, $object->element, $object->id); $head[$h][0] = DOL_URL_ROOT.'/projet/document.php?id='.$object->id; $head[$h][1] = $langs->trans('Documents'); if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' <span class="badge">'.($nbFiles+$nbLinks).'</span>'; @@ -123,12 +123,12 @@ function project_prepare_head($object) } $head[$h][0] = DOL_URL_ROOT.'/projet/info.php?id='.$object->id; - $head[$h][1].= $langs->trans("Events"); - if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) )) - { - $head[$h][1].= '/'; - $head[$h][1].= $langs->trans("Agenda"); - } + $head[$h][1].= $langs->trans("Events"); + if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) )) + { + $head[$h][1].= '/'; + $head[$h][1].= $langs->trans("Agenda"); + } $head[$h][2] = 'agenda'; $h++; @@ -171,8 +171,8 @@ function task_prepare_head($object) $resql = $db->query($sql); if ($resql) { - $obj = $db->fetch_object($resql); - if ($obj) $nbTimeSpent=1; + $obj = $db->fetch_object($resql); + if ($obj) $nbTimeSpent=1; } else dol_print_error($db); @@ -189,23 +189,23 @@ function task_prepare_head($object) complete_head_from_modules($conf,$langs,$object,$head,$h,'task'); if (empty($conf->global->MAIN_DISABLE_NOTES_TAB)) - { - $nbNote = 0; - if(!empty($object->note_private)) $nbNote++; + { + $nbNote = 0; + if(!empty($object->note_private)) $nbNote++; if(!empty($object->note_public)) $nbNote++; $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/note.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':''); $head[$h][1] = $langs->trans('Notes'); if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>'; $head[$h][2] = 'task_notes'; $h++; - } + } $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/document.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':''); $filesdir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($object->project->ref) . '/' .dol_sanitizeFileName($object->ref); include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; $nbFiles = count(dol_dir_list($filesdir,'files',0,'','(\.meta|_preview.*\.png)$')); - $nbLinks=Link::count($db, $object->element, $object->id); + $nbLinks=Link::count($db, $object->element, $object->id); $head[$h][1] = $langs->trans('Documents'); if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' <span class="badge">'.($nbFiles+$nbLinks).'</span>'; $head[$h][2] = 'task_document'; @@ -467,11 +467,11 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t // Date end print '<td align="center">'; $taskstatic->projectstatus = $lines[$i]->projectstatus; - $taskstatic->progress = $lines[$i]->progress; - $taskstatic->fk_statut = $lines[$i]->status; - $taskstatic->datee = $lines[$i]->date_end; - print dol_print_date($lines[$i]->date_end,'dayhour'); - if ($taskstatic->hasDelay()) print img_warning($langs->trans("Late")); + $taskstatic->progress = $lines[$i]->progress; + $taskstatic->fk_statut = $lines[$i]->status; + $taskstatic->datee = $lines[$i]->date_end; + print dol_print_date($lines[$i]->date_end,'dayhour'); + if ($taskstatic->hasDelay()) print img_warning($langs->trans("Late")); print '</td>'; $plannedworkloadoutputformat='allhourmin'; @@ -531,9 +531,9 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t if ($level >= 0) // Call sublevels { - $level++; - if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick); - $level--; + $level++; + if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick); + $level--; } $total_projectlinesa_spent += $lines[$i]->duration; @@ -605,13 +605,13 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr // Create a smaller array with sublevels only to be used later. This increase dramatically performances. if ($parent == 0) // Always and only if at first level { - for ($i = 0 ; $i < $numlines ; $i++) - { - if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i]; - } + for ($i = 0 ; $i < $numlines ; $i++) + { + if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i]; + } } - //dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0)); + //dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0)); for ($i = 0 ; $i < $numlines ; $i++) { if ($parent == 0) $level = 0; @@ -621,26 +621,26 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr // If we want all or we have a role on task, we show it if (empty($mine) || ! empty($tasksrole[$lines[$i]->id])) { - //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); + //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); // Break on a new project - if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) - { - $lastprojectid=$lines[$i]->fk_project; - if ($preselectedday) - { - $projectstatic->id = $lines[$i]->fk_project; - } - } - - if (empty($workloadforid[$projectstatic->id])) - { - if ($preselectedday) - { - $projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week - $workloadforid[$projectstatic->id]=1; - } - } + if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) + { + $lastprojectid=$lines[$i]->fk_project; + if ($preselectedday) + { + $projectstatic->id = $lines[$i]->fk_project; + } + } + + if (empty($workloadforid[$projectstatic->id])) + { + if ($preselectedday) + { + $projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $workloadforid[$projectstatic->id]=1; + } + } $projectstatic->id=$lines[$i]->fk_project; $projectstatic->ref=$lines[$i]->projectref; @@ -665,12 +665,12 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) { - // Thirdparty - print '<td class="tdoverflowmax100">'; - $thirdpartystatic->id=$lines[$i]->socid; - $thirdpartystatic->name=$lines[$i]->thirdparty_name; - print $thirdpartystatic->getNomUrl(1, 'project', 10); - print '</td>'; + // Thirdparty + print '<td class="tdoverflowmax100">'; + $thirdpartystatic->id=$lines[$i]->socid; + $thirdpartystatic->name=$lines[$i]->thirdparty_name; + print $thirdpartystatic->getNomUrl(1, 'project', 10); + print '</td>'; } // Ref @@ -753,14 +753,14 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print '<td align="center" class="duration'.($cssonholiday?' '.$cssonholiday:'').'">'; $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id]; - $alreadyspent=''; - if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); + $alreadyspent=''; + if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); - $idw = 0; + $idw = 0; $tableCell=''; $tableCell.='<span class="timesheetalreadyrecorded"><input type="text" class="center" size="2" disabled id="timespent['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="'.$alreadyspent.'"></span>'; - $tableCell.='<span class="hideonsmartphone"> + </span>'; + $tableCell.='<span class="hideonsmartphone"> + </span>'; //$tableCell.=' '; $tableCell.=$form->select_duration($lines[$i]->id.'duration','',$disabledtask,'text',0,1); //$tableCell.=' <input type="submit" class="button"'.($disabledtask?' disabled':'').' value="'.$langs->trans("Add").'">'; @@ -800,8 +800,8 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); - else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); + if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); + else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); } $level--; } @@ -845,13 +845,13 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ // Create a smaller array with sublevels only to be used later. This increase dramatically performances. if ($parent == 0) // Always and only if at first level { - for ($i = 0 ; $i < $numlines ; $i++) - { - if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i]; - } + for ($i = 0 ; $i < $numlines ; $i++) + { + if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i]; + } } - //dol_syslog('projectLinesPerWeek inc='.$inc.' firstdaytoshow='.$firstdaytoshow.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0)); + //dol_syslog('projectLinesPerWeek inc='.$inc.' firstdaytoshow='.$firstdaytoshow.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0)); for ($i = 0 ; $i < $numlines ; $i++) { @@ -862,20 +862,20 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ // If we want all or we have a role on task, we show it if (empty($mine) || ! empty($tasksrole[$lines[$i]->id])) { - //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); + //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); - // Break on a new project - if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) - { - $lastprojectid=$lines[$i]->fk_project; - $projectstatic->id = $lines[$i]->fk_project; - } + // Break on a new project + if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) + { + $lastprojectid=$lines[$i]->fk_project; + $projectstatic->id = $lines[$i]->fk_project; + } - if (empty($workloadforid[$projectstatic->id])) - { - $projectstatic->loadTimeSpent($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week - $workloadforid[$projectstatic->id]=1; - } + if (empty($workloadforid[$projectstatic->id])) + { + $projectstatic->loadTimeSpent($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $workloadforid[$projectstatic->id]=1; + } $projectstatic->id=$lines[$i]->fk_project; $projectstatic->ref=$lines[$i]->projectref; @@ -899,12 +899,12 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) { - // Thirdparty - print '<td class="tdoverflowmax100">'; - $thirdpartystatic->id=$lines[$i]->thirdparty_id; - $thirdpartystatic->name=$lines[$i]->thirdparty_name; - print $thirdpartystatic->getNomUrl(1, 'project'); - print '</td>'; + // Thirdparty + print '<td class="tdoverflowmax100">'; + $thirdpartystatic->id=$lines[$i]->thirdparty_id; + $thirdpartystatic->name=$lines[$i]->thirdparty_name; + print $thirdpartystatic->getNomUrl(1, 'project'); + print '</td>'; } // Ref @@ -979,7 +979,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ // Fields to show current time $tableCell=''; $modeinput='hours'; for ($idw = 0; $idw < 7; $idw++) - { + { $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd'); $cssonholiday=''; @@ -988,28 +988,28 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ elseif (! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayafternoon '; $tmparray=dol_getdate($tmpday); - $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id]; - $alreadyspent=''; - if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); - $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']); - - $tableCell ='<td align="center" class="hide'.$idw.($cssonholiday?' '.$cssonholiday:'').'">'; - if ($alreadyspent) - { - $tableCell.='<span class="timesheetalreadyrecorded"><input type="text" class="center smallpadd" size="2" disabled id="timespent['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="'.$alreadyspent.'"></span>'; - //$placeholder=' placeholder="00:00"'; - $placeholder=''; - //$tableCell.='+'; - } - $tableCell.='<input type="text" alt="'.($disabledtask?'':$alttitle).'" title="'.($disabledtask?'':$alttitle).'" '.($disabledtask?'disabled':$placeholder).' class="center smallpadd" size="2" id="timeadded['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="" cols="2" maxlength="5"'; - $tableCell.=' onkeypress="return regexEvent(this,event,\'timeChar\')"'; - $tableCell.=' onkeyup="updateTotal('.$idw.',\''.$modeinput.'\')"'; - $tableCell.=' onblur="regexEvent(this,event,\''.$modeinput.'\'); updateTotal('.$idw.',\''.$modeinput.'\')" />'; - $tableCell.='</td>'; - print $tableCell; - } - - // Warning + $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id]; + $alreadyspent=''; + if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); + $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']); + + $tableCell ='<td align="center" class="hide'.$idw.($cssonholiday?' '.$cssonholiday:'').'">'; + if ($alreadyspent) + { + $tableCell.='<span class="timesheetalreadyrecorded"><input type="text" class="center smallpadd" size="2" disabled id="timespent['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="'.$alreadyspent.'"></span>'; + //$placeholder=' placeholder="00:00"'; + $placeholder=''; + //$tableCell.='+'; + } + $tableCell.='<input type="text" alt="'.($disabledtask?'':$alttitle).'" title="'.($disabledtask?'':$alttitle).'" '.($disabledtask?'disabled':$placeholder).' class="center smallpadd" size="2" id="timeadded['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="" cols="2" maxlength="5"'; + $tableCell.=' onkeypress="return regexEvent(this,event,\'timeChar\')"'; + $tableCell.=' onkeyup="updateTotal('.$idw.',\''.$modeinput.'\')"'; + $tableCell.=' onblur="regexEvent(this,event,\''.$modeinput.'\'); updateTotal('.$idw.',\''.$modeinput.'\')" />'; + $tableCell.='</td>'; + print $tableCell; + } + + // Warning print '<td align="right">'; if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject")); else if ($disabledtask) @@ -1021,7 +1021,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ } print '</td>'; - print "</tr>\n"; + print "</tr>\n"; } // Call to show task with a lower level (task under the current task) @@ -1029,8 +1029,8 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); - else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); + if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); + else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); } $level--; } @@ -1100,7 +1100,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $projectstatic=new Project($db); - $thirdpartystatic=new Societe($db); + $thirdpartystatic=new Societe($db); $sortfield=''; $sortorder=''; @@ -1161,12 +1161,12 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $resql = $db->query($sql1); if ($resql) { - $i=0; + $i=0; $num = $db->num_rows($resql); while ($i < $num) { $objp = $db->fetch_object($resql); - $arrayidofprojects[$objp->projectid]=$objp->projectid; + $arrayidofprojects[$objp->projectid]=$objp->projectid; $i++; } } @@ -1194,22 +1194,22 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $num = $db->num_rows($resql); $i = 0; - print '<tr class="liste_titre">'; - print_liste_field_titre($title.' <span class="badge">'.$num.'</span>',$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder); - print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder); - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) - { - print_liste_field_titre("OpportunityAmount","","","","",'align="right"',$sortfield,$sortorder); - print_liste_field_titre("OpportunityStatus","","","","",'align="right"',$sortfield,$sortorder); - } - if (empty($conf->global->PROJECT_HIDE_TASKS)) - { - print_liste_field_titre("Tasks","","","","",'align="right"',$sortfield,$sortorder); - if (! in_array('plannedworkload', $hiddenfields)) print_liste_field_titre("PlannedWorkload","","","","",'align="right"',$sortfield,$sortorder); - if (! in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared","","","","",'align="right"',$sortfield,$sortorder); - } - print_liste_field_titre("Status","","","","",'align="right"',$sortfield,$sortorder); - print "</tr>\n"; + print '<tr class="liste_titre">'; + print_liste_field_titre($title.' <span class="badge">'.$num.'</span>',$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder); + print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder); + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + { + print_liste_field_titre("OpportunityAmount","","","","",'align="right"',$sortfield,$sortorder); + print_liste_field_titre("OpportunityStatus","","","","",'align="right"',$sortfield,$sortorder); + } + if (empty($conf->global->PROJECT_HIDE_TASKS)) + { + print_liste_field_titre("Tasks","","","","",'align="right"',$sortfield,$sortorder); + if (! in_array('plannedworkload', $hiddenfields)) print_liste_field_titre("PlannedWorkload","","","","",'align="right"',$sortfield,$sortorder); + if (! in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared","","","","",'align="right"',$sortfield,$sortorder); + } + print_liste_field_titre("Status","","","","",'align="right"',$sortfield,$sortorder); + print "</tr>\n"; while ($i < $num) { @@ -1223,11 +1223,11 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $userAccess = $projectstatic->restrictedProjectArea($user); if ($userAccess >= 0) { - $projectstatic->ref=$objp->ref; - $projectstatic->statut = $objp->status; - $projectstatic->title = $objp->title; - $projectstatic->datee = $db->jdate($objp->datee); - $projectstatic->dateo = $db->jdate($objp->dateo); + $projectstatic->ref=$objp->ref; + $projectstatic->statut = $objp->status; + $projectstatic->title = $objp->title; + $projectstatic->datee = $db->jdate($objp->datee); + $projectstatic->dateo = $db->jdate($objp->dateo); print '<tr class="oddeven">'; @@ -1238,41 +1238,41 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= print '<td>'; if ($objp->fk_soc > 0) { - $thirdpartystatic->id=$objp->fk_soc; - $thirdpartystatic->ref=$objp->socname; - $thirdpartystatic->name=$objp->socname; - print $thirdpartystatic->getNomUrl(1); + $thirdpartystatic->id=$objp->fk_soc; + $thirdpartystatic->ref=$objp->socname; + $thirdpartystatic->name=$objp->socname; + print $thirdpartystatic->getNomUrl(1); } print '</td>'; if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { print '<td align="right">'; - if ($objp->opp_amount) print price($objp->opp_amount, 0, '', 1, -1, -1, $conf->currency); + if ($objp->opp_amount) print price($objp->opp_amount, 0, '', 1, -1, -1, $conf->currency); print '</td>'; print '<td align="right">'; $code = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code'); - if ($code) print $langs->trans("OppStatus".$code); + if ($code) print $langs->trans("OppStatus".$code); print '</td>'; } if (empty($conf->global->PROJECT_HIDE_TASKS)) { - print '<td align="right">'.$objp->nb.'</td>'; - - $plannedworkload=$objp->planned_workload; - $total_plannedworkload+=$plannedworkload; - if (! in_array('plannedworkload', $hiddenfields)) - { - print '<td align="right">'.($plannedworkload?convertSecondToTime($plannedworkload):'').'</td>'; - } - if (! in_array('declaredprogress', $hiddenfields)) - { - $declaredprogressworkload=$objp->declared_progess_workload; - $total_declaredprogressworkload+=$declaredprogressworkload; - print '<td align="right">'; - //print $objp->planned_workload.'-'.$objp->declared_progess_workload."<br>"; - print ($plannedworkload?round(100*$declaredprogressworkload/$plannedworkload,0).'%':''); - print '</td>'; - } + print '<td align="right">'.$objp->nb.'</td>'; + + $plannedworkload=$objp->planned_workload; + $total_plannedworkload+=$plannedworkload; + if (! in_array('plannedworkload', $hiddenfields)) + { + print '<td align="right">'.($plannedworkload?convertSecondToTime($plannedworkload):'').'</td>'; + } + if (! in_array('declaredprogress', $hiddenfields)) + { + $declaredprogressworkload=$objp->declared_progess_workload; + $total_declaredprogressworkload+=$declaredprogressworkload; + print '<td align="right">'; + //print $objp->planned_workload.'-'.$objp->declared_progess_workload."<br>"; + print ($plannedworkload?round(100*$declaredprogressworkload/$plannedworkload,0).'%':''); + print '</td>'; + } } print '<td align="right">'.$projectstatic->getLibStatut(3).'</td>'; @@ -1295,12 +1295,12 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= } if (empty($conf->global->PROJECT_HIDE_TASKS)) { - print '<td class="liste_total" align="right">'.$total_task.'</td>'; - if (! in_array('plannedworkload', $hiddenfields)) print '<td class="liste_total" align="right">'.($total_plannedworkload?convertSecondToTime($total_plannedworkload):'').'</td>'; - if (! in_array('declaredprogress', $hiddenfields)) print '<td class="liste_total" align="right">'.($total_plannedworkload?round(100*$total_declaredprogressworkload/$total_plannedworkload,0).'%':'').'</td>'; + print '<td class="liste_total" align="right">'.$total_task.'</td>'; + if (! in_array('plannedworkload', $hiddenfields)) print '<td class="liste_total" align="right">'.($total_plannedworkload?convertSecondToTime($total_plannedworkload):'').'</td>'; + if (! in_array('declaredprogress', $hiddenfields)) print '<td class="liste_total" align="right">'.($total_plannedworkload?round(100*$total_declaredprogressworkload/$total_plannedworkload,0).'%':'').'</td>'; } print '<td class="liste_total"></td>'; - print '</tr>'; + print '</tr>'; $db->free($resql); } diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 428f8451894adf1cf37ef3b7076bafd79e526339..8f73678a532f981dcd7878f8a37df306ea400845 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -45,10 +45,10 @@ function user_prepare_head($object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/user/card.php?id='.$object->id; - $head[$h][1] = $langs->trans("UserCard"); - $head[$h][2] = 'user'; - $h++; + $head[$h][0] = DOL_URL_ROOT.'/user/card.php?id='.$object->id; + $head[$h][1] = $langs->trans("UserCard"); + $head[$h][2] = 'user'; + $h++; if ((! empty($conf->ldap->enabled) && ! empty($conf->global->LDAP_SYNCHRO_ACTIVE)) && (empty($conf->global->MAIN_DISABLE_LDAP_TAB) || ! empty($user->admin))) @@ -60,10 +60,10 @@ function user_prepare_head($object) $h++; } - $head[$h][0] = DOL_URL_ROOT.'/user/param_ihm.php?id='.$object->id; - $head[$h][1] = $langs->trans("UserGUISetup"); - $head[$h][2] = 'guisetup'; - $h++; + $head[$h][0] = DOL_URL_ROOT.'/user/param_ihm.php?id='.$object->id; + $head[$h][1] = $langs->trans("UserGUISetup"); + $head[$h][2] = 'guisetup'; + $h++; if ($canreadperms) { @@ -73,116 +73,116 @@ function user_prepare_head($object) $h++; } - if (! empty($conf->agenda->enabled)) - { - if (empty($conf->global->AGENDA_EXT_NB)) $conf->global->AGENDA_EXT_NB=5; - $MAXAGENDA=$conf->global->AGENDA_EXT_NB; - - $i=1; - $nbagenda = 0; - while ($i <= $MAXAGENDA) - { - $key=$i; - $name='AGENDA_EXT_NAME_'.$object->id.'_'.$key; - $src='AGENDA_EXT_SRC_'.$object->id.'_'.$key; - $offsettz='AGENDA_EXT_OFFSETTZ_'.$object->id.'_'.$key; - $color='AGENDA_EXT_COLOR_'.$object->id.'_'.$key; - $i++; - - if (! empty($object->conf->$name)) $nbagenda++; - } - - $head[$h][0] = DOL_URL_ROOT.'/user/agenda_extsites.php?id='.$object->id; - $head[$h][1] = $langs->trans("ExtSites").($nbagenda ? ' <span class="badge">'.$nbagenda.'</span>' : ''); - $head[$h][2] = 'extsites'; - $h++; - } - - if (! empty($conf->clicktodial->enabled)) - { - $head[$h][0] = DOL_URL_ROOT.'/user/clicktodial.php?id='.$object->id; - $head[$h][1] = $langs->trans("ClickToDial"); - $head[$h][2] = 'clicktodial'; - $h++; - } - - // Notifications - if ($user->societe_id == 0 && ! empty($conf->notification->enabled)) - { - $nbNote = 0; - $sql = "SELECT COUNT(n.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n"; - $sql.= " WHERE fk_user = ".$object->id; - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $db->fetch_object($resql); - $nbNote=$obj->nb; - $i++; - } - } - else { - dol_print_error($db); - } - - $head[$h][0] = DOL_URL_ROOT.'/user/notify/card.php?id='.$object->id; - $head[$h][1] = $langs->trans("Notifications"); - if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>'; - $head[$h][2] = 'notify'; - $h++; - } - - // Show more tabs from modules - // Entries must be declared in modules descriptor with line - // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab - // $this->tabs = array('entity:-tabname); to remove a tab - complete_head_from_modules($conf,$langs,$object,$head,$h,'user'); - - if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) - || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) - { + if (! empty($conf->agenda->enabled)) + { + if (empty($conf->global->AGENDA_EXT_NB)) $conf->global->AGENDA_EXT_NB=5; + $MAXAGENDA=$conf->global->AGENDA_EXT_NB; + + $i=1; + $nbagenda = 0; + while ($i <= $MAXAGENDA) + { + $key=$i; + $name='AGENDA_EXT_NAME_'.$object->id.'_'.$key; + $src='AGENDA_EXT_SRC_'.$object->id.'_'.$key; + $offsettz='AGENDA_EXT_OFFSETTZ_'.$object->id.'_'.$key; + $color='AGENDA_EXT_COLOR_'.$object->id.'_'.$key; + $i++; + + if (! empty($object->conf->$name)) $nbagenda++; + } + + $head[$h][0] = DOL_URL_ROOT.'/user/agenda_extsites.php?id='.$object->id; + $head[$h][1] = $langs->trans("ExtSites").($nbagenda ? ' <span class="badge">'.$nbagenda.'</span>' : ''); + $head[$h][2] = 'extsites'; + $h++; + } + + if (! empty($conf->clicktodial->enabled)) + { + $head[$h][0] = DOL_URL_ROOT.'/user/clicktodial.php?id='.$object->id; + $head[$h][1] = $langs->trans("ClickToDial"); + $head[$h][2] = 'clicktodial'; + $h++; + } + + // Notifications + if ($user->societe_id == 0 && ! empty($conf->notification->enabled)) + { + $nbNote = 0; + $sql = "SELECT COUNT(n.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n"; + $sql.= " WHERE fk_user = ".$object->id; + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + $nbNote=$obj->nb; + $i++; + } + } + else { + dol_print_error($db); + } + + $head[$h][0] = DOL_URL_ROOT.'/user/notify/card.php?id='.$object->id; + $head[$h][1] = $langs->trans("Notifications"); + if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>'; + $head[$h][2] = 'notify'; + $h++; + } + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab + // $this->tabs = array('entity:-tabname); to remove a tab + complete_head_from_modules($conf,$langs,$object,$head,$h,'user'); + + if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) + || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) + { // Bank - $head[$h][0] = DOL_URL_ROOT.'/user/bank.php?id='.$object->id; - $head[$h][1] = $langs->trans("HRAndBank"); - $head[$h][2] = 'bank'; - $h++; + $head[$h][0] = DOL_URL_ROOT.'/user/bank.php?id='.$object->id; + $head[$h][1] = $langs->trans("HRAndBank"); + $head[$h][2] = 'bank'; + $h++; } - // Such info on users is visible only by internal user - if (empty($user->societe_id)) - { + // Such info on users is visible only by internal user + if (empty($user->societe_id)) + { // Notes - $nbNote = 0; - if(!empty($object->note)) $nbNote++; - $head[$h][0] = DOL_URL_ROOT.'/user/note.php?id='.$object->id; - $head[$h][1] = $langs->trans("Note"); + $nbNote = 0; + if(!empty($object->note)) $nbNote++; + $head[$h][0] = DOL_URL_ROOT.'/user/note.php?id='.$object->id; + $head[$h][1] = $langs->trans("Note"); if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>'; - $head[$h][2] = 'note'; - $h++; - - // Attached files - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; - $upload_dir = $conf->user->dir_output . "/" . $object->id; - $nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview.*\.png)$')); - $nbLinks=Link::count($db, $object->element, $object->id); - $head[$h][0] = DOL_URL_ROOT.'/user/document.php?userid='.$object->id; - $head[$h][1] = $langs->trans("Documents"); - if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' <span class="badge">'.($nbFiles+$nbLinks).'</span>'; - $head[$h][2] = 'document'; - $h++; - - $head[$h][0] = DOL_URL_ROOT.'/user/info.php?id='.$object->id; - $head[$h][1] = $langs->trans("Info"); - $head[$h][2] = 'info'; - $h++; - } - - complete_head_from_modules($conf,$langs,$object,$head,$h,'user','remove'); + $head[$h][2] = 'note'; + $h++; + + // Attached files + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->user->dir_output . "/" . $object->id; + $nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview.*\.png)$')); + $nbLinks=Link::count($db, $object->element, $object->id); + $head[$h][0] = DOL_URL_ROOT.'/user/document.php?userid='.$object->id; + $head[$h][1] = $langs->trans("Documents"); + if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' <span class="badge">'.($nbFiles+$nbLinks).'</span>'; + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = DOL_URL_ROOT.'/user/info.php?id='.$object->id; + $head[$h][1] = $langs->trans("Info"); + $head[$h][2] = 'info'; + $h++; + } + + complete_head_from_modules($conf,$langs,$object,$head,$h,'user','remove'); return $head; } @@ -206,10 +206,10 @@ function group_prepare_head($object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/user/group/card.php?id='.$object->id; - $head[$h][1] = $langs->trans("GroupCard"); - $head[$h][2] = 'group'; - $h++; + $head[$h][0] = DOL_URL_ROOT.'/user/group/card.php?id='.$object->id; + $head[$h][1] = $langs->trans("GroupCard"); + $head[$h][2] = 'group'; + $h++; if ((! empty($conf->ldap->enabled) && ! empty($conf->global->LDAP_SYNCHRO_ACTIVE)) && (empty($conf->global->MAIN_DISABLE_LDAP_TAB) || ! empty($user->admin))) @@ -229,15 +229,15 @@ function group_prepare_head($object) $h++; } - // Show more tabs from modules - // Entries must be declared in modules descriptor with line - // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab - // $this->tabs = array('entity:-tabname); to remove a tab - complete_head_from_modules($conf,$langs,$object,$head,$h,'group'); + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab + // $this->tabs = array('entity:-tabname); to remove a tab + complete_head_from_modules($conf,$langs,$object,$head,$h,'group'); - complete_head_from_modules($conf,$langs,$object,$head,$h,'group','remove'); + complete_head_from_modules($conf,$langs,$object,$head,$h,'group','remove'); - return $head; + return $head; } /** @@ -252,25 +252,25 @@ function user_admin_prepare_head() $langs->load("users"); $h=0; - $head[$h][0] = DOL_URL_ROOT.'/admin/user.php'; - $head[$h][1] = $langs->trans("Parameters"); - $head[$h][2] = 'card'; - $h++; + $head[$h][0] = DOL_URL_ROOT.'/admin/user.php'; + $head[$h][1] = $langs->trans("Parameters"); + $head[$h][2] = 'card'; + $h++; - $head[$h][0] = DOL_URL_ROOT.'/admin/usergroup.php'; - $head[$h][1] = $langs->trans("Group"); - $head[$h][2] = 'usergroupcard'; - $h++; + $head[$h][0] = DOL_URL_ROOT.'/admin/usergroup.php'; + $head[$h][1] = $langs->trans("Group"); + $head[$h][2] = 'usergroupcard'; + $h++; - $head[$h][0] = DOL_URL_ROOT.'/user/admin/user_extrafields.php'; - $head[$h][1] = $langs->trans("ExtraFields"); - $head[$h][2] = 'attributes'; - $h++; + $head[$h][0] = DOL_URL_ROOT.'/user/admin/user_extrafields.php'; + $head[$h][1] = $langs->trans("ExtraFields"); + $head[$h][2] = 'attributes'; + $h++; $head[$h][0] = DOL_URL_ROOT.'/user/admin/group_extrafields.php'; - $head[$h][1] = $langs->trans("ExtraFields")." ".$langs->trans("Groups"); - $head[$h][2] = 'attributes_group'; - $h++; + $head[$h][1] = $langs->trans("ExtraFields")." ".$langs->trans("Groups"); + $head[$h][2] = 'attributes_group'; + $h++; // Show more tabs from modules // Entries must be declared in modules descriptor with line @@ -293,134 +293,134 @@ function user_admin_prepare_head() */ function show_theme($fuser,$edit=0,$foruserprofile=false) { - global $conf,$langs,$db,$form; - global $bc; + global $conf,$langs,$db,$form; + global $bc; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; - $formother = new FormOther($db); - - $dirthemes=array('/theme'); - if (! empty($conf->modules_parts['theme'])) // Using this feature slow down application - { - foreach($conf->modules_parts['theme'] as $reldir) - { - $dirthemes=array_merge($dirthemes,(array) ($reldir.'theme')); - } - } - $dirthemes=array_unique($dirthemes); + $formother = new FormOther($db); + + $dirthemes=array('/theme'); + if (! empty($conf->modules_parts['theme'])) // Using this feature slow down application + { + foreach($conf->modules_parts['theme'] as $reldir) + { + $dirthemes=array_merge($dirthemes,(array) ($reldir.'theme')); + } + } + $dirthemes=array_unique($dirthemes); // Now dir_themes=array('/themes') or dir_themes=array('/theme','/mymodule/theme') - $selected_theme=''; - if (empty($foruserprofile)) $selected_theme=$conf->global->MAIN_THEME; - else $selected_theme=((is_object($fuser) && ! empty($fuser->conf->MAIN_THEME))?$fuser->conf->MAIN_THEME:''); + $selected_theme=''; + if (empty($foruserprofile)) $selected_theme=$conf->global->MAIN_THEME; + else $selected_theme=((is_object($fuser) && ! empty($fuser->conf->MAIN_THEME))?$fuser->conf->MAIN_THEME:''); $hoverdisabled=''; - if (empty($foruserprofile)) $hoverdisabled=(isset($conf->global->THEME_ELDY_USE_HOVER) && $conf->global->THEME_ELDY_USE_HOVER == '0'); - else $hoverdisabled=(is_object($fuser)?(empty($fuser->conf->THEME_ELDY_USE_HOVER) || $fuser->conf->THEME_ELDY_USE_HOVER == '0'):''); - - $colspan=2; - if ($foruserprofile) $colspan=4; - - $thumbsbyrow=6; - print '<table class="noborder" width="100%">'; - - // Title - if ($foruserprofile) - { - print '<tr class="liste_titre"><th class="titlefield">'.$langs->trans("Parameter").'</th><th>'.$langs->trans("DefaultValue").'</th>'; - print '<th colspan="2"> </th>'; - print '</tr>'; - - print '<tr>'; - print '<td>'.$langs->trans("DefaultSkin").'</td>'; - print '<td>'.$conf->global->MAIN_THEME.'</td>'; - print '<td align="left" class="nowrap" width="20%"><input id="check_MAIN_THEME" name="check_MAIN_THEME"'.($edit?'':' disabled').' type="checkbox" '.($selected_theme?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>'; - print '<td> </td>'; - print '</tr>'; - } - else - { - print '<tr class="liste_titre"><th class="titlefield">'.$langs->trans("DefaultSkin").'</th>'; - print '<th align="right">'; - $url='https://www.dolistore.com/lang-en/4-skins'; - if (preg_match('/fr/i',$langs->defaultlang)) $url='https://www.dolistore.com/fr/4-themes'; - //if (preg_match('/es/i',$langs->defaultlang)) $url='http://www.dolistore.com/lang-es/4-themes'; - print '<a href="'.$url.'" target="_blank">'; - print $langs->trans('DownloadMoreSkins'); - print '</a>'; - print '</th></tr>'; - - print '<tr>'; - print '<td>'.$langs->trans("ThemeDir").'</td>'; - print '<td>'; - foreach($dirthemes as $dirtheme) - { - echo '"'.$dirtheme.'" '; - } - print '</td>'; - print '</tr>'; - } - - print '<tr><td colspan="'.$colspan.'">'; - - print '<table class="nobordernopadding" width="100%"><tr><td><div align="center">'; - - $i=0; - foreach($dirthemes as $dir) - { - //print $dirroot.$dir;exit; - $dirtheme=dol_buildpath($dir,0); // This include loop on $conf->file->dol_document_root - $urltheme=dol_buildpath($dir,1); - - if (is_dir($dirtheme)) - { - $handle=opendir($dirtheme); - if (is_resource($handle)) - { - while (($subdir = readdir($handle))!==false) - { - if (is_dir($dirtheme."/".$subdir) && substr($subdir, 0, 1) <> '.' - && substr($subdir, 0, 3) <> 'CVS' && ! preg_match('/common|phones/i',$subdir)) - { - // Disable not stable themes (dir ends with _exp or _dev) - if ($conf->global->MAIN_FEATURES_LEVEL < 2 && preg_match('/_dev$/i',$subdir)) continue; - if ($conf->global->MAIN_FEATURES_LEVEL < 1 && preg_match('/_exp$/i',$subdir)) continue; - - print '<div class="inline-block" style="margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;">'; - $file=$dirtheme."/".$subdir."/thumb.png"; - $url=$urltheme."/".$subdir."/thumb.png"; - if (! file_exists($file)) $url=DOL_URL_ROOT.'/public/theme/common/nophoto.png'; - print '<a href="'.$_SERVER["PHP_SELF"].($edit?'?action=edit&theme=':'?theme=').$subdir.(GETPOST('optioncss','alpha',1)?'&optioncss='.GETPOST('optioncss','alpha',1):'').($fuser?'&id='.$fuser->id:'').'" style="font-weight: normal;" alt="'.$langs->trans("Preview").'">'; - if ($subdir == $conf->global->MAIN_THEME) $title=$langs->trans("ThemeCurrentlyActive"); - else $title=$langs->trans("ShowPreview"); - print '<img src="'.$url.'" border="0" width="80" height="60" alt="'.$title.'" title="'.$title.'" style="margin-bottom: 5px;">'; - print '</a><br>'; - if ($subdir == $selected_theme) - { - print '<input '.($edit?'':'disabled').' type="radio" class="themethumbs" style="border: 0px;" checked name="main_theme" value="'.$subdir.'"> <b>'.$subdir.'</b>'; - } - else - { - print '<input '.($edit?'':'disabled').' type="radio" class="themethumbs" style="border: 0px;" name="main_theme" value="'.$subdir.'"> '.$subdir; - } + if (empty($foruserprofile)) $hoverdisabled=(isset($conf->global->THEME_ELDY_USE_HOVER) && $conf->global->THEME_ELDY_USE_HOVER == '0'); + else $hoverdisabled=(is_object($fuser)?(empty($fuser->conf->THEME_ELDY_USE_HOVER) || $fuser->conf->THEME_ELDY_USE_HOVER == '0'):''); + + $colspan=2; + if ($foruserprofile) $colspan=4; + + $thumbsbyrow=6; + print '<table class="noborder" width="100%">'; + + // Title + if ($foruserprofile) + { + print '<tr class="liste_titre"><th class="titlefield">'.$langs->trans("Parameter").'</th><th>'.$langs->trans("DefaultValue").'</th>'; + print '<th colspan="2"> </th>'; + print '</tr>'; + + print '<tr>'; + print '<td>'.$langs->trans("DefaultSkin").'</td>'; + print '<td>'.$conf->global->MAIN_THEME.'</td>'; + print '<td align="left" class="nowrap" width="20%"><input id="check_MAIN_THEME" name="check_MAIN_THEME"'.($edit?'':' disabled').' type="checkbox" '.($selected_theme?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>'; + print '<td> </td>'; + print '</tr>'; + } + else + { + print '<tr class="liste_titre"><th class="titlefield">'.$langs->trans("DefaultSkin").'</th>'; + print '<th align="right">'; + $url='https://www.dolistore.com/lang-en/4-skins'; + if (preg_match('/fr/i',$langs->defaultlang)) $url='https://www.dolistore.com/fr/4-themes'; + //if (preg_match('/es/i',$langs->defaultlang)) $url='http://www.dolistore.com/lang-es/4-themes'; + print '<a href="'.$url.'" target="_blank">'; + print $langs->trans('DownloadMoreSkins'); + print '</a>'; + print '</th></tr>'; + + print '<tr>'; + print '<td>'.$langs->trans("ThemeDir").'</td>'; + print '<td>'; + foreach($dirthemes as $dirtheme) + { + echo '"'.$dirtheme.'" '; + } + print '</td>'; + print '</tr>'; + } + + print '<tr><td colspan="'.$colspan.'">'; + + print '<table class="nobordernopadding" width="100%"><tr><td><div align="center">'; + + $i=0; + foreach($dirthemes as $dir) + { + //print $dirroot.$dir;exit; + $dirtheme=dol_buildpath($dir,0); // This include loop on $conf->file->dol_document_root + $urltheme=dol_buildpath($dir,1); + + if (is_dir($dirtheme)) + { + $handle=opendir($dirtheme); + if (is_resource($handle)) + { + while (($subdir = readdir($handle))!==false) + { + if (is_dir($dirtheme."/".$subdir) && substr($subdir, 0, 1) <> '.' + && substr($subdir, 0, 3) <> 'CVS' && ! preg_match('/common|phones/i',$subdir)) + { + // Disable not stable themes (dir ends with _exp or _dev) + if ($conf->global->MAIN_FEATURES_LEVEL < 2 && preg_match('/_dev$/i',$subdir)) continue; + if ($conf->global->MAIN_FEATURES_LEVEL < 1 && preg_match('/_exp$/i',$subdir)) continue; + + print '<div class="inline-block" style="margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;">'; + $file=$dirtheme."/".$subdir."/thumb.png"; + $url=$urltheme."/".$subdir."/thumb.png"; + if (! file_exists($file)) $url=DOL_URL_ROOT.'/public/theme/common/nophoto.png'; + print '<a href="'.$_SERVER["PHP_SELF"].($edit?'?action=edit&theme=':'?theme=').$subdir.(GETPOST('optioncss','alpha',1)?'&optioncss='.GETPOST('optioncss','alpha',1):'').($fuser?'&id='.$fuser->id:'').'" style="font-weight: normal;" alt="'.$langs->trans("Preview").'">'; + if ($subdir == $conf->global->MAIN_THEME) $title=$langs->trans("ThemeCurrentlyActive"); + else $title=$langs->trans("ShowPreview"); + print '<img src="'.$url.'" border="0" width="80" height="60" alt="'.$title.'" title="'.$title.'" style="margin-bottom: 5px;">'; + print '</a><br>'; + if ($subdir == $selected_theme) + { + print '<input '.($edit?'':'disabled').' type="radio" class="themethumbs" style="border: 0px;" checked name="main_theme" value="'.$subdir.'"> <b>'.$subdir.'</b>'; + } + else + { + print '<input '.($edit?'':'disabled').' type="radio" class="themethumbs" style="border: 0px;" name="main_theme" value="'.$subdir.'"> '.$subdir; + } print '</div>'; - $i++; - } - } - } - } - } + $i++; + } + } + } + } + } - print '</div></td></tr></table>'; + print '</div></td></tr></table>'; - print '</td></tr>'; + print '</td></tr>'; - // TopMenuDisableImages - if ($foruserprofile) - { - /* + // TopMenuDisableImages + if ($foruserprofile) + { + /* print '<tr class="oddeven">'; print '<td>'.$langs->trans("TopMenuDisableImages").'</td>'; print '<td>'.($conf->global->THEME_TOPMENU_DISABLE_IMAGE?$conf->global->THEME_TOPMENU_DISABLE_IMAGE:$langs->trans("Default")).'</td>'; @@ -440,30 +440,30 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } if ($edit) print '<br>('.$langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis").')'; print '</td>';*/ - } - else - { - $default=$langs->trans('No'); - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("TopMenuDisableImages").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - if ($edit) - { - print $form->selectyesno('THEME_TOPMENU_DISABLE_IMAGE', $conf->global->THEME_TOPMENU_DISABLE_IMAGE, 1); - } - else - { - print yn($conf->global->THEME_TOPMENU_DISABLE_IMAGE); - } - print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; - } + } + else + { + $default=$langs->trans('No'); + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("TopMenuDisableImages").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + if ($edit) + { + print $form->selectyesno('THEME_TOPMENU_DISABLE_IMAGE', $conf->global->THEME_TOPMENU_DISABLE_IMAGE, 1); + } + else + { + print yn($conf->global->THEME_TOPMENU_DISABLE_IMAGE); + } + print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; + } // Background color THEME_ELDY_BACKBODY - if ($foruserprofile) + if ($foruserprofile) { - /* + /* print '<tr class="oddeven">'; print '<td>'.$langs->trans("TopMenuBackgroundColor").'</td>'; print '<td>'.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'</td>'; @@ -486,29 +486,29 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("BackgroundColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - //var_dump($conf->global->THEME_ELDY_BACKBODY); - if ($edit) - { + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("BackgroundColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + //var_dump($conf->global->THEME_ELDY_BACKBODY); + if ($edit) + { print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_BACKBODY,array()),''),'THEME_ELDY_BACKBODY','formcolor',1).' '; - } + } else { $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_BACKBODY,array()),''); if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; else print $langs->trans("Default"); } - print ' ('.$langs->trans("Default").': <strong>ffffff</strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; + print ' ('.$langs->trans("Default").': <strong>ffffff</strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; } // TopMenuBackgroundColor - if ($foruserprofile) + if ($foruserprofile) { - /* + /* print '<tr class="oddeven">'; print '<td>'.$langs->trans("TopMenuBackgroundColor").'</td>'; print '<td>'.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'</td>'; @@ -531,25 +531,25 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $default='5a6482'; - if ($conf->theme == 'md') $default='5a3278'; + $default='5a6482'; + if ($conf->theme == 'md') $default='5a3278'; - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("TopMenuBackgroundColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - if ($edit) - { + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("TopMenuBackgroundColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + if ($edit) + { print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TOPMENU_BACK1,array()),''),'THEME_ELDY_TOPMENU_BACK1','formcolor',1).' '; - } + } else { $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TOPMENU_BACK1,array()),''); if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; else print $langs->trans("Default"); } - print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; + print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; } // LeftMenuBackgroundColor @@ -607,22 +607,22 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("BackgroundTableTitleColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - if ($edit) - { + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("BackgroundTableTitleColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + if ($edit) + { print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_BACKTITLE1,array()),''),'THEME_ELDY_BACKTITLE1','formcolor',1).' '; - } + } else { print $formother->showColor($conf->global->THEME_ELDY_BACKTITLE1, $langs->trans("Default")); } - print ' ('.$langs->trans("Default").': <strong>f0f0f0</strong>) '; // $colorbacktitle1 in CSS - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; + print ' ('.$langs->trans("Default").': <strong>f0f0f0</strong>) '; // $colorbacktitle1 in CSS + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; - print '</tr>'; + print '</tr>'; } // BackgroundTableLineOddColor @@ -632,25 +632,25 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $default='ffffff'; - if ($conf->theme == 'md') $default='ffffff'; + $default='ffffff'; + if ($conf->theme == 'md') $default='ffffff'; - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("BackgroundTableLineOddColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - if ($edit) - { - print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEIMPAIR1,array()),''),'THEME_ELDY_LINEIMPAIR1','formcolor',1).' '; - } - else - { - $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEIMPAIR1,array()),''); - if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; - else print $langs->trans("Default"); - } - print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("BackgroundTableLineOddColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + if ($edit) + { + print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEIMPAIR1,array()),''),'THEME_ELDY_LINEIMPAIR1','formcolor',1).' '; + } + else + { + $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEIMPAIR1,array()),''); + if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; + else print $langs->trans("Default"); + } + print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; } // BackgroundTableLineEvenColor @@ -660,25 +660,25 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $default='f8f8f8'; - if ($conf->theme == 'md') $default='f8f8f8'; + $default='f8f8f8'; + if ($conf->theme == 'md') $default='f8f8f8'; - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("BackgroundTableLineEvenColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - if ($edit) - { - print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEPAIR1,array()),''),'THEME_ELDY_LINEPAIR1','formcolor',1).' '; - } - else - { - $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEPAIR1,array()),''); - if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; - else print $langs->trans("Default"); - } - print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("BackgroundTableLineEvenColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + if ($edit) + { + print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEPAIR1,array()),''),'THEME_ELDY_LINEPAIR1','formcolor',1).' '; + } + else + { + $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_LINEPAIR1,array()),''); + if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; + else print $langs->trans("Default"); + } + print ' ('.$langs->trans("Default").': <strong>'.$default.'</strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; } // TextTitleColor @@ -689,29 +689,29 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("TextTitleColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - if ($edit) - { - print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTTITLENOTAB,array()),''),'THEME_ELDY_TEXTTITLENOTAB','formcolor',1).' '; - } - else - { - print $formother->showColor($conf->global->THEME_ELDY_TEXTTITLENOTAB, $langs->trans("Default")); - } - print ' ('.$langs->trans("Default").': <strong><span style="color: #3c3c14">3c3c14</span></strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("TextTitleColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + if ($edit) + { + print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTTITLENOTAB,array()),''),'THEME_ELDY_TEXTTITLENOTAB','formcolor',1).' '; + } + else + { + print $formother->showColor($conf->global->THEME_ELDY_TEXTTITLENOTAB, $langs->trans("Default")); + } + print ' ('.$langs->trans("Default").': <strong><span style="color: #3c3c14">3c3c14</span></strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; + print '</td>'; - print '</tr>'; + print '</tr>'; } // Text LinkColor if ($foruserprofile) { - /* + /* print '<tr class="oddeven">'; print '<td>'.$langs->trans("TopMenuBackgroundColor").'</td>'; print '<td>'.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TEXTLINK:$langs->trans("Default")).'</td>'; @@ -734,33 +734,33 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("LinkColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - if ($edit) - { - print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTLINK,array()),''),'THEME_ELDY_TEXTLINK','formcolor',1).' '; - } - else - { - $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTLINK,array()),''); - if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; - else - { - //print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$defaultcolor.'" value="'.$langs->trans("Default").'">'; - //print '<span style="color: #000078">'.$langs->trans("Default").'</span>'; - print $langs->trans("Default"); - } - } - print ' ('.$langs->trans("Default").': <strong><span style="color: #000078">000078</span></strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("LinkColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + if ($edit) + { + print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTLINK,array()),''),'THEME_ELDY_TEXTLINK','formcolor',1).' '; + } + else + { + $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTLINK,array()),''); + if ($color) print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; + else + { + //print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$defaultcolor.'" value="'.$langs->trans("Default").'">'; + //print '<span style="color: #000078">'.$langs->trans("Default").'</span>'; + print $langs->trans("Default"); + } + } + print ' ('.$langs->trans("Default").': <strong><span style="color: #000078">000078</span></strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; } // Use Hover if ($foruserprofile) { - /* Must first change option to choose color of highlight instead of yes or no. + /* Must first change option to choose color of highlight instead of yes or no. print '<tr class="oddeven">'; print '<td>'.$langs->trans("HighlightLinesOnMouseHover").'</td>'; print '<td><input '.$bc[$var].' name="check_THEME_ELDY_USE_HOVER" disabled="disabled" type="checkbox" '.($conf->global->THEME_ELDY_USE_HOVER?" checked":"").'></td>'; @@ -773,33 +773,33 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - print '<tr class="oddeven">'; - print '<td>'.$langs->trans("HighlightLinesColor").'</td>'; - print '<td colspan="'.($colspan-1).'">'; - //print '<input '.$bc[$var].' name="check_THEME_ELDY_USE_HOVER"'.($edit?'':' disabled').' type="checkbox" '.($hoverdisabled?"":" checked").'>'; - //print ' ('.$langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis").')'; - if ($edit) - { - if ($conf->global->THEME_ELDY_USE_HOVER == '1') $color='edf4fb'; - else $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_USE_HOVER,array()),''); - print $formother->selectColor($color,'THEME_ELDY_USE_HOVER','formcolor',1).' '; - } - else - { - if ($conf->global->THEME_ELDY_USE_HOVER == '1') $color='edf4fb'; - else $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_USE_HOVER,array()),''); - if ($color) - { - if ($color != 'edf4fb') print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; - else print $langs->trans("Default"); - } - else print $langs->trans("None"); - } - print ' ('.$langs->trans("Default").': <strong>edf4fb</strong>) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - print '</td>'; - print '</tr>'; + print '<tr class="oddeven">'; + print '<td>'.$langs->trans("HighlightLinesColor").'</td>'; + print '<td colspan="'.($colspan-1).'">'; + //print '<input '.$bc[$var].' name="check_THEME_ELDY_USE_HOVER"'.($edit?'':' disabled').' type="checkbox" '.($hoverdisabled?"":" checked").'>'; + //print ' ('.$langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis").')'; + if ($edit) + { + if ($conf->global->THEME_ELDY_USE_HOVER == '1') $color='edf4fb'; + else $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_USE_HOVER,array()),''); + print $formother->selectColor($color,'THEME_ELDY_USE_HOVER','formcolor',1).' '; + } + else + { + if ($conf->global->THEME_ELDY_USE_HOVER == '1') $color='edf4fb'; + else $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_USE_HOVER,array()),''); + if ($color) + { + if ($color != 'edf4fb') print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">'; + else print $langs->trans("Default"); + } + else print $langs->trans("None"); + } + print ' ('.$langs->trans("Default").': <strong>edf4fb</strong>) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + print '</td>'; + print '</tr>'; } - print '</table>'; + print '</table>'; } diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 121328114648d3bc005616fbfbe8803a8d8329f9..0beffce17a3e326987b9f8af7469d23027faa80b 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -31,59 +31,59 @@ */ function dolWebsiteOutput($content) { - global $db, $langs, $conf, $user; - global $dolibarr_main_url_root, $dolibarr_main_data_root; + global $db, $langs, $conf, $user; + global $dolibarr_main_url_root, $dolibarr_main_data_root; - dol_syslog("dolWebsiteOutput start (mode=".(defined('USEDOLIBARRSERVER')?'USEDOLIBARRSERVER':'').')'); + dol_syslog("dolWebsiteOutput start (mode=".(defined('USEDOLIBARRSERVER')?'USEDOLIBARRSERVER':'').')'); - // Define $urlwithroot - $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); - $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file - //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + // Define $urlwithroot + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - // Note: This seems never called when page is output inside the website editor (search 'REPLACEMENT OF LINKS When page called by website editor') + // Note: This seems never called when page is output inside the website editor (search 'REPLACEMENT OF LINKS When page called by website editor') - if (! defined('USEDOLIBARRSERVER')) // REPLACEMENT OF LINKS When page called from virtual host - { - $symlinktomediaexists=1; + if (! defined('USEDOLIBARRSERVER')) // REPLACEMENT OF LINKS When page called from virtual host + { + $symlinktomediaexists=1; // Make a change into HTML code to allow to include images from medias directory correct with direct link for virtual server // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&entity=1&file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" /> // become // <img alt="" src="'.$urlwithroot.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" /> - $nbrep=0; - if (! $symlinktomediaexists) - { - $content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^\/]*\/?>)/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep); - $content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep); - } - else - { - $content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^\/]*\/?>)/', '\1medias/\4\5', $content, -1, $nbrep); - $content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/', '\1medias/\4\5', $content, -1, $nbrep); - } - } - else // REPLACEMENT OF LINKS When page called from dolibarr server - { - global $website; - - // Replace relative link / with dolibarr URL: ...href="/"... - $content=preg_replace('/(href=")\/\"/', '\1'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'"', $content, -1, $nbrep); - // Replace relative link /xxx.php with dolibarr URL: ...href="....php" - $content=preg_replace('/(href=")\/?([^\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep); - - // Fix relative link /document.php with correct URL after the DOL_URL_ROOT: ...href="/document.php?modulepart=" - $content=preg_replace('/(href=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3"', $content, -1, $nbrep); - // Fix relative link /viewimage.php with correct URL after the DOL_URL_ROOT: ...href="/viewimage.php?modulepart=" - $content=preg_replace('/(href=")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3"', $content, -1, $nbrep); - - // Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/ - $content=preg_replace('/url\((["\']?)medias\//', 'url(\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); - } - - dol_syslog("dolWebsiteOutput end"); - - print $content; + $nbrep=0; + if (! $symlinktomediaexists) + { + $content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^\/]*\/?>)/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep); + $content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep); + } + else + { + $content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^\/]*\/?>)/', '\1medias/\4\5', $content, -1, $nbrep); + $content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/', '\1medias/\4\5', $content, -1, $nbrep); + } + } + else // REPLACEMENT OF LINKS When page called from dolibarr server + { + global $website; + + // Replace relative link / with dolibarr URL: ...href="/"... + $content=preg_replace('/(href=")\/\"/', '\1'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'"', $content, -1, $nbrep); + // Replace relative link /xxx.php with dolibarr URL: ...href="....php" + $content=preg_replace('/(href=")\/?([^\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep); + + // Fix relative link /document.php with correct URL after the DOL_URL_ROOT: ...href="/document.php?modulepart=" + $content=preg_replace('/(href=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3"', $content, -1, $nbrep); + // Fix relative link /viewimage.php with correct URL after the DOL_URL_ROOT: ...href="/viewimage.php?modulepart=" + $content=preg_replace('/(href=")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3"', $content, -1, $nbrep); + + // Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/ + $content=preg_replace('/url\((["\']?)medias\//', 'url(\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); + } + + dol_syslog("dolWebsiteOutput end"); + + print $content; } diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 247dc4ac6aef4f75c232870a901663e52b7397a6..d468c882b2de3cff289875ff024ccde5abf9a01d 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -98,12 +98,12 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) $resultFetchLdapUser=0; // Define $userSearchFilter - $userSearchFilter = ""; - if (empty($dolibarr_main_auth_ldap_filter)) { - $userSearchFilter = "(" . $ldapuserattr . "=" . $usertotest . ")"; - } else { - $userSearchFilter = str_replace('%1%', $usertotest, $dolibarr_main_auth_ldap_filter); - } + $userSearchFilter = ""; + if (empty($dolibarr_main_auth_ldap_filter)) { + $userSearchFilter = "(" . $ldapuserattr . "=" . $usertotest . ")"; + } else { + $userSearchFilter = str_replace('%1%', $usertotest, $dolibarr_main_auth_ldap_filter); + } // If admin login provided // Code to get user in LDAP from an admin connection (may differ from user connection, done later) @@ -127,7 +127,7 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) } else { - if ($ldapdebug) print "DEBUG: ".$ldap->error."<br>\n"; + if ($ldapdebug) print "DEBUG: ".$ldap->error."<br>\n"; } $ldap->close(); } @@ -135,15 +135,15 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) // Forge LDAP user and password to test with them // If LDAP need a dn with login like "uid=jbloggs,ou=People,dc=foo,dc=com", default dn may work even if previous code with // admin login no exectued. - $ldap->searchUser=$ldapuserattr."=".$usertotest.",".$ldapdn; // Default dn (will work if LDAP accept a dn with login value inside) + $ldap->searchUser=$ldapuserattr."=".$usertotest.",".$ldapdn; // Default dn (will work if LDAP accept a dn with login value inside) // But if LDAP need a dn with name like "cn=Jhon Bloggs,ou=People,dc=foo,dc=com", previous part must have been executed to have // dn detected into ldapUserDN. if ($resultFetchLdapUser && !empty($ldap->ldapUserDN)) $ldap->searchUser = $ldap->ldapUserDN; - $ldap->searchPassword=$passwordtotest; + $ldap->searchPassword=$passwordtotest; // Test with this->seachUser and this->searchPassword - //print $resultFetchLdapUser."-".$ldap->ldapUserDN."-".$ldap->searchUser.'-'.$ldap->searchPassword;exit; - $result=$ldap->connect_bind(); + //print $resultFetchLdapUser."-".$ldap->ldapUserDN."-".$ldap->searchUser.'-'.$ldap->searchPassword;exit; + $result=$ldap->connect_bind(); if ($result > 0) { if ($result == 2) // Connection is ok for user/pass into LDAP @@ -214,7 +214,7 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) } else { - /* Login failed. Return false, together with the error code and text from + /* Login failed. Return false, together with the error code and text from ** the LDAP server. The common error codes and reasons are listed below : ** (for iPlanet, other servers may differ) ** 19 - Account locked out (too many invalid login attempts) @@ -222,13 +222,13 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) ** 49 - Wrong password ** 53 - Account inactive (manually locked out by administrator) */ - dol_syslog("functions_ldap::check_user_password_ldap Authentification ko failed to connect to LDAP for '".$usertotest."'"); - if (is_resource($ldap->connection)) // If connection ok but bind ko - { - $ldap->ldapErrorCode = ldap_errno($ldap->connection); - $ldap->ldapErrorText = ldap_error($ldap->connection); - dol_syslog("functions_ldap::check_user_password_ldap ".$ldap->ldapErrorCode." ".$ldap->ldapErrorText); - } + dol_syslog("functions_ldap::check_user_password_ldap Authentification ko failed to connect to LDAP for '".$usertotest."'"); + if (is_resource($ldap->connection)) // If connection ok but bind ko + { + $ldap->ldapErrorCode = ldap_errno($ldap->connection); + $ldap->ldapErrorText = ldap_error($ldap->connection); + dol_syslog("functions_ldap::check_user_password_ldap ".$ldap->ldapErrorCode." ".$ldap->ldapErrorText); + } sleep(2); // Anti brut force protection $langs->load('main'); $langs->load('other'); diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 11f8b70f26baebcb386a31cb95d3d8de76904670..c42fabcc9370cd9aeafe00bebc41132000df716f 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -34,245 +34,245 @@ */ class DolibarrModules // Can not be abstract, because we need to instantiate it into unActivateModule to be able to disable a module whose files were removed. { - /** - * @var DoliDb Database handler - */ - public $db; - - /** - * @var int Module unique ID - * @see https://wiki.dolibarr.org/index.php/List_of_modules_id - */ - public $numero; - - /** - * @var string Publisher name - * @since 4.0.0 - */ - public $editor_name; - - /** - * @var string URL of module at publisher site - * @since 4.0.0 - */ - public $editor_url; - - /** - * @var string Family - * @see familyinfo - * - * Native values: 'crm', 'financial', 'hr', 'projects', 'products', 'ecm', 'technic', 'other'. - * Use familyinfo to declare a custom value. - */ - public $family; - - /** - * @var array Custom family informations - * @see family - * - * e.g.: - * array( - * 'myownfamily' => array( - * 'position' => '001', - * 'label' => $langs->trans("MyOwnFamily") - * ) - * ); - * - */ - public $familyinfo; - - /** - * @var int Module position - * @since 3.9.0 - */ - public $module_position=500; - - /** - * @var string Module name - * - * Only used if Module[ID]Name translation string is not found. - * - * You can use the following code to automatically derive it from your module's class name: - * preg_replace('/^mod/i', '', get_class($this)) - */ - public $name; - - /** - * @var string[] Paths to create when module is activated - * - * e.g.: array('/mymodule/temp') - */ - public $dirs = array(); - - /** - * @var array Module boxes - */ - public $boxes = array(); - - /** - * @var array Module constants - */ - public $const = array(); - - /** - * @var array Module cron jobs entries - */ - public $cronjobs = array(); - - /** - * @var array Module access rights - */ - public $rights; - - /** - * @var string Module access rights family - */ - public $rights_class; - - /** - * @var array Module menu entries - */ - public $menu = array(); - - /** - * @var array Module parts - * array( - * // Set this to 1 if module has its own trigger directory (/mymodule/core/triggers) - * 'triggers' => 0, - * // Set this to 1 if module has its own login method directory (/mymodule/core/login) - * 'login' => 0, - * // Set this to 1 if module has its own substitution function file (/mymodule/core/substitutions) - * 'substitutions' => 0, - * // Set this to 1 if module has its own menus handler directory (/mymodule/core/menus) - * 'menus' => 0, - * // Set this to 1 if module has its own theme directory (/mymodule/theme) - * 'theme' => 0, - * // Set this to 1 if module overwrite template dir (/mymodule/core/tpl) - * 'tpl' => 0, - * // Set this to 1 if module has its own barcode directory (/mymodule/core/modules/barcode) - * 'barcode' => 0, - * // Set this to 1 if module has its own models directory (/mymodule/core/modules/xxx) - * 'models' => 0, - * // Set this to relative path of css file if module has its own css file - * 'css' => '/mymodule/css/mymodule.css.php', - * // Set this to relative path of js file if module must load a js on all pages - * 'js' => '/mymodule/js/mymodule.js', - * // Set here all hooks context managed by module - * 'hooks' => array('hookcontext1','hookcontext2'), - * // Set here all workflow context managed by module - * 'workflow' => array( - * 'WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2' = >array( - * 'enabled' => '! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', - * 'picto'=>'yourpicto@mymodule' - * ) - * ) - * ) - */ - public $module_parts = array(); - - /** - * @var string Module documents ? - * @deprecated Seems unused anywhere - */ - public $docs; - - /** - * @var string ? - * @deprecated Seems unused anywhere - */ - public $dbversion = "-"; - - /** - * @var string Error message - */ - public $error; - - /** - * @var string Module version - * @see http://semver.org - * - * The following keywords can also be used: - * 'development' - * 'experimental' - * 'dolibarr': only for core modules that share its version - * 'dolibarr_deprecated': only for deprecated core modules - * - */ - public $version; - - /** - * @var string Module description (short text) - * - * Only used if Module[ID]Desc translation string is not found. - */ - public $description; - - /** - * @var string Module description (long text) - * @since 4.0.0 - * - * HTML content supported. - */ - public $descriptionlong; - - - // For exports - - /** - * @var string Module export code - */ - public $export_code; - - /** - * @var string Module export label - */ - public $export_label; - - public $export_permission; - public $export_fields_array; - public $export_TypeFields_array; - public $export_entities_array; - public $export_special_array; // special or computed field - public $export_dependencies_array; - public $export_sql_start; - public $export_sql_end; - public $export_sql_order; - - - // For import - - /** - * @var string Module import code - */ - public $import_code; - - /** - * @var string Module import label - */ - public $import_label; - - - /** - * @var string Module constant name - */ - public $const_name; - - /** - * @var bool Module can't be disabled - */ - public $always_enabled; - - /** - * @var bool Module is enabled globally (Multicompany support) - */ - public $core_enabled; - - /** - * @var string Relative path to module style sheet - * @deprecated - * @see module_parts - */ - public $style_sheet = ''; + /** + * @var DoliDb Database handler + */ + public $db; + + /** + * @var int Module unique ID + * @see https://wiki.dolibarr.org/index.php/List_of_modules_id + */ + public $numero; + + /** + * @var string Publisher name + * @since 4.0.0 + */ + public $editor_name; + + /** + * @var string URL of module at publisher site + * @since 4.0.0 + */ + public $editor_url; + + /** + * @var string Family + * @see familyinfo + * + * Native values: 'crm', 'financial', 'hr', 'projects', 'products', 'ecm', 'technic', 'other'. + * Use familyinfo to declare a custom value. + */ + public $family; + + /** + * @var array Custom family informations + * @see family + * + * e.g.: + * array( + * 'myownfamily' => array( + * 'position' => '001', + * 'label' => $langs->trans("MyOwnFamily") + * ) + * ); + * + */ + public $familyinfo; + + /** + * @var int Module position + * @since 3.9.0 + */ + public $module_position=500; + + /** + * @var string Module name + * + * Only used if Module[ID]Name translation string is not found. + * + * You can use the following code to automatically derive it from your module's class name: + * preg_replace('/^mod/i', '', get_class($this)) + */ + public $name; + + /** + * @var string[] Paths to create when module is activated + * + * e.g.: array('/mymodule/temp') + */ + public $dirs = array(); + + /** + * @var array Module boxes + */ + public $boxes = array(); + + /** + * @var array Module constants + */ + public $const = array(); + + /** + * @var array Module cron jobs entries + */ + public $cronjobs = array(); + + /** + * @var array Module access rights + */ + public $rights; + + /** + * @var string Module access rights family + */ + public $rights_class; + + /** + * @var array Module menu entries + */ + public $menu = array(); + + /** + * @var array Module parts + * array( + * // Set this to 1 if module has its own trigger directory (/mymodule/core/triggers) + * 'triggers' => 0, + * // Set this to 1 if module has its own login method directory (/mymodule/core/login) + * 'login' => 0, + * // Set this to 1 if module has its own substitution function file (/mymodule/core/substitutions) + * 'substitutions' => 0, + * // Set this to 1 if module has its own menus handler directory (/mymodule/core/menus) + * 'menus' => 0, + * // Set this to 1 if module has its own theme directory (/mymodule/theme) + * 'theme' => 0, + * // Set this to 1 if module overwrite template dir (/mymodule/core/tpl) + * 'tpl' => 0, + * // Set this to 1 if module has its own barcode directory (/mymodule/core/modules/barcode) + * 'barcode' => 0, + * // Set this to 1 if module has its own models directory (/mymodule/core/modules/xxx) + * 'models' => 0, + * // Set this to relative path of css file if module has its own css file + * 'css' => '/mymodule/css/mymodule.css.php', + * // Set this to relative path of js file if module must load a js on all pages + * 'js' => '/mymodule/js/mymodule.js', + * // Set here all hooks context managed by module + * 'hooks' => array('hookcontext1','hookcontext2'), + * // Set here all workflow context managed by module + * 'workflow' => array( + * 'WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2' = >array( + * 'enabled' => '! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', + * 'picto'=>'yourpicto@mymodule' + * ) + * ) + * ) + */ + public $module_parts = array(); + + /** + * @var string Module documents ? + * @deprecated Seems unused anywhere + */ + public $docs; + + /** + * @var string ? + * @deprecated Seems unused anywhere + */ + public $dbversion = "-"; + + /** + * @var string Error message + */ + public $error; + + /** + * @var string Module version + * @see http://semver.org + * + * The following keywords can also be used: + * 'development' + * 'experimental' + * 'dolibarr': only for core modules that share its version + * 'dolibarr_deprecated': only for deprecated core modules + * + */ + public $version; + + /** + * @var string Module description (short text) + * + * Only used if Module[ID]Desc translation string is not found. + */ + public $description; + + /** + * @var string Module description (long text) + * @since 4.0.0 + * + * HTML content supported. + */ + public $descriptionlong; + + + // For exports + + /** + * @var string Module export code + */ + public $export_code; + + /** + * @var string Module export label + */ + public $export_label; + + public $export_permission; + public $export_fields_array; + public $export_TypeFields_array; + public $export_entities_array; + public $export_special_array; // special or computed field + public $export_dependencies_array; + public $export_sql_start; + public $export_sql_end; + public $export_sql_order; + + + // For import + + /** + * @var string Module import code + */ + public $import_code; + + /** + * @var string Module import label + */ + public $import_label; + + + /** + * @var string Module constant name + */ + public $const_name; + + /** + * @var bool Module can't be disabled + */ + public $always_enabled; + + /** + * @var bool Module is enabled globally (Multicompany support) + */ + public $core_enabled; + + /** + * @var string Relative path to module style sheet + * @deprecated + * @see module_parts + */ + public $style_sheet = ''; /** * @var 0|1|2|3 Where to display the module in setup page @@ -322,24 +322,24 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $conflictwith; - /** - * @var string[] Module language files - */ - public $langfiles; + /** + * @var string[] Module language files + */ + public $langfiles; - /** - * @var array<string,string> Array of warnings to show when we activate the module - * - * array('always'='text') or array('FR'='text') - */ - public $warnings_activation; + /** + * @var array<string,string> Array of warnings to show when we activate the module + * + * array('always'='text') or array('FR'='text') + */ + public $warnings_activation; - /** - * @var array<string,string> Array of warnings to show when we activate an external module - * - * array('always'='text') or array('FR'='text') - */ - public $warnings_activation_ext; + /** + * @var array<string,string> Array of warnings to show when we activate an external module + * + * array('always'='text') or array('FR'='text') + */ + public $warnings_activation_ext; /** @@ -378,1769 +378,1769 @@ class DolibarrModules // Can not be abstract, because we need to insta // We need constructor into function unActivateModule into admin.lib.php - /** - * Enables a module. - * Inserts all informations into database - * + /** + * Enables a module. + * Inserts all informations into database + * * @param array $array_sql SQL requests to be executed when enabling module - * @param string $options String with options when disabling module: - * 'noboxes' = Do not insert boxes - * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation - * - * @return int 1 if OK, 0 if KO - */ - function _init($array_sql, $options='') - { - global $conf; - $err=0; - - $this->db->begin(); - - // Insert activation module constant - if (! $err) $err+=$this->_active(); - - // Insert new pages for tabs (into llx_const) - if (! $err) $err+=$this->insert_tabs(); - - // Insert activation of module's parts - if (! $err) $err+=$this->insert_module_parts(); - - // Insert constant defined by modules (into llx_const) - if (! $err && ! preg_match('/newboxdefonly/',$options)) $err+=$this->insert_const(); // Test on newboxdefonly to avoid to erase value during upgrade - - // Insert boxes def into llx_boxes_def and boxes setup (into llx_boxes) - if (! $err && ! preg_match('/noboxes/',$options)) $err+=$this->insert_boxes($options); - - // Insert cron job entries (entry in llx_cronjobs) - if (! $err) $err+=$this->insert_cronjobs(); - - // Insert permission definitions of module into llx_rights_def. If user is admin, grant this permission to user. - if (! $err) $err+=$this->insert_permissions(1, null, 1); - - // Insert specific menus entries into database - if (! $err) $err+=$this->insert_menus(); - - // Create module's directories - if (! $err) $err+=$this->create_dirs(); - - // Execute addons requests - $num=count($array_sql); - for ($i = 0; $i < $num; $i++) - { - if (! $err) - { - $val=$array_sql[$i]; - $sql=$val; - $ignoreerror=0; - if (is_array($val)) - { - $sql=$val['sql']; - $ignoreerror=$val['ignoreerror']; - } - // Add current entity id - $sql=str_replace('__ENTITY__', $conf->entity, $sql); - - dol_syslog(get_class($this)."::_init ignoreerror=".$ignoreerror."", LOG_DEBUG); - $result=$this->db->query($sql, $ignoreerror); - if (! $result) - { - if (! $ignoreerror) - { - $this->error=$this->db->lasterror(); - $err++; - } - else - { - dol_syslog(get_class($this)."::_init Warning ".$this->db->lasterror(), LOG_WARNING); - } - } - } - } - - // Return code - if (! $err) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return 0; - } - } - - /** - * Disable function. Deletes the module constant and boxes from the database. - * - * @param string[] $array_sql SQL requests to be executed when module is disabled - * @param string $options Options when disabling module: - * 'newboxdefonly|noboxes' = We don't remove boxes. - * - * @return int 1 if OK, 0 if KO - */ - function _remove($array_sql, $options='') - { - $err=0; - - $this->db->begin(); - - // Remove activation module line (constant MAIN_MODULE_MYMODULE in llx_const) - if (! $err) $err+=$this->_unactive(); - - // Remove activation of module's new tabs (MAIN_MODULE_MYMODULE_TABS_XXX in llx_const) - if (! $err) $err+=$this->delete_tabs(); - - // Remove activation of module's parts (MAIN_MODULE_MYMODULE_XXX in llx_const) - if (! $err) $err+=$this->delete_module_parts(); - - // Remove constants defined by modules - if (! $err) $err+=$this->delete_const(); - - // Remove list of module's available boxes (entry in llx_boxes) - if (! $err && ! preg_match('/(newboxdefonly|noboxes)/',$options)) $err+=$this->delete_boxes(); // We don't have to delete if option ask to keep boxes safe or ask to add new box def only - - // Remove list of module's cron job entries (entry in llx_cronjobs) - if (! $err) $err+=$this->delete_cronjobs(); - - // Remove module's permissions from list of available permissions (entries in llx_rights_def) - if (! $err) $err+=$this->delete_permissions(); - - // Remove module's menus (entries in llx_menu) - if (! $err) $err+=$this->delete_menus(); - - // Remove module's directories - if (! $err) $err+=$this->delete_dirs(); - - // Run complementary sql requests - $num=count($array_sql); - for ($i = 0; $i < $num; $i++) - { - if (! $err) - { - dol_syslog(get_class($this)."::_remove", LOG_DEBUG); - $result=$this->db->query($array_sql[$i]); - if (! $result) - { - $this->error=$this->db->error(); - $err++; - } - } - } - - // Return code - if (! $err) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return 0; - } - } - - - /** - * Gives the translated module name if translation exists in admin.lang or into language files of module. - * Otherwise return the module key name. - * - * @return string Translated module name - */ - function getName() - { - global $langs; - $langs->load("admin"); - - if ($langs->trans("Module".$this->numero."Name") != ("Module".$this->numero."Name")) - { - // If module name translation exists - return $langs->trans("Module".$this->numero."Name"); - } - else - { - // If module name translation using it's unique id does not exists, we try to use its name to find translation - if (is_array($this->langfiles)) - { - foreach($this->langfiles as $val) - { - if ($val) $langs->load($val); - } - } - - if ($langs->trans("Module".$this->name."Name") != ("Module".$this->name."Name")) - { - // If module name translation exists - return $langs->trans("Module".$this->name."Name"); - } - - // Last change with simple product label - return $langs->trans($this->name); - } - } - - - /** - * Gives the translated module description if translation exists in admin.lang or the default module description - * - * @return string Translated module description - */ - function getDesc() - { - global $langs; - $langs->load("admin"); - - if ($langs->trans("Module".$this->numero."Desc") != ("Module".$this->numero."Desc")) - { - // If module description translation exists - return $langs->trans("Module".$this->numero."Desc"); - } - else - { - // If module description translation does not exist using its unique id, we can use its name to find translation - if (is_array($this->langfiles)) - { - foreach($this->langfiles as $val) - { - if ($val) $langs->load($val); - } - } - return $langs->trans($this->description); - } - } - - /** - * Gives the long description of a module. First check README-la_LA.md then README.md - * If not markdown files found, it return translated value of the key ->descriptionlong. - * - * @return string Long description of a module from README.md of from property. - */ - function getDescLong() - { - global $langs; - $langs->load("admin"); - - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; - - $pathoffile = $this->getDescLongReadmeFound(); - - if ($pathoffile) // Mostly for external modules - { - $content = file_get_contents($pathoffile); - - if ((float) DOL_VERSION >= 6.0) - { - @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; - $content = dolMd2Html($content, 'parsedown', - array( - 'doc/'=>dol_buildpath(strtolower($this->name).'/doc/', 1), - 'img/'=>dol_buildpath(strtolower($this->name).'/img/', 1), - 'images/'=>dol_buildpath(strtolower($this->name).'/imgages/', 1), - )); - } - else - { - $content = nl2br($content); - } - } - else // Mostly for internal modules - { - if (! empty($this->descriptionlong)) - { - if (is_array($this->langfiles)) - { - foreach($this->langfiles as $val) - { - if ($val) $langs->load($val); - } - } - - $content = $langs->trans($this->descriptionlong); - } - } - - return $content; - } - - /** - * Return path of file if a README file was found. - * - * @return string Path of file if a README file was found. - */ - function getDescLongReadmeFound() - { - $filefound= false; - - // Define path to file README.md. - // First check README-la_LA.md then README.md - $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0); - if (dol_is_file($pathoffile)) - { - $filefound = true; - } - if (! $filefound) - { - $pathoffile = dol_buildpath(strtolower($this->name).'/README.md', 0); - if (dol_is_file($pathoffile)) - { - $filefound = true; - } - } - - return ($filefound?$pathoffile:''); - } - - - /** - * Gives the changelog. First check ChangeLog-la_LA.md then ChangeLog.md - * - * @return string Content of ChangeLog - */ - function getChangeLog() - { - global $langs; - $langs->load("admin"); - - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; - - $filefound= false; - - // Define path to file README.md. - // First check README-la_LA.md then README.md - $pathoffile = dol_buildpath(strtolower($this->name).'/ChangeLog-'.$langs->defaultlang.'.md', 0); - if (dol_is_file($pathoffile)) - { - $filefound = true; - } - if (! $filefound) - { - $pathoffile = dol_buildpath(strtolower($this->name).'/ChangeLog.md', 0); - if (dol_is_file($pathoffile)) - { - $filefound = true; - } - } - - if ($filefound) // Mostly for external modules - { - $content = file_get_contents($pathoffile); - - if ((float) DOL_VERSION >= 6.0) - { - @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; - $content = dolMd2Html($content, 'parsedown', array('doc/'=>dol_buildpath(strtolower($this->name).'/doc/', 1))); - } - else - { - $content = nl2br($content); - } - } - - return $content; - } - - /** - * Gives the publisher name - * - * @return string Publisher name - */ - function getPublisher() - { - return $this->editor_name; - } - - /** - * Gives the publisher url - * - * @return string Publisher url - */ - function getPublisherUrl() - { - return $this->editor_url; - } - - /** - * Gives module version (translated if param $translated is on) - * For 'experimental' modules, gives 'experimental' translation - * For 'dolibarr' modules, gives Dolibarr version - * - * @param int $translated 1=Special version keys are translated, 0=Special version keys are not translated - * @return string Module version - */ - function getVersion($translated=1) - { - global $langs; - $langs->load("admin"); - - $ret=''; - - $newversion=preg_replace('/_deprecated/','',$this->version); - if ($newversion == 'experimental') $ret=($translated?$langs->trans("VersionExperimental"):$newversion); - elseif ($newversion == 'development') $ret=($translated?$langs->trans("VersionDevelopment"):$newversion); - elseif ($newversion == 'dolibarr') $ret=DOL_VERSION; - elseif ($newversion) $ret=$newversion; - else $ret=($translated?$langs->trans("VersionUnknown"):'unknown'); - - if (preg_match('/_deprecated/',$this->version)) $ret.=($translated?' ('.$langs->trans("Deprecated").')':$this->version); - return $ret; - } - - - /** - * Tells if module is core or external - * - * @return string 'core', 'external' or 'unknown' - */ - function isCoreOrExternalModule() - { - if ($this->version == 'dolibarr' || $this->version == 'dolibarr_deprecated') return 'core'; - if (! empty($this->version) && ! in_array($this->version,array('experimental','development'))) return 'external'; - if (! empty($this->editor_name) || ! empty($this->editor_url)) return 'external'; - if ($this->numero >= 100000) return 'external'; - return 'unknown'; - } - - - /** - * Gives module related language files list - * - * @return string[] Language files list - */ - function getLangFilesArray() - { - return $this->langfiles; - } - - /** - * Gives translated label of an export dataset - * - * @param int $r Dataset index - * - * @return string Translated databaset label - */ - function getExportDatasetLabel($r) - { - global $langs; - - $langstring="ExportDataset_".$this->export_code[$r]; - if ($langs->trans($langstring) == $langstring) - { - // Translation not found - return $langs->trans($this->export_label[$r]); - } - else - { - // Translation found - return $langs->trans($langstring); - } - } - - - /** - * Gives translated label of an import dataset - * - * @param int $r Dataset index - * - * @return string Translated dataset label - */ - function getImportDatasetLabel($r) - { - global $langs; - - $langstring="ImportDataset_".$this->import_code[$r]; - //print "x".$langstring; - if ($langs->trans($langstring) == $langstring) - { - // Translation not found - return $langs->trans($this->import_label[$r]); - } - else - { - // Translation found - return $langs->trans($langstring); - } - } - - - /** - * Gives the last date of activation - * - * @return timestamp Date of last activation - */ - function getLastActivationDate() - { - global $conf; - - $sql = "SELECT tms FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; - $sql.= " AND entity IN (0, ".$conf->entity.")"; - - dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; - else - { - $obj=$this->db->fetch_object($resql); - if ($obj) return $this->db->jdate($obj->tms); - } - - return ''; - } - - - /** - * Gives the last author of activation - * - * @return array Array array('authorid'=>Id of last activation user, 'lastactivationdate'=>Date of last activation) - */ - function getLastActivationInfo() - { - global $conf; - - $sql = "SELECT tms, note FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; - $sql.= " AND entity IN (0, ".$conf->entity.")"; - - dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; - else - { - $obj=$this->db->fetch_object($resql); - $tmp=array(); - if ($obj->note) - { - $tmp=json_decode($obj->note, true); - } - if ($obj) return array('authorid'=>$tmp['authorid'], 'ip'=>$tmp['ip'], 'lastactivationdate'=>$this->db->jdate($obj->tms)); - } - - return array(); - } - - - /** - * Insert constants for module activation - * - * @return int Error count (0 if OK) - */ - function _active() - { - global $conf, $user; - - $err = 0; - - // Common module - $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity); - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; - $sql.= " AND entity IN (0, ".$entity.")"; - - dol_syslog(get_class($this)."::_active", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; - - $note=json_encode(array('authorid'=>(is_object($user)?$user->id:0), 'ip'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR']))); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name, value, visible, entity, note) VALUES"; - $sql.= " (".$this->db->encrypt($this->const_name,1); - $sql.= ", ".$this->db->encrypt('1',1); - $sql.= ", 0, ".$entity; - $sql.= ", '".$this->db->escape($note)."')"; - - dol_syslog(get_class($this)."::_active", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; - - return $err; - } - - - /** - * Module deactivation - * - * @return int Error count (0 if OK) - */ - function _unactive() - { - global $conf; - - $err = 0; - - // Common module - $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity); - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; - $sql.= " AND entity IN (0, ".$entity.")"; - - dol_syslog(get_class($this)."::_unactive", LOG_DEBUG); - $this->db->query($sql); - - return $err; - } - - - /** - * Create tables and keys required by module. - * Files module.sql and module.key.sql with create table and create keys - * commands must be stored in directory reldir='/module/sql/' - * This function is called by this->init - * - * @param string $reldir Relative directory where to scan files - * @return int <=0 if KO, >0 if OK - */ - function _load_tables($reldir) - { - global $conf; - - $error=0; - $dirfound=0; - - if (empty($reldir)) return 1; - - include_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; - - $ok = 1; - foreach($conf->file->dol_document_root as $dirroot) - { - if ($ok) - { - $dir = $dirroot.$reldir; - $ok = 0; - - $handle=@opendir($dir); // Dir may not exists - if (is_resource($handle)) - { - $dirfound++; - - // Run llx_mytable.sql files, then llx_mytable_*.sql - $files = array(); - while (($file = readdir($handle))!==false) - { - $files[] = $file; - } - sort($files); - foreach ($files as $file) - { - if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') - { - $result=run_sql($dir.$file,1,'',1); - if ($result <= 0) $error++; - } - } - - rewinddir($handle); - - // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) then then llx_mytable_*.key.sql - $files = array(); - while (($file = readdir($handle))!==false) - { - $files[] = $file; - } - sort($files); - foreach ($files as $file) - { - if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') - { - $result=run_sql($dir.$file,1,'',1); - if ($result <= 0) $error++; - } - } - - rewinddir($handle); - - // Run data_xxx.sql files (Must be done after llx_mytable.key.sql) - $files = array(); - while (($file = readdir($handle))!==false) - { - $files[] = $file; - } - sort($files); - foreach ($files as $file) - { - if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data') - { - $result=run_sql($dir.$file,1,'',1); - if ($result <= 0) $error++; - } - } - - rewinddir($handle); - - // Run update_xxx.sql files - $files = array(); - while (($file = readdir($handle))!==false) - { - $files[] = $file; - } - sort($files); - foreach ($files as $file) - { - if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update') - { - $result=run_sql($dir.$file,1,'',1); - if ($result <= 0) $error++; - } - } - - closedir($handle); - } - - if ($error == 0) - { - $ok = 1; - } - } - } - - if (! $dirfound) dol_syslog("A module ask to load sql files into ".$reldir." but this directory was not found.", LOG_WARNING); - return $ok; - } - - - /** - * Adds boxes - * - * @param string $option Options when disabling module ('newboxdefonly'=insert only boxes definition) - * - * @return int Error count (0 if OK) - */ - function insert_boxes($option='') - { - require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; - - global $conf; - - $err=0; - - if (is_array($this->boxes)) - { - $pos_name = InfoBox::getListOfPagesForBoxes(); - - foreach ($this->boxes as $key => $value) - { - $file = isset($this->boxes[$key]['file'])?$this->boxes[$key]['file']:''; - $note = isset($this->boxes[$key]['note'])?$this->boxes[$key]['note']:''; - $enabledbydefaulton = isset($this->boxes[$key]['enabledbydefaulton'])?$this->boxes[$key]['enabledbydefaulton']:'Home'; - - if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility - if (empty($note)) $note = isset($this->boxes[$key][2])?$this->boxes[$key][2]:''; // For backward compatibility - - // Search if boxes def already present - $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."boxes_def"; - $sql.= " WHERE file = '".$this->db->escape($file)."'"; - $sql.= " AND entity = ".$conf->entity; - if ($note) $sql.=" AND note ='".$this->db->escape($note)."'"; - - dol_syslog(get_class($this)."::insert_boxes", LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - $obj = $this->db->fetch_object($result); - if ($obj->nb == 0) - { - $this->db->begin(); - - if (! $err) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes_def (file, entity, note)"; - $sql.= " VALUES ('".$this->db->escape($file)."', "; - $sql.= $conf->entity.", "; - $sql.= $note?"'".$this->db->escape($note)."'":"null"; - $sql.= ")"; - - dol_syslog(get_class($this)."::insert_boxes", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; - - } - if (! $err && ! preg_match('/newboxdefonly/',$option)) - { - $lastid=$this->db->last_insert_id(MAIN_DB_PREFIX."boxes_def","rowid"); - - foreach ($pos_name as $key2 => $val2) - { - //print 'key2='.$key2.'-val2='.$val2."<br>\n"; - if ($enabledbydefaulton && $val2 != $enabledbydefaulton) continue; // Not enabled by default onto this page. - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes (box_id,position,box_order,fk_user,entity)"; - $sql.= " VALUES (".$lastid.", ".$key2.", '0', 0, ".$conf->entity.")"; - - dol_syslog(get_class($this)."::insert_boxes onto page ".$key2."=".$val2."", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; - } - } - - if (! $err) - { - $this->db->commit(); - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - } - } - // else box already registered into database - } - else - { - $this->error=$this->db->lasterror(); - $err++; - } - } - } - - return $err; - } - - - /** - * Removes boxes - * - * @return int Error count (0 if OK) - */ - function delete_boxes() - { - global $conf; - - $err=0; - - if (is_array($this->boxes)) - { - foreach ($this->boxes as $key => $value) - { - //$titre = $this->boxes[$key][0]; - $file = $this->boxes[$key]['file']; - //$note = $this->boxes[$key][2]; - - // TODO If the box is also included by another module and the other module is still on, we should not remove it. - // For the moment, we manage this with hard coded exception - //print "Remove box ".$file.'<br>'; - if ($file == 'box_graph_product_distribution.php') - { - if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) - { - dol_syslog("We discard disabling of module ".$file." because another module still active require it."); - continue; - } - } - - if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility - - if ($this->db->type == 'sqlite3') { - // sqlite doesn't support "USING" syntax. - // TODO: remove this dependency. - $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes "; - $sql .= "WHERE ".MAIN_DB_PREFIX."boxes.box_id IN ("; - $sql .= "SELECT ".MAIN_DB_PREFIX."boxes_def.rowid "; - $sql .= "FROM ".MAIN_DB_PREFIX."boxes_def "; - $sql .= "WHERE ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."') "; - $sql .= "AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; - } else { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; - $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def"; - $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid"; - $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'"; - $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; - } - - dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $err++; - } - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes_def"; - $sql.= " WHERE file = '".$this->db->escape($file)."'"; - $sql.= " AND entity = ".$conf->entity; - - dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $err++; - } - } - } - - return $err; - } - - /** - * Adds cronjobs - * - * @return int Error count (0 if OK) - */ - function insert_cronjobs() - { - require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; - - global $conf; - - $err=0; - - if (is_array($this->cronjobs)) - { - foreach ($this->cronjobs as $key => $value) - { - $label = isset($this->cronjobs[$key]['label'])?$this->cronjobs[$key]['label']:''; - $jobtype = isset($this->cronjobs[$key]['jobtype'])?$this->cronjobs[$key]['jobtype']:''; - $class = isset($this->cronjobs[$key]['class'])?$this->cronjobs[$key]['class']:''; - $objectname = isset($this->cronjobs[$key]['objectname'])?$this->cronjobs[$key]['objectname']:''; - $method = isset($this->cronjobs[$key]['method'])?$this->cronjobs[$key]['method']:''; - $command = isset($this->cronjobs[$key]['command'])?$this->cronjobs[$key]['command']:''; - $parameters = isset($this->cronjobs[$key]['parameters'])?$this->cronjobs[$key]['parameters']:''; - $comment = isset($this->cronjobs[$key]['comment'])?$this->cronjobs[$key]['comment']:''; - $frequency = isset($this->cronjobs[$key]['frequency'])?$this->cronjobs[$key]['frequency']:''; - $unitfrequency = isset($this->cronjobs[$key]['unitfrequency'])?$this->cronjobs[$key]['unitfrequency']:''; - $status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:''; - $priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:''; - $test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:''; // Line must be visible - - // Search if boxes def already present - $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob"; - $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'"; - if ($class) $sql.= " AND classesname = '".$this->db->escape($class)."'"; - if ($objectname) $sql.= " AND objectname = '".$this->db->escape($objectname)."'"; - if ($method) $sql.= " AND methodename = '".$this->db->escape($method)."'"; - if ($command) $sql.= " AND command = '".$this->db->escape($command)."'"; - $sql.= " AND entity = ".$conf->entity; - - $now=dol_now(); - - dol_syslog(get_class($this)."::insert_cronjobs", LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - $obj = $this->db->fetch_object($result); - if ($obj->nb == 0) - { - $this->db->begin(); - - if (! $err) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note,"; - if(is_int($frequency)){ $sql.= ' frequency,'; } - if(is_int($unitfrequency)){ $sql.= ' unitfrequency,'; } - if(is_int($priority)){ $sql.= ' priority,'; } - if(is_int($status)){ $sql.= ' status,'; } - $sql.= " entity, test)"; - $sql.= " VALUES ("; - $sql.= "'".$this->db->escape($this->rights_class)."', "; - $sql.= "'".$this->db->idate($now)."', "; - $sql.= "'".$this->db->idate($now)."', "; - $sql.= "'".$this->db->escape($label)."', "; - $sql.= "'".$this->db->escape($jobtype)."', "; - $sql.= ($class?"'".$this->db->escape($class)."'":"null").","; - $sql.= ($objectname?"'".$this->db->escape($objectname)."'":"null").","; - $sql.= ($method?"'".$this->db->escape($method)."'":"null").","; - $sql.= ($command?"'".$this->db->escape($command)."'":"null").","; - $sql.= ($parameters?"'".$this->db->escape($parameters)."'":"null").","; - $sql.= ($comment?"'".$this->db->escape($comment)."'":"null").","; - if(is_int($frequency)){ $sql.= "'".$this->db->escape($frequency)."', "; } - if(is_int($unitfrequency)){ $sql.= "'".$this->db->escape($unitfrequency)."', "; } - if(is_int($priority)) {$sql.= "'".$this->db->escape($priority)."', ";} - if(is_int($status)){ $sql.= "'".$this->db->escape($status)."', "; } - $sql.= $conf->entity.","; - $sql.= "'".$this->db->escape($test)."'"; - $sql.= ")"; - - dol_syslog(get_class($this)."::insert_cronjobs", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; - - } - - if (! $err) - { - $this->db->commit(); - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - } - } - // else box already registered into database - } - else - { - $this->error=$this->db->lasterror(); - $err++; - } - } - } - - return $err; - } - - - /** - * Removes boxes - * - * @return int Error count (0 if OK) - */ - function delete_cronjobs() - { - global $conf; - - $err=0; - - if (is_array($this->cronjobs)) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."cronjob"; - $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'"; - $sql.= " AND entity = ".$conf->entity; - - dol_syslog(get_class($this)."::delete_cronjobs", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $err++; - } - } - - return $err; - } - - /** - * Removes tabs - * - * @return int Error count (0 if OK) - */ - function delete_tabs() - { - global $conf; - - $err=0; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." like '".$this->db->escape($this->const_name)."_TABS_%'"; - $sql.= " AND entity = ".$conf->entity; - - dol_syslog(get_class($this)."::delete_tabs", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $this->error=$this->db->lasterror(); - $err++; - } - - return $err; - } - - /** - * Adds tabs - * - * @return int Error count (0 if ok) - */ - function insert_tabs() + * @param string $options String with options when disabling module: + * 'noboxes' = Do not insert boxes + * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation + * + * @return int 1 if OK, 0 if KO + */ + function _init($array_sql, $options='') { global $conf; - $err=0; - if (! empty($this->tabs)) + $this->db->begin(); + + // Insert activation module constant + if (! $err) $err+=$this->_active(); + + // Insert new pages for tabs (into llx_const) + if (! $err) $err+=$this->insert_tabs(); + + // Insert activation of module's parts + if (! $err) $err+=$this->insert_module_parts(); + + // Insert constant defined by modules (into llx_const) + if (! $err && ! preg_match('/newboxdefonly/',$options)) $err+=$this->insert_const(); // Test on newboxdefonly to avoid to erase value during upgrade + + // Insert boxes def into llx_boxes_def and boxes setup (into llx_boxes) + if (! $err && ! preg_match('/noboxes/',$options)) $err+=$this->insert_boxes($options); + + // Insert cron job entries (entry in llx_cronjobs) + if (! $err) $err+=$this->insert_cronjobs(); + + // Insert permission definitions of module into llx_rights_def. If user is admin, grant this permission to user. + if (! $err) $err+=$this->insert_permissions(1, null, 1); + + // Insert specific menus entries into database + if (! $err) $err+=$this->insert_menus(); + + // Create module's directories + if (! $err) $err+=$this->create_dirs(); + + // Execute addons requests + $num=count($array_sql); + for ($i = 0; $i < $num; $i++) { - $i=0; - foreach ($this->tabs as $key => $value) + if (! $err) { - if (is_array($value) && count($value) == 0) continue; // Discard empty arrays + $val=$array_sql[$i]; + $sql=$val; + $ignoreerror=0; + if (is_array($val)) + { + $sql=$val['sql']; + $ignoreerror=$val['ignoreerror']; + } + // Add current entity id + $sql=str_replace('__ENTITY__', $conf->entity, $sql); - $entity=$conf->entity; - $newvalue = $value; + dol_syslog(get_class($this)."::_init ignoreerror=".$ignoreerror."", LOG_DEBUG); + $result=$this->db->query($sql, $ignoreerror); + if (! $result) + { + if (! $ignoreerror) + { + $this->error=$this->db->lasterror(); + $err++; + } + else + { + dol_syslog(get_class($this)."::_init Warning ".$this->db->lasterror(), LOG_WARNING); + } + } + } + } - if (is_array($value)) + // Return code + if (! $err) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return 0; + } + } + + /** + * Disable function. Deletes the module constant and boxes from the database. + * + * @param string[] $array_sql SQL requests to be executed when module is disabled + * @param string $options Options when disabling module: + * 'newboxdefonly|noboxes' = We don't remove boxes. + * + * @return int 1 if OK, 0 if KO + */ + function _remove($array_sql, $options='') + { + $err=0; + + $this->db->begin(); + + // Remove activation module line (constant MAIN_MODULE_MYMODULE in llx_const) + if (! $err) $err+=$this->_unactive(); + + // Remove activation of module's new tabs (MAIN_MODULE_MYMODULE_TABS_XXX in llx_const) + if (! $err) $err+=$this->delete_tabs(); + + // Remove activation of module's parts (MAIN_MODULE_MYMODULE_XXX in llx_const) + if (! $err) $err+=$this->delete_module_parts(); + + // Remove constants defined by modules + if (! $err) $err+=$this->delete_const(); + + // Remove list of module's available boxes (entry in llx_boxes) + if (! $err && ! preg_match('/(newboxdefonly|noboxes)/',$options)) $err+=$this->delete_boxes(); // We don't have to delete if option ask to keep boxes safe or ask to add new box def only + + // Remove list of module's cron job entries (entry in llx_cronjobs) + if (! $err) $err+=$this->delete_cronjobs(); + + // Remove module's permissions from list of available permissions (entries in llx_rights_def) + if (! $err) $err+=$this->delete_permissions(); + + // Remove module's menus (entries in llx_menu) + if (! $err) $err+=$this->delete_menus(); + + // Remove module's directories + if (! $err) $err+=$this->delete_dirs(); + + // Run complementary sql requests + $num=count($array_sql); + for ($i = 0; $i < $num; $i++) + { + if (! $err) + { + dol_syslog(get_class($this)."::_remove", LOG_DEBUG); + $result=$this->db->query($array_sql[$i]); + if (! $result) { - $newvalue = $value['data']; - if (isset($value['entity'])) $entity = $value['entity']; + $this->error=$this->db->error(); + $err++; } + } + } - if ($newvalue) + // Return code + if (! $err) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return 0; + } + } + + + /** + * Gives the translated module name if translation exists in admin.lang or into language files of module. + * Otherwise return the module key name. + * + * @return string Translated module name + */ + function getName() + { + global $langs; + $langs->load("admin"); + + if ($langs->trans("Module".$this->numero."Name") != ("Module".$this->numero."Name")) + { + // If module name translation exists + return $langs->trans("Module".$this->numero."Name"); + } + else + { + // If module name translation using it's unique id does not exists, we try to use its name to find translation + if (is_array($this->langfiles)) + { + foreach($this->langfiles as $val) { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; - $sql.= "name"; - $sql.= ", type"; - $sql.= ", value"; - $sql.= ", note"; - $sql.= ", visible"; - $sql.= ", entity"; - $sql.= ")"; - $sql.= " VALUES ("; - $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1); - $sql.= ", 'chaine'"; - $sql.= ", ".$this->db->encrypt($newvalue,1); - $sql.= ", null"; - $sql.= ", '0'"; - $sql.= ", ".$entity; - $sql.= ")"; + if ($val) $langs->load($val); + } + } - dol_syslog(get_class($this)."::insert_tabs", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) - { - dol_syslog($this->db->lasterror(), LOG_ERR); - if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $this->error = $this->db->lasterror(); - $this->errors[] = $this->db->lasterror(); - $err++; - break; - } - } + if ($langs->trans("Module".$this->name."Name") != ("Module".$this->name."Name")) + { + // If module name translation exists + return $langs->trans("Module".$this->name."Name"); + } + + // Last change with simple product label + return $langs->trans($this->name); + } + } + + + /** + * Gives the translated module description if translation exists in admin.lang or the default module description + * + * @return string Translated module description + */ + function getDesc() + { + global $langs; + $langs->load("admin"); + + if ($langs->trans("Module".$this->numero."Desc") != ("Module".$this->numero."Desc")) + { + // If module description translation exists + return $langs->trans("Module".$this->numero."Desc"); + } + else + { + // If module description translation does not exist using its unique id, we can use its name to find translation + if (is_array($this->langfiles)) + { + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); } - $i++; } + return $langs->trans($this->description); } - return $err; } - /** - * Adds constants - * - * @return int Error count (0 if OK) - */ - function insert_const() - { - global $conf; - - $err=0; - - if (empty($this->const)) return 0; - - foreach ($this->const as $key => $value) - { - $name = $this->const[$key][0]; - $type = $this->const[$key][1]; - $val = $this->const[$key][2]; - $note = isset($this->const[$key][3])?$this->const[$key][3]:''; - $visible = isset($this->const[$key][4])?$this->const[$key][4]:0; - $entity = (! empty($this->const[$key][5]) && $this->const[$key][5]!='current')?0:$conf->entity; - - // Clean - if (empty($visible)) $visible='0'; - if (empty($val) && $val != '0') $val=''; - - $sql = "SELECT count(*)"; - $sql.= " FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($name)."'"; - $sql.= " AND entity = ".$entity; - - $result=$this->db->query($sql); - if ($result) - { - $row = $this->db->fetch_row($result); - - if ($row[0] == 0) // If not found - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)"; - $sql.= " VALUES ("; - $sql.= $this->db->encrypt($name,1); - $sql.= ",'".$type."'"; - $sql.= ",".(($val != '')?$this->db->encrypt($val,1):"''"); - $sql.= ",".($note?"'".$this->db->escape($note)."'":"null"); - $sql.= ",'".$visible."'"; - $sql.= ",".$entity; - $sql.= ")"; - - - dol_syslog(get_class($this)."::insert_const", LOG_DEBUG); - if (! $this->db->query($sql) ) - { - $err++; - } - } - else - { - dol_syslog(get_class($this)."::insert_const constant '".$name."' already exists", LOG_WARNING); - } - } - else - { - $err++; - } - } - - return $err; - } - - /** - * Removes constants tagged 'deleteonunactive' - * - * @return int <0 if KO, 0 if OK - */ - function delete_const() - { - global $conf; - - $err=0; - - if (empty($this->const)) return 0; - - foreach ($this->const as $key => $value) - { - $name = $this->const[$key][0]; - $deleteonunactive = (! empty($this->const[$key][6]))?1:0; - - if ($deleteonunactive) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'"; - $sql.= " AND entity in (0, ".$conf->entity.")"; - dol_syslog(get_class($this)."::delete_const", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $this->error=$this->db->lasterror(); - $err++; - } - } - } - - return $err; - } - - /** - * Adds access rights - * - * @param int $reinitadminperms If 1, we also grant them to all admin users - * @param int $force_entity Force current entity - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int Error count (0 if OK) - */ - function insert_permissions($reinitadminperms=0, $force_entity=null, $notrigger=0) - { - global $conf,$user; - - $err=0; - $entity=(! empty($force_entity) ? $force_entity : $conf->entity); - - // Test if module is activated - $sql_del = "SELECT ".$this->db->decrypt('value')." as value"; - $sql_del.= " FROM ".MAIN_DB_PREFIX."const"; - $sql_del.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; - $sql_del.= " AND entity IN (0,".$entity.")"; - - dol_syslog(get_class($this)."::insert_permissions", LOG_DEBUG); - $resql=$this->db->query($sql_del); - - if ($resql) - { - $obj=$this->db->fetch_object($resql); - if ($obj !== null && ! empty($obj->value) && ! empty($this->rights)) - { - // If the module is active - foreach ($this->rights as $key => $value) - { - $r_id = $this->rights[$key][0]; - $r_desc = $this->rights[$key][1]; - $r_type = isset($this->rights[$key][2])?$this->rights[$key][2]:''; - $r_def = $this->rights[$key][3]; - $r_perms = $this->rights[$key][4]; - $r_subperms = isset($this->rights[$key][5])?$this->rights[$key][5]:''; - $r_modul = $this->rights_class; - - if (empty($r_type)) $r_type='w'; - - // Search if perm already present - $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."rights_def"; - $sql.= " WHERE id = ".$r_id." AND entity = ".$entity; - $resqlselect=$this->db->query($sql); - - $obj = $this->db->fetch_object($resqlselect); - if ($obj->nb == 0) - { - if (dol_strlen($r_perms) ) - { - if (dol_strlen($r_subperms) ) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; - $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)"; - $sql.= " VALUES "; - $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')"; - } - else - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; - $sql.= " (id, entity, libelle, module, type, bydefault, perms)"; - $sql.= " VALUES "; - $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')"; - } - } - else - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def "; - $sql .= " (id, entity, libelle, module, type, bydefault)"; - $sql .= " VALUES "; - $sql .= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")"; - } - - $resqlinsert=$this->db->query($sql,1); - - if (! $resqlinsert) - { - if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS") - { - $this->error=$this->db->lasterror(); - $err++; - break; - } - else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO); - - } - - $this->db->free($resqlinsert); - } - - $this->db->free($resqlselect); - - // If we want to init permissions on admin users - if ($reinitadminperms) - { - if (! class_exists('User')) { - require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; - } - $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."user WHERE admin = 1"; - dol_syslog(get_class($this)."::insert_permissions Search all admin users", LOG_DEBUG); - $resqlseladmin=$this->db->query($sql,1); - if ($resqlseladmin) - { - $num=$this->db->num_rows($resqlseladmin); - $i=0; - while ($i < $num) - { - $obj2=$this->db->fetch_object($resqlseladmin); - dol_syslog(get_class($this)."::insert_permissions Add permission to user id=".$obj2->rowid); - $tmpuser=new User($this->db); - $tmpuser->fetch($obj2->rowid); - if (!empty($tmpuser->id)) { - $tmpuser->addrights($r_id, '', '', 0, 1); - } - $i++; - } - if (! empty($user->admin)) // Reload permission for current user if defined - { - // We reload permissions - $user->clearrights(); - $user->getrights(); - } - } - else dol_print_error($this->db); - } - } - } - $this->db->free($resql); - } - else - { - $this->error=$this->db->lasterror(); - $err++; - } - - return $err; - } - - - /** - * Removes access rights - * - * @return int Error count (0 if OK) - */ - function delete_permissions() - { - global $conf; - - $err=0; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."rights_def"; - $sql.= " WHERE module = '".$this->db->escape($this->rights_class)."'"; - $sql.= " AND entity = ".$conf->entity; - dol_syslog(get_class($this)."::delete_permissions", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $this->error=$this->db->lasterror(); - $err++; - } - - return $err; - } - - - /** - * Adds menu entries - * - * @return int Error count (0 if OK) - */ - function insert_menus() - { - global $user; - - if (! is_array($this->menu) || empty($this->menu)) return 0; - - require_once DOL_DOCUMENT_ROOT . '/core/class/menubase.class.php'; - - $err=0; - - $this->db->begin(); - - foreach ($this->menu as $key => $value) - { - $menu = new Menubase($this->db); - $menu->menu_handler='all'; - $menu->module=$this->rights_class; - if (! $this->menu[$key]['fk_menu']) - { - $menu->fk_menu=0; - } - else - { - $foundparent=0; - $fk_parent=$this->menu[$key]['fk_menu']; - if (preg_match('/^r=/',$fk_parent)) // old deprecated method - { - $fk_parent=str_replace('r=','',$fk_parent); - if (isset($this->menu[$fk_parent]['rowid'])) - { - $menu->fk_menu=$this->menu[$fk_parent]['rowid']; - $foundparent=1; - } - } - elseif (preg_match('/^fk_mainmenu=([a-zA-Z0-9_]+),fk_leftmenu=([a-zA-Z0-9_]+)$/',$fk_parent,$reg)) - { - $menu->fk_menu=-1; - $menu->fk_mainmenu=$reg[1]; - $menu->fk_leftmenu=$reg[2]; - $foundparent=1; - } - elseif (preg_match('/^fk_mainmenu=([a-zA-Z0-9_]+)$/',$fk_parent,$reg)) - { - $menu->fk_menu=-1; - $menu->fk_mainmenu=$reg[1]; - $menu->fk_leftmenu=''; - $foundparent=1; - } - if (! $foundparent) - { - $this->error="ErrorBadDefinitionOfMenuArrayInModuleDescriptor"; - dol_syslog(get_class($this)."::insert_menus ".$this->error." ".$this->menu[$key]['fk_menu'], LOG_ERR); - $err++; - } - } - $menu->type=$this->menu[$key]['type']; - $menu->mainmenu=isset($this->menu[$key]['mainmenu'])?$this->menu[$key]['mainmenu']:(isset($menu->fk_mainmenu)?$menu->fk_mainmenu:''); - $menu->leftmenu=isset($this->menu[$key]['leftmenu'])?$this->menu[$key]['leftmenu']:''; - $menu->titre=$this->menu[$key]['titre']; - $menu->url=$this->menu[$key]['url']; - $menu->langs=$this->menu[$key]['langs']; - $menu->position=$this->menu[$key]['position']; - $menu->perms=$this->menu[$key]['perms']; - $menu->target=$this->menu[$key]['target']; - $menu->user=$this->menu[$key]['user']; - $menu->enabled=isset($this->menu[$key]['enabled'])?$this->menu[$key]['enabled']:0; - $menu->position=$this->menu[$key]['position']; - - if (! $err) - { - $result=$menu->create($user); // Save menu entry into table llx_menu - if ($result > 0) - { - $this->menu[$key]['rowid']=$result; - } - else - { - $this->error=$menu->error; - dol_syslog(get_class($this).'::insert_menus result='.$result." ".$this->error, LOG_ERR); - $err++; - break; - } - } - } - - if (! $err) - { - $this->db->commit(); - } - else - { - dol_syslog(get_class($this)."::insert_menus ".$this->error, LOG_ERR); - $this->db->rollback(); - } - - return $err; - } - - - /** - * Removes menu entries - * - * @return int Error count (0 if OK) - */ - function delete_menus() - { - global $conf; - - $err=0; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."menu"; - $sql.= " WHERE module = '".$this->db->escape($this->rights_class)."'"; - $sql.= " AND entity = ".$conf->entity; - - dol_syslog(get_class($this)."::delete_menus", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $this->error=$this->db->lasterror(); - $err++; - } - - return $err; - } - - /** - * Creates directories - * - * @return int Error count (0 if OK) - */ - function create_dirs() - { - global $langs, $conf; - - $err=0; - - if (isset($this->dirs) && is_array($this->dirs)) - { - foreach ($this->dirs as $key => $value) - { - $addtodatabase=0; - - if (! is_array($value)) $dir=$value; // Default simple mode - else { - $constname = $this->const_name."_DIR_"; - $dir = $this->dirs[$key][1]; - $addtodatabase = empty($this->dirs[$key][2])?'':$this->dirs[$key][2]; // Create constante in llx_const - $subname = empty($this->dirs[$key][3])?'':strtoupper($this->dirs[$key][3]); // Add submodule name (ex: $conf->module->submodule->dir_output) - $forcename = empty($this->dirs[$key][4])?'':strtoupper($this->dirs[$key][4]); // Change the module name if different - - if (! empty($forcename)) $constname = 'MAIN_MODULE_'.$forcename."_DIR_"; - if (! empty($subname)) $constname = $constname.$subname."_"; - - $name = $constname.strtoupper($this->dirs[$key][0]); - } - - // Define directory full path ($dir must start with "/") - if (empty($conf->global->MAIN_MODULE_MULTICOMPANY) || $conf->entity == 1) $fulldir = DOL_DATA_ROOT.$dir; - else $fulldir = DOL_DATA_ROOT."/".$conf->entity.$dir; - // Create dir if it does not exists - if (! empty($fulldir) && ! file_exists($fulldir)) - { - if (dol_mkdir($fulldir, DOL_DATA_ROOT) < 0) - { - $this->error = $langs->trans("ErrorCanNotCreateDir",$fulldir); - dol_syslog(get_class($this)."::_init ".$this->error, LOG_ERR); - $err++; - } - } - - // Define the constant in database if requested (not the default mode) - if (! empty($addtodatabase)) - { - $result = $this->insert_dirs($name, $dir); - if ($result) $err++; - } - } - } - - return $err; - } - - - /** - * Adds directories definitions - * - * @param string $name Name - * @param string $dir Directory - * - * @return int Error count (0 if OK) - */ - function insert_dirs($name,$dir) - { - global $conf; - - $err=0; - - $sql = "SELECT count(*)"; - $sql.= " FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'"; - $sql.= " AND entity = ".$conf->entity; - - dol_syslog(get_class($this)."::insert_dirs", LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - $row = $this->db->fetch_row($result); - - if ($row[0] == 0) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)"; - $sql.= " VALUES (".$this->db->encrypt($name,1).",'chaine',".$this->db->encrypt($dir,1).",'Directory for module ".$this->name."','0',".$conf->entity.")"; - - dol_syslog(get_class($this)."::insert_dirs", LOG_DEBUG); - $this->db->query($sql); - } - } - else - { - $this->error=$this->db->lasterror(); - $err++; - } - - return $err; - } - - - /** - * Removes directories - * - * @return int Error count (0 if OK) - */ - function delete_dirs() - { - global $conf; - - $err=0; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->db->escape($this->const_name)."_DIR_%'"; - $sql.= " AND entity = ".$conf->entity; - - dol_syslog(get_class($this)."::delete_dirs", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $this->error=$this->db->lasterror(); - $err++; - } - - return $err; - } - - /** - * Adds generic parts - * - * @return int Error count (0 if OK) - */ - function insert_module_parts() - { - global $conf; - - $error=0; - - if (is_array($this->module_parts) && ! empty($this->module_parts)) - { - foreach($this->module_parts as $key => $value) - { - if (is_array($value) && count($value) == 0) continue; // Discard empty arrays - - $entity=$conf->entity; // Reset the current entity - $newvalue = $value; - - // Serialize array parameters - if (is_array($value)) - { - // Can defined other parameters - if (is_array($value['data']) && ! empty($value['data'])) - { - $newvalue = json_encode($value['data']); - if (isset($value['entity'])) $entity = $value['entity']; - } - else if (isset($value['data']) && !is_array($value['data'])) - { - $newvalue = $value['data']; - if (isset($value['entity'])) $entity = $value['entity']; - } - else - { - $newvalue = json_encode($value); - } - } - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; - $sql.= "name"; - $sql.= ", type"; - $sql.= ", value"; - $sql.= ", note"; - $sql.= ", visible"; - $sql.= ", entity"; - $sql.= ")"; - $sql.= " VALUES ("; - $sql.= $this->db->encrypt($this->const_name."_".strtoupper($key), 1); - $sql.= ", 'chaine'"; - $sql.= ", ".$this->db->encrypt($newvalue, 1); - $sql.= ", null"; - $sql.= ", '0'"; - $sql.= ", ".$entity; - $sql.= ")"; - - dol_syslog(get_class($this)."::insert_const_".$key."", LOG_DEBUG); - $resql=$this->db->query($sql,1); - if (! $resql) - { - if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $error++; - $this->error=$this->db->lasterror(); - } - else - { - dol_syslog(get_class($this)."::insert_const_".$key." Record already exists.", LOG_WARNING); - } - } - } - } - return $error; - } - - /** - * Removes generic parts - * - * @return int Error count (0 if OK) - */ - function delete_module_parts() - { - global $conf; - - $err=0; - $entity=$conf->entity; - - if (is_array($this->module_parts) && ! empty($this->module_parts)) - { - foreach($this->module_parts as $key => $value) - { - // If entity is defined - if (is_array($value) && isset($value['entity'])) $entity = $value['entity']; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->db->escape($this->const_name)."_".strtoupper($key)."'"; - $sql.= " AND entity = ".$entity; - - dol_syslog(get_class($this)."::delete_const_".$key."", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $this->error=$this->db->lasterror(); - $err++; - } - } - } - return $err; - } + /** + * Gives the long description of a module. First check README-la_LA.md then README.md + * If not markdown files found, it return translated value of the key ->descriptionlong. + * + * @return string Long description of a module from README.md of from property. + */ + function getDescLong() + { + global $langs; + $langs->load("admin"); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; + + $pathoffile = $this->getDescLongReadmeFound(); + + if ($pathoffile) // Mostly for external modules + { + $content = file_get_contents($pathoffile); + + if ((float) DOL_VERSION >= 6.0) + { + @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; + $content = dolMd2Html($content, 'parsedown', + array( + 'doc/'=>dol_buildpath(strtolower($this->name).'/doc/', 1), + 'img/'=>dol_buildpath(strtolower($this->name).'/img/', 1), + 'images/'=>dol_buildpath(strtolower($this->name).'/imgages/', 1), + )); + } + else + { + $content = nl2br($content); + } + } + else // Mostly for internal modules + { + if (! empty($this->descriptionlong)) + { + if (is_array($this->langfiles)) + { + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } + } + + $content = $langs->trans($this->descriptionlong); + } + } + + return $content; + } + + /** + * Return path of file if a README file was found. + * + * @return string Path of file if a README file was found. + */ + function getDescLongReadmeFound() + { + $filefound= false; + + // Define path to file README.md. + // First check README-la_LA.md then README.md + $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0); + if (dol_is_file($pathoffile)) + { + $filefound = true; + } + if (! $filefound) + { + $pathoffile = dol_buildpath(strtolower($this->name).'/README.md', 0); + if (dol_is_file($pathoffile)) + { + $filefound = true; + } + } + + return ($filefound?$pathoffile:''); + } + + + /** + * Gives the changelog. First check ChangeLog-la_LA.md then ChangeLog.md + * + * @return string Content of ChangeLog + */ + function getChangeLog() + { + global $langs; + $langs->load("admin"); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; + + $filefound= false; + + // Define path to file README.md. + // First check README-la_LA.md then README.md + $pathoffile = dol_buildpath(strtolower($this->name).'/ChangeLog-'.$langs->defaultlang.'.md', 0); + if (dol_is_file($pathoffile)) + { + $filefound = true; + } + if (! $filefound) + { + $pathoffile = dol_buildpath(strtolower($this->name).'/ChangeLog.md', 0); + if (dol_is_file($pathoffile)) + { + $filefound = true; + } + } + + if ($filefound) // Mostly for external modules + { + $content = file_get_contents($pathoffile); + + if ((float) DOL_VERSION >= 6.0) + { + @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; + $content = dolMd2Html($content, 'parsedown', array('doc/'=>dol_buildpath(strtolower($this->name).'/doc/', 1))); + } + else + { + $content = nl2br($content); + } + } + + return $content; + } + + /** + * Gives the publisher name + * + * @return string Publisher name + */ + function getPublisher() + { + return $this->editor_name; + } + + /** + * Gives the publisher url + * + * @return string Publisher url + */ + function getPublisherUrl() + { + return $this->editor_url; + } + + /** + * Gives module version (translated if param $translated is on) + * For 'experimental' modules, gives 'experimental' translation + * For 'dolibarr' modules, gives Dolibarr version + * + * @param int $translated 1=Special version keys are translated, 0=Special version keys are not translated + * @return string Module version + */ + function getVersion($translated=1) + { + global $langs; + $langs->load("admin"); + + $ret=''; + + $newversion=preg_replace('/_deprecated/','',$this->version); + if ($newversion == 'experimental') $ret=($translated?$langs->trans("VersionExperimental"):$newversion); + elseif ($newversion == 'development') $ret=($translated?$langs->trans("VersionDevelopment"):$newversion); + elseif ($newversion == 'dolibarr') $ret=DOL_VERSION; + elseif ($newversion) $ret=$newversion; + else $ret=($translated?$langs->trans("VersionUnknown"):'unknown'); + + if (preg_match('/_deprecated/',$this->version)) $ret.=($translated?' ('.$langs->trans("Deprecated").')':$this->version); + return $ret; + } + + + /** + * Tells if module is core or external + * + * @return string 'core', 'external' or 'unknown' + */ + function isCoreOrExternalModule() + { + if ($this->version == 'dolibarr' || $this->version == 'dolibarr_deprecated') return 'core'; + if (! empty($this->version) && ! in_array($this->version,array('experimental','development'))) return 'external'; + if (! empty($this->editor_name) || ! empty($this->editor_url)) return 'external'; + if ($this->numero >= 100000) return 'external'; + return 'unknown'; + } + + + /** + * Gives module related language files list + * + * @return string[] Language files list + */ + function getLangFilesArray() + { + return $this->langfiles; + } + + /** + * Gives translated label of an export dataset + * + * @param int $r Dataset index + * + * @return string Translated databaset label + */ + function getExportDatasetLabel($r) + { + global $langs; + + $langstring="ExportDataset_".$this->export_code[$r]; + if ($langs->trans($langstring) == $langstring) + { + // Translation not found + return $langs->trans($this->export_label[$r]); + } + else + { + // Translation found + return $langs->trans($langstring); + } + } + + + /** + * Gives translated label of an import dataset + * + * @param int $r Dataset index + * + * @return string Translated dataset label + */ + function getImportDatasetLabel($r) + { + global $langs; + + $langstring="ImportDataset_".$this->import_code[$r]; + //print "x".$langstring; + if ($langs->trans($langstring) == $langstring) + { + // Translation not found + return $langs->trans($this->import_label[$r]); + } + else + { + // Translation found + return $langs->trans($langstring); + } + } + + + /** + * Gives the last date of activation + * + * @return timestamp Date of last activation + */ + function getLastActivationDate() + { + global $conf; + + $sql = "SELECT tms FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; + $sql.= " AND entity IN (0, ".$conf->entity.")"; + + dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; + else + { + $obj=$this->db->fetch_object($resql); + if ($obj) return $this->db->jdate($obj->tms); + } + + return ''; + } + + + /** + * Gives the last author of activation + * + * @return array Array array('authorid'=>Id of last activation user, 'lastactivationdate'=>Date of last activation) + */ + function getLastActivationInfo() + { + global $conf; + + $sql = "SELECT tms, note FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; + $sql.= " AND entity IN (0, ".$conf->entity.")"; + + dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; + else + { + $obj=$this->db->fetch_object($resql); + $tmp=array(); + if ($obj->note) + { + $tmp=json_decode($obj->note, true); + } + if ($obj) return array('authorid'=>$tmp['authorid'], 'ip'=>$tmp['ip'], 'lastactivationdate'=>$this->db->jdate($obj->tms)); + } + + return array(); + } + + + /** + * Insert constants for module activation + * + * @return int Error count (0 if OK) + */ + function _active() + { + global $conf, $user; + + $err = 0; + + // Common module + $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; + $sql.= " AND entity IN (0, ".$entity.")"; + + dol_syslog(get_class($this)."::_active", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; + + $note=json_encode(array('authorid'=>(is_object($user)?$user->id:0), 'ip'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR']))); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name, value, visible, entity, note) VALUES"; + $sql.= " (".$this->db->encrypt($this->const_name,1); + $sql.= ", ".$this->db->encrypt('1',1); + $sql.= ", 0, ".$entity; + $sql.= ", '".$this->db->escape($note)."')"; + + dol_syslog(get_class($this)."::_active", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; + + return $err; + } + + + /** + * Module deactivation + * + * @return int Error count (0 if OK) + */ + function _unactive() + { + global $conf; + + $err = 0; + + // Common module + $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; + $sql.= " AND entity IN (0, ".$entity.")"; + + dol_syslog(get_class($this)."::_unactive", LOG_DEBUG); + $this->db->query($sql); + + return $err; + } + + + /** + * Create tables and keys required by module. + * Files module.sql and module.key.sql with create table and create keys + * commands must be stored in directory reldir='/module/sql/' + * This function is called by this->init + * + * @param string $reldir Relative directory where to scan files + * @return int <=0 if KO, >0 if OK + */ + function _load_tables($reldir) + { + global $conf; + + $error=0; + $dirfound=0; + + if (empty($reldir)) return 1; + + include_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; + + $ok = 1; + foreach($conf->file->dol_document_root as $dirroot) + { + if ($ok) + { + $dir = $dirroot.$reldir; + $ok = 0; + + $handle=@opendir($dir); // Dir may not exists + if (is_resource($handle)) + { + $dirfound++; + + // Run llx_mytable.sql files, then llx_mytable_*.sql + $files = array(); + while (($file = readdir($handle))!==false) + { + $files[] = $file; + } + sort($files); + foreach ($files as $file) + { + if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') + { + $result=run_sql($dir.$file,1,'',1); + if ($result <= 0) $error++; + } + } + + rewinddir($handle); + + // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) then then llx_mytable_*.key.sql + $files = array(); + while (($file = readdir($handle))!==false) + { + $files[] = $file; + } + sort($files); + foreach ($files as $file) + { + if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') + { + $result=run_sql($dir.$file,1,'',1); + if ($result <= 0) $error++; + } + } + + rewinddir($handle); + + // Run data_xxx.sql files (Must be done after llx_mytable.key.sql) + $files = array(); + while (($file = readdir($handle))!==false) + { + $files[] = $file; + } + sort($files); + foreach ($files as $file) + { + if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data') + { + $result=run_sql($dir.$file,1,'',1); + if ($result <= 0) $error++; + } + } + + rewinddir($handle); + + // Run update_xxx.sql files + $files = array(); + while (($file = readdir($handle))!==false) + { + $files[] = $file; + } + sort($files); + foreach ($files as $file) + { + if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update') + { + $result=run_sql($dir.$file,1,'',1); + if ($result <= 0) $error++; + } + } + + closedir($handle); + } + + if ($error == 0) + { + $ok = 1; + } + } + } + + if (! $dirfound) dol_syslog("A module ask to load sql files into ".$reldir." but this directory was not found.", LOG_WARNING); + return $ok; + } + + + /** + * Adds boxes + * + * @param string $option Options when disabling module ('newboxdefonly'=insert only boxes definition) + * + * @return int Error count (0 if OK) + */ + function insert_boxes($option='') + { + require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; + + global $conf; + + $err=0; + + if (is_array($this->boxes)) + { + $pos_name = InfoBox::getListOfPagesForBoxes(); + + foreach ($this->boxes as $key => $value) + { + $file = isset($this->boxes[$key]['file'])?$this->boxes[$key]['file']:''; + $note = isset($this->boxes[$key]['note'])?$this->boxes[$key]['note']:''; + $enabledbydefaulton = isset($this->boxes[$key]['enabledbydefaulton'])?$this->boxes[$key]['enabledbydefaulton']:'Home'; + + if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility + if (empty($note)) $note = isset($this->boxes[$key][2])?$this->boxes[$key][2]:''; // For backward compatibility + + // Search if boxes def already present + $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."boxes_def"; + $sql.= " WHERE file = '".$this->db->escape($file)."'"; + $sql.= " AND entity = ".$conf->entity; + if ($note) $sql.=" AND note ='".$this->db->escape($note)."'"; + + dol_syslog(get_class($this)."::insert_boxes", LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj->nb == 0) + { + $this->db->begin(); + + if (! $err) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes_def (file, entity, note)"; + $sql.= " VALUES ('".$this->db->escape($file)."', "; + $sql.= $conf->entity.", "; + $sql.= $note?"'".$this->db->escape($note)."'":"null"; + $sql.= ")"; + + dol_syslog(get_class($this)."::insert_boxes", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; + + } + if (! $err && ! preg_match('/newboxdefonly/',$option)) + { + $lastid=$this->db->last_insert_id(MAIN_DB_PREFIX."boxes_def","rowid"); + + foreach ($pos_name as $key2 => $val2) + { + //print 'key2='.$key2.'-val2='.$val2."<br>\n"; + if ($enabledbydefaulton && $val2 != $enabledbydefaulton) continue; // Not enabled by default onto this page. + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes (box_id,position,box_order,fk_user,entity)"; + $sql.= " VALUES (".$lastid.", ".$key2.", '0', 0, ".$conf->entity.")"; + + dol_syslog(get_class($this)."::insert_boxes onto page ".$key2."=".$val2."", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; + } + } + + if (! $err) + { + $this->db->commit(); + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + } + } + // else box already registered into database + } + else + { + $this->error=$this->db->lasterror(); + $err++; + } + } + } + + return $err; + } + + + /** + * Removes boxes + * + * @return int Error count (0 if OK) + */ + function delete_boxes() + { + global $conf; + + $err=0; + + if (is_array($this->boxes)) + { + foreach ($this->boxes as $key => $value) + { + //$titre = $this->boxes[$key][0]; + $file = $this->boxes[$key]['file']; + //$note = $this->boxes[$key][2]; + + // TODO If the box is also included by another module and the other module is still on, we should not remove it. + // For the moment, we manage this with hard coded exception + //print "Remove box ".$file.'<br>'; + if ($file == 'box_graph_product_distribution.php') + { + if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) + { + dol_syslog("We discard disabling of module ".$file." because another module still active require it."); + continue; + } + } + + if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility + + if ($this->db->type == 'sqlite3') { + // sqlite doesn't support "USING" syntax. + // TODO: remove this dependency. + $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes "; + $sql .= "WHERE ".MAIN_DB_PREFIX."boxes.box_id IN ("; + $sql .= "SELECT ".MAIN_DB_PREFIX."boxes_def.rowid "; + $sql .= "FROM ".MAIN_DB_PREFIX."boxes_def "; + $sql .= "WHERE ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."') "; + $sql .= "AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + } else { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; + $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def"; + $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid"; + $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'"; + $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + } + + dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $err++; + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes_def"; + $sql.= " WHERE file = '".$this->db->escape($file)."'"; + $sql.= " AND entity = ".$conf->entity; + + dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $err++; + } + } + } + + return $err; + } + + /** + * Adds cronjobs + * + * @return int Error count (0 if OK) + */ + function insert_cronjobs() + { + require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; + + global $conf; + + $err=0; + + if (is_array($this->cronjobs)) + { + foreach ($this->cronjobs as $key => $value) + { + $label = isset($this->cronjobs[$key]['label'])?$this->cronjobs[$key]['label']:''; + $jobtype = isset($this->cronjobs[$key]['jobtype'])?$this->cronjobs[$key]['jobtype']:''; + $class = isset($this->cronjobs[$key]['class'])?$this->cronjobs[$key]['class']:''; + $objectname = isset($this->cronjobs[$key]['objectname'])?$this->cronjobs[$key]['objectname']:''; + $method = isset($this->cronjobs[$key]['method'])?$this->cronjobs[$key]['method']:''; + $command = isset($this->cronjobs[$key]['command'])?$this->cronjobs[$key]['command']:''; + $parameters = isset($this->cronjobs[$key]['parameters'])?$this->cronjobs[$key]['parameters']:''; + $comment = isset($this->cronjobs[$key]['comment'])?$this->cronjobs[$key]['comment']:''; + $frequency = isset($this->cronjobs[$key]['frequency'])?$this->cronjobs[$key]['frequency']:''; + $unitfrequency = isset($this->cronjobs[$key]['unitfrequency'])?$this->cronjobs[$key]['unitfrequency']:''; + $status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:''; + $priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:''; + $test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:''; // Line must be visible + + // Search if boxes def already present + $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob"; + $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'"; + if ($class) $sql.= " AND classesname = '".$this->db->escape($class)."'"; + if ($objectname) $sql.= " AND objectname = '".$this->db->escape($objectname)."'"; + if ($method) $sql.= " AND methodename = '".$this->db->escape($method)."'"; + if ($command) $sql.= " AND command = '".$this->db->escape($command)."'"; + $sql.= " AND entity = ".$conf->entity; + + $now=dol_now(); + + dol_syslog(get_class($this)."::insert_cronjobs", LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj->nb == 0) + { + $this->db->begin(); + + if (! $err) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note,"; + if(is_int($frequency)){ $sql.= ' frequency,'; } + if(is_int($unitfrequency)){ $sql.= ' unitfrequency,'; } + if(is_int($priority)){ $sql.= ' priority,'; } + if(is_int($status)){ $sql.= ' status,'; } + $sql.= " entity, test)"; + $sql.= " VALUES ("; + $sql.= "'".$this->db->escape($this->rights_class)."', "; + $sql.= "'".$this->db->idate($now)."', "; + $sql.= "'".$this->db->idate($now)."', "; + $sql.= "'".$this->db->escape($label)."', "; + $sql.= "'".$this->db->escape($jobtype)."', "; + $sql.= ($class?"'".$this->db->escape($class)."'":"null").","; + $sql.= ($objectname?"'".$this->db->escape($objectname)."'":"null").","; + $sql.= ($method?"'".$this->db->escape($method)."'":"null").","; + $sql.= ($command?"'".$this->db->escape($command)."'":"null").","; + $sql.= ($parameters?"'".$this->db->escape($parameters)."'":"null").","; + $sql.= ($comment?"'".$this->db->escape($comment)."'":"null").","; + if(is_int($frequency)){ $sql.= "'".$this->db->escape($frequency)."', "; } + if(is_int($unitfrequency)){ $sql.= "'".$this->db->escape($unitfrequency)."', "; } + if(is_int($priority)) {$sql.= "'".$this->db->escape($priority)."', ";} + if(is_int($status)){ $sql.= "'".$this->db->escape($status)."', "; } + $sql.= $conf->entity.","; + $sql.= "'".$this->db->escape($test)."'"; + $sql.= ")"; + + dol_syslog(get_class($this)."::insert_cronjobs", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; + + } + + if (! $err) + { + $this->db->commit(); + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + } + } + // else box already registered into database + } + else + { + $this->error=$this->db->lasterror(); + $err++; + } + } + } + + return $err; + } + + + /** + * Removes boxes + * + * @return int Error count (0 if OK) + */ + function delete_cronjobs() + { + global $conf; + + $err=0; + + if (is_array($this->cronjobs)) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."cronjob"; + $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'"; + $sql.= " AND entity = ".$conf->entity; + + dol_syslog(get_class($this)."::delete_cronjobs", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $err++; + } + } + + return $err; + } + + /** + * Removes tabs + * + * @return int Error count (0 if OK) + */ + function delete_tabs() + { + global $conf; + + $err=0; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." like '".$this->db->escape($this->const_name)."_TABS_%'"; + $sql.= " AND entity = ".$conf->entity; + + dol_syslog(get_class($this)."::delete_tabs", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $this->error=$this->db->lasterror(); + $err++; + } + + return $err; + } + + /** + * Adds tabs + * + * @return int Error count (0 if ok) + */ + function insert_tabs() + { + global $conf; + + $err=0; + + if (! empty($this->tabs)) + { + $i=0; + foreach ($this->tabs as $key => $value) + { + if (is_array($value) && count($value) == 0) continue; // Discard empty arrays + + $entity=$conf->entity; + $newvalue = $value; + + if (is_array($value)) + { + $newvalue = $value['data']; + if (isset($value['entity'])) $entity = $value['entity']; + } + + if ($newvalue) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; + $sql.= "name"; + $sql.= ", type"; + $sql.= ", value"; + $sql.= ", note"; + $sql.= ", visible"; + $sql.= ", entity"; + $sql.= ")"; + $sql.= " VALUES ("; + $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1); + $sql.= ", 'chaine'"; + $sql.= ", ".$this->db->encrypt($newvalue,1); + $sql.= ", null"; + $sql.= ", '0'"; + $sql.= ", ".$entity; + $sql.= ")"; + + dol_syslog(get_class($this)."::insert_tabs", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) + { + dol_syslog($this->db->lasterror(), LOG_ERR); + if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + $err++; + break; + } + } + } + $i++; + } + } + return $err; + } + + /** + * Adds constants + * + * @return int Error count (0 if OK) + */ + function insert_const() + { + global $conf; + + $err=0; + + if (empty($this->const)) return 0; + + foreach ($this->const as $key => $value) + { + $name = $this->const[$key][0]; + $type = $this->const[$key][1]; + $val = $this->const[$key][2]; + $note = isset($this->const[$key][3])?$this->const[$key][3]:''; + $visible = isset($this->const[$key][4])?$this->const[$key][4]:0; + $entity = (! empty($this->const[$key][5]) && $this->const[$key][5]!='current')?0:$conf->entity; + + // Clean + if (empty($visible)) $visible='0'; + if (empty($val) && $val != '0') $val=''; + + $sql = "SELECT count(*)"; + $sql.= " FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($name)."'"; + $sql.= " AND entity = ".$entity; + + $result=$this->db->query($sql); + if ($result) + { + $row = $this->db->fetch_row($result); + + if ($row[0] == 0) // If not found + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)"; + $sql.= " VALUES ("; + $sql.= $this->db->encrypt($name,1); + $sql.= ",'".$type."'"; + $sql.= ",".(($val != '')?$this->db->encrypt($val,1):"''"); + $sql.= ",".($note?"'".$this->db->escape($note)."'":"null"); + $sql.= ",'".$visible."'"; + $sql.= ",".$entity; + $sql.= ")"; + + + dol_syslog(get_class($this)."::insert_const", LOG_DEBUG); + if (! $this->db->query($sql) ) + { + $err++; + } + } + else + { + dol_syslog(get_class($this)."::insert_const constant '".$name."' already exists", LOG_WARNING); + } + } + else + { + $err++; + } + } + + return $err; + } + + /** + * Removes constants tagged 'deleteonunactive' + * + * @return int <0 if KO, 0 if OK + */ + function delete_const() + { + global $conf; + + $err=0; + + if (empty($this->const)) return 0; + + foreach ($this->const as $key => $value) + { + $name = $this->const[$key][0]; + $deleteonunactive = (! empty($this->const[$key][6]))?1:0; + + if ($deleteonunactive) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'"; + $sql.= " AND entity in (0, ".$conf->entity.")"; + dol_syslog(get_class($this)."::delete_const", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $this->error=$this->db->lasterror(); + $err++; + } + } + } + + return $err; + } + + /** + * Adds access rights + * + * @param int $reinitadminperms If 1, we also grant them to all admin users + * @param int $force_entity Force current entity + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int Error count (0 if OK) + */ + function insert_permissions($reinitadminperms=0, $force_entity=null, $notrigger=0) + { + global $conf,$user; + + $err=0; + $entity=(! empty($force_entity) ? $force_entity : $conf->entity); + + // Test if module is activated + $sql_del = "SELECT ".$this->db->decrypt('value')." as value"; + $sql_del.= " FROM ".MAIN_DB_PREFIX."const"; + $sql_del.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; + $sql_del.= " AND entity IN (0,".$entity.")"; + + dol_syslog(get_class($this)."::insert_permissions", LOG_DEBUG); + $resql=$this->db->query($sql_del); + + if ($resql) + { + $obj=$this->db->fetch_object($resql); + if ($obj !== null && ! empty($obj->value) && ! empty($this->rights)) + { + // If the module is active + foreach ($this->rights as $key => $value) + { + $r_id = $this->rights[$key][0]; + $r_desc = $this->rights[$key][1]; + $r_type = isset($this->rights[$key][2])?$this->rights[$key][2]:''; + $r_def = $this->rights[$key][3]; + $r_perms = $this->rights[$key][4]; + $r_subperms = isset($this->rights[$key][5])?$this->rights[$key][5]:''; + $r_modul = $this->rights_class; + + if (empty($r_type)) $r_type='w'; + + // Search if perm already present + $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."rights_def"; + $sql.= " WHERE id = ".$r_id." AND entity = ".$entity; + $resqlselect=$this->db->query($sql); + + $obj = $this->db->fetch_object($resqlselect); + if ($obj->nb == 0) + { + if (dol_strlen($r_perms) ) + { + if (dol_strlen($r_subperms) ) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; + $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)"; + $sql.= " VALUES "; + $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')"; + } + else + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; + $sql.= " (id, entity, libelle, module, type, bydefault, perms)"; + $sql.= " VALUES "; + $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')"; + } + } + else + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def "; + $sql .= " (id, entity, libelle, module, type, bydefault)"; + $sql .= " VALUES "; + $sql .= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")"; + } + + $resqlinsert=$this->db->query($sql,1); + + if (! $resqlinsert) + { + if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS") + { + $this->error=$this->db->lasterror(); + $err++; + break; + } + else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO); + + } + + $this->db->free($resqlinsert); + } + + $this->db->free($resqlselect); + + // If we want to init permissions on admin users + if ($reinitadminperms) + { + if (! class_exists('User')) { + require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; + } + $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."user WHERE admin = 1"; + dol_syslog(get_class($this)."::insert_permissions Search all admin users", LOG_DEBUG); + $resqlseladmin=$this->db->query($sql,1); + if ($resqlseladmin) + { + $num=$this->db->num_rows($resqlseladmin); + $i=0; + while ($i < $num) + { + $obj2=$this->db->fetch_object($resqlseladmin); + dol_syslog(get_class($this)."::insert_permissions Add permission to user id=".$obj2->rowid); + $tmpuser=new User($this->db); + $tmpuser->fetch($obj2->rowid); + if (!empty($tmpuser->id)) { + $tmpuser->addrights($r_id, '', '', 0, 1); + } + $i++; + } + if (! empty($user->admin)) // Reload permission for current user if defined + { + // We reload permissions + $user->clearrights(); + $user->getrights(); + } + } + else dol_print_error($this->db); + } + } + } + $this->db->free($resql); + } + else + { + $this->error=$this->db->lasterror(); + $err++; + } + + return $err; + } + + + /** + * Removes access rights + * + * @return int Error count (0 if OK) + */ + function delete_permissions() + { + global $conf; + + $err=0; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."rights_def"; + $sql.= " WHERE module = '".$this->db->escape($this->rights_class)."'"; + $sql.= " AND entity = ".$conf->entity; + dol_syslog(get_class($this)."::delete_permissions", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $this->error=$this->db->lasterror(); + $err++; + } + + return $err; + } + + + /** + * Adds menu entries + * + * @return int Error count (0 if OK) + */ + function insert_menus() + { + global $user; + + if (! is_array($this->menu) || empty($this->menu)) return 0; + + require_once DOL_DOCUMENT_ROOT . '/core/class/menubase.class.php'; + + $err=0; + + $this->db->begin(); + + foreach ($this->menu as $key => $value) + { + $menu = new Menubase($this->db); + $menu->menu_handler='all'; + $menu->module=$this->rights_class; + if (! $this->menu[$key]['fk_menu']) + { + $menu->fk_menu=0; + } + else + { + $foundparent=0; + $fk_parent=$this->menu[$key]['fk_menu']; + if (preg_match('/^r=/',$fk_parent)) // old deprecated method + { + $fk_parent=str_replace('r=','',$fk_parent); + if (isset($this->menu[$fk_parent]['rowid'])) + { + $menu->fk_menu=$this->menu[$fk_parent]['rowid']; + $foundparent=1; + } + } + elseif (preg_match('/^fk_mainmenu=([a-zA-Z0-9_]+),fk_leftmenu=([a-zA-Z0-9_]+)$/',$fk_parent,$reg)) + { + $menu->fk_menu=-1; + $menu->fk_mainmenu=$reg[1]; + $menu->fk_leftmenu=$reg[2]; + $foundparent=1; + } + elseif (preg_match('/^fk_mainmenu=([a-zA-Z0-9_]+)$/',$fk_parent,$reg)) + { + $menu->fk_menu=-1; + $menu->fk_mainmenu=$reg[1]; + $menu->fk_leftmenu=''; + $foundparent=1; + } + if (! $foundparent) + { + $this->error="ErrorBadDefinitionOfMenuArrayInModuleDescriptor"; + dol_syslog(get_class($this)."::insert_menus ".$this->error." ".$this->menu[$key]['fk_menu'], LOG_ERR); + $err++; + } + } + $menu->type=$this->menu[$key]['type']; + $menu->mainmenu=isset($this->menu[$key]['mainmenu'])?$this->menu[$key]['mainmenu']:(isset($menu->fk_mainmenu)?$menu->fk_mainmenu:''); + $menu->leftmenu=isset($this->menu[$key]['leftmenu'])?$this->menu[$key]['leftmenu']:''; + $menu->titre=$this->menu[$key]['titre']; + $menu->url=$this->menu[$key]['url']; + $menu->langs=$this->menu[$key]['langs']; + $menu->position=$this->menu[$key]['position']; + $menu->perms=$this->menu[$key]['perms']; + $menu->target=$this->menu[$key]['target']; + $menu->user=$this->menu[$key]['user']; + $menu->enabled=isset($this->menu[$key]['enabled'])?$this->menu[$key]['enabled']:0; + $menu->position=$this->menu[$key]['position']; + + if (! $err) + { + $result=$menu->create($user); // Save menu entry into table llx_menu + if ($result > 0) + { + $this->menu[$key]['rowid']=$result; + } + else + { + $this->error=$menu->error; + dol_syslog(get_class($this).'::insert_menus result='.$result." ".$this->error, LOG_ERR); + $err++; + break; + } + } + } + + if (! $err) + { + $this->db->commit(); + } + else + { + dol_syslog(get_class($this)."::insert_menus ".$this->error, LOG_ERR); + $this->db->rollback(); + } + + return $err; + } + + + /** + * Removes menu entries + * + * @return int Error count (0 if OK) + */ + function delete_menus() + { + global $conf; + + $err=0; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."menu"; + $sql.= " WHERE module = '".$this->db->escape($this->rights_class)."'"; + $sql.= " AND entity = ".$conf->entity; + + dol_syslog(get_class($this)."::delete_menus", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $err++; + } + + return $err; + } + + /** + * Creates directories + * + * @return int Error count (0 if OK) + */ + function create_dirs() + { + global $langs, $conf; + + $err=0; + + if (isset($this->dirs) && is_array($this->dirs)) + { + foreach ($this->dirs as $key => $value) + { + $addtodatabase=0; + + if (! is_array($value)) $dir=$value; // Default simple mode + else { + $constname = $this->const_name."_DIR_"; + $dir = $this->dirs[$key][1]; + $addtodatabase = empty($this->dirs[$key][2])?'':$this->dirs[$key][2]; // Create constante in llx_const + $subname = empty($this->dirs[$key][3])?'':strtoupper($this->dirs[$key][3]); // Add submodule name (ex: $conf->module->submodule->dir_output) + $forcename = empty($this->dirs[$key][4])?'':strtoupper($this->dirs[$key][4]); // Change the module name if different + + if (! empty($forcename)) $constname = 'MAIN_MODULE_'.$forcename."_DIR_"; + if (! empty($subname)) $constname = $constname.$subname."_"; + + $name = $constname.strtoupper($this->dirs[$key][0]); + } + + // Define directory full path ($dir must start with "/") + if (empty($conf->global->MAIN_MODULE_MULTICOMPANY) || $conf->entity == 1) $fulldir = DOL_DATA_ROOT.$dir; + else $fulldir = DOL_DATA_ROOT."/".$conf->entity.$dir; + // Create dir if it does not exists + if (! empty($fulldir) && ! file_exists($fulldir)) + { + if (dol_mkdir($fulldir, DOL_DATA_ROOT) < 0) + { + $this->error = $langs->trans("ErrorCanNotCreateDir",$fulldir); + dol_syslog(get_class($this)."::_init ".$this->error, LOG_ERR); + $err++; + } + } + + // Define the constant in database if requested (not the default mode) + if (! empty($addtodatabase)) + { + $result = $this->insert_dirs($name, $dir); + if ($result) $err++; + } + } + } + + return $err; + } + + + /** + * Adds directories definitions + * + * @param string $name Name + * @param string $dir Directory + * + * @return int Error count (0 if OK) + */ + function insert_dirs($name,$dir) + { + global $conf; + + $err=0; + + $sql = "SELECT count(*)"; + $sql.= " FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'"; + $sql.= " AND entity = ".$conf->entity; + + dol_syslog(get_class($this)."::insert_dirs", LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + $row = $this->db->fetch_row($result); + + if ($row[0] == 0) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)"; + $sql.= " VALUES (".$this->db->encrypt($name,1).",'chaine',".$this->db->encrypt($dir,1).",'Directory for module ".$this->name."','0',".$conf->entity.")"; + + dol_syslog(get_class($this)."::insert_dirs", LOG_DEBUG); + $this->db->query($sql); + } + } + else + { + $this->error=$this->db->lasterror(); + $err++; + } + + return $err; + } + + + /** + * Removes directories + * + * @return int Error count (0 if OK) + */ + function delete_dirs() + { + global $conf; + + $err=0; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->db->escape($this->const_name)."_DIR_%'"; + $sql.= " AND entity = ".$conf->entity; + + dol_syslog(get_class($this)."::delete_dirs", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $this->error=$this->db->lasterror(); + $err++; + } + + return $err; + } + + /** + * Adds generic parts + * + * @return int Error count (0 if OK) + */ + function insert_module_parts() + { + global $conf; + + $error=0; + + if (is_array($this->module_parts) && ! empty($this->module_parts)) + { + foreach($this->module_parts as $key => $value) + { + if (is_array($value) && count($value) == 0) continue; // Discard empty arrays + + $entity=$conf->entity; // Reset the current entity + $newvalue = $value; + + // Serialize array parameters + if (is_array($value)) + { + // Can defined other parameters + if (is_array($value['data']) && ! empty($value['data'])) + { + $newvalue = json_encode($value['data']); + if (isset($value['entity'])) $entity = $value['entity']; + } + else if (isset($value['data']) && !is_array($value['data'])) + { + $newvalue = $value['data']; + if (isset($value['entity'])) $entity = $value['entity']; + } + else + { + $newvalue = json_encode($value); + } + } + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; + $sql.= "name"; + $sql.= ", type"; + $sql.= ", value"; + $sql.= ", note"; + $sql.= ", visible"; + $sql.= ", entity"; + $sql.= ")"; + $sql.= " VALUES ("; + $sql.= $this->db->encrypt($this->const_name."_".strtoupper($key), 1); + $sql.= ", 'chaine'"; + $sql.= ", ".$this->db->encrypt($newvalue, 1); + $sql.= ", null"; + $sql.= ", '0'"; + $sql.= ", ".$entity; + $sql.= ")"; + + dol_syslog(get_class($this)."::insert_const_".$key."", LOG_DEBUG); + $resql=$this->db->query($sql,1); + if (! $resql) + { + if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $error++; + $this->error=$this->db->lasterror(); + } + else + { + dol_syslog(get_class($this)."::insert_const_".$key." Record already exists.", LOG_WARNING); + } + } + } + } + return $error; + } + + /** + * Removes generic parts + * + * @return int Error count (0 if OK) + */ + function delete_module_parts() + { + global $conf; + + $err=0; + $entity=$conf->entity; + + if (is_array($this->module_parts) && ! empty($this->module_parts)) + { + foreach($this->module_parts as $key => $value) + { + // If entity is defined + if (is_array($value) && isset($value['entity'])) $entity = $value['entity']; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->db->escape($this->const_name)."_".strtoupper($key)."'"; + $sql.= " AND entity = ".$entity; + + dol_syslog(get_class($this)."::delete_const_".$key."", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $this->error=$this->db->lasterror(); + $err++; + } + } + } + return $err; + } /** * Function called when module is enabled. @@ -2148,8 +2148,8 @@ class DolibarrModules // Can not be abstract, because we need to insta * It also creates data directories * * @param string $options Options when enabling module ('', 'newboxdefonly', 'noboxes') - * 'noboxes' = Do not insert boxes - * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation + * 'noboxes' = Do not insert boxes + * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation * @return int 1 if OK, 0 if KO */ public function init($options = '') diff --git a/htdocs/core/modules/dons/html_cerfafr.modules.php b/htdocs/core/modules/dons/html_cerfafr.modules.php index f3e0146a719805c49de0b3ec95ab1fb7382c937e..0f7f2aa2c365fbf6ae6a5c3c5fd90d8bab2c7def 100644 --- a/htdocs/core/modules/dons/html_cerfafr.modules.php +++ b/htdocs/core/modules/dons/html_cerfafr.modules.php @@ -35,22 +35,22 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; */ class html_cerfafr extends ModeleDon { - /** - * Constructor - * - * @param DoliDb $db Database handler - */ - function __construct($db) - { - global $conf,$langs; + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + function __construct($db) + { + global $conf,$langs; - $this->db = $db; - $this->name = "cerfafr"; - $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*03'; + $this->db = $db; + $this->name = "cerfafr"; + $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*03'; - // Dimension page for size A4 - $this->type = 'html'; - } + // Dimension page for size A4 + $this->type = 'html'; + } /** @@ -64,16 +64,16 @@ class html_cerfafr extends ModeleDon } - /** - * Write the object to document file to disk - * - * @param Don $don Donation object - * @param Translate $outputlangs Lang object for output language + /** + * Write the object to document file to disk + * + * @param Don $don Donation object + * @param Translate $outputlangs Lang object for output language * @param string $currency Currency code - * @return int >0 if OK, <0 if KO - */ - function write_file($don,$outputlangs,$currency='') - { + * @return int >0 if OK, <0 if KO + */ + function write_file($don,$outputlangs,$currency='') + { global $user,$conf,$langs,$mysoc; $now=dol_now(); @@ -91,13 +91,13 @@ class html_cerfafr extends ModeleDon $currency = !empty($currency) ? $currency : $conf->currency; if (! empty($conf->don->dir_output)) - { + { // Definition of the object don (for upward compatibility) - if (! is_object($don)) - { - $don = new Don($this->db); - $ret=$don->fetch($id); - $id=$don->id; + if (! is_object($don)) + { + $don = new Don($this->db); + $ret=$don->fetch($id); + $id=$don->id; } // Definition of $dir and $file @@ -113,27 +113,27 @@ class html_cerfafr extends ModeleDon $file = $dir . "/" . $donref . ".html"; } - if (! file_exists($dir)) - { - if (dol_mkdir($dir) < 0) - { - $this->error=$langs->trans("ErrorCanNotCreateDir",$dir); - return -1; - } - } + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->trans("ErrorCanNotCreateDir",$dir); + return -1; + } + } - if (file_exists($dir)) - { - $formclass = new Form($this->db); + if (file_exists($dir)) + { + $formclass = new Form($this->db); - // This is not the proper way to do it but $formclass->form_modes_reglement - // prints the translation instead of returning it - if ($don->modepaiementid) - { - $formclass->load_cache_types_paiements(); - $paymentmode = $formclass->cache_types_paiements[$don->modepaiementid]['label']; - } - else $paymentmode = ''; + // This is not the proper way to do it but $formclass->form_modes_reglement + // prints the translation instead of returning it + if ($don->modepaiementid) + { + $formclass->load_cache_types_paiements(); + $paymentmode = $formclass->cache_types_paiements[$don->modepaiementid]['label']; + } + else $paymentmode = ''; if ($don->modepaiementid==7){ $ModePaiement = '<td width="25%"><input type="checkbox"> Remise d\'espèces</td><td width="25%"><input type="checkbox" disabled="true" checked="checked"> Chèque</td><td width="50%"><input type="checkbox"> Virement, prélèvement, carte bancaire</td>'; @@ -160,52 +160,52 @@ class html_cerfafr extends ModeleDon } */ - // Define contents - $donmodel=DOL_DOCUMENT_ROOT ."/core/modules/dons/html_cerfafr.html"; - $form = implode('', file($donmodel)); - $form = str_replace('__REF__',$don->id,$form); - $form = str_replace('__DATE__',dol_print_date($don->date,'day',false,$outputlangs),$form); - //$form = str_replace('__IP__',$user->ip,$form); // TODO $user->ip not exist - $form = str_replace('__AMOUNT__',$don->amount,$form); + // Define contents + $donmodel=DOL_DOCUMENT_ROOT ."/core/modules/dons/html_cerfafr.html"; + $form = implode('', file($donmodel)); + $form = str_replace('__REF__',$don->id,$form); + $form = str_replace('__DATE__',dol_print_date($don->date,'day',false,$outputlangs),$form); + //$form = str_replace('__IP__',$user->ip,$form); // TODO $user->ip not exist + $form = str_replace('__AMOUNT__',$don->amount,$form); $form = str_replace('__AMOUNTLETTERS__',chiffre_en_lettre($don->amount),$form); - $form = str_replace('__CURRENCY__',$outputlangs->transnoentitiesnoconv("Currency".$currency),$form); - $form = str_replace('__CURRENCYCODE__',$conf->currency,$form); - $form = str_replace('__MAIN_INFO_SOCIETE_NOM__',$mysoc->name,$form); - $form = str_replace('__MAIN_INFO_SOCIETE_ADDRESS__',$mysoc->address,$form); - $form = str_replace('__MAIN_INFO_SOCIETE_ZIP__',$mysoc->zip,$form); - $form = str_replace('__MAIN_INFO_SOCIETE_TOWN__',$mysoc->town,$form); + $form = str_replace('__CURRENCY__',$outputlangs->transnoentitiesnoconv("Currency".$currency),$form); + $form = str_replace('__CURRENCYCODE__',$conf->currency,$form); + $form = str_replace('__MAIN_INFO_SOCIETE_NOM__',$mysoc->name,$form); + $form = str_replace('__MAIN_INFO_SOCIETE_ADDRESS__',$mysoc->address,$form); + $form = str_replace('__MAIN_INFO_SOCIETE_ZIP__',$mysoc->zip,$form); + $form = str_replace('__MAIN_INFO_SOCIETE_TOWN__',$mysoc->town,$form); $form = str_replace('__MAIN_INFO_SOCIETE_OBJECT__',$mysoc->object,$form); $form = str_replace('__DONATOR_FIRSTNAME__',$don->firstname,$form); - $form = str_replace('__DONATOR_LASTNAME__',$don->lastname,$form); + $form = str_replace('__DONATOR_LASTNAME__',$don->lastname,$form); $form = str_replace('__DONATOR_SOCIETE__',$don->societe,$form); $form = str_replace('__DONATOR_STATUT__',$don->statut,$form); - $form = str_replace('__DONATOR_ADDRESS__',$don->address,$form); - $form = str_replace('__DONATOR_ZIP__',$don->zip,$form); - $form = str_replace('__DONATOR_TOWN__',$don->town,$form); - $form = str_replace('__PAYMENTMODE_LIB__ ', $paymentmode,$form); + $form = str_replace('__DONATOR_ADDRESS__',$don->address,$form); + $form = str_replace('__DONATOR_ZIP__',$don->zip,$form); + $form = str_replace('__DONATOR_TOWN__',$don->town,$form); + $form = str_replace('__PAYMENTMODE_LIB__ ', $paymentmode,$form); $form = str_replace('__ModePaiement__', $ModePaiement,$form); - $form = str_replace('__NOW__',dol_print_date($now,'day',false,$outputlangs),$form); - $form = str_replace('__DonationRef__',$outputlangs->trans("DonationRef"),$form); + $form = str_replace('__NOW__',dol_print_date($now,'day',false,$outputlangs),$form); + $form = str_replace('__DonationRef__',$outputlangs->trans("DonationRef"),$form); $form = str_replace('__DonationTitle__',$outputlangs->trans("DonationTitle"),$form); - $form = str_replace('__DonationReceipt__',$outputlangs->trans("DonationReceipt"),$form); - $form = str_replace('__DonationRecipient__',$outputlangs->trans("DonationRecipient"),$form); - $form = str_replace('__DonationDatePayment__',$outputlangs->trans("DonationDatePayment"),$form); + $form = str_replace('__DonationReceipt__',$outputlangs->trans("DonationReceipt"),$form); + $form = str_replace('__DonationRecipient__',$outputlangs->trans("DonationRecipient"),$form); + $form = str_replace('__DonationDatePayment__',$outputlangs->trans("DonationDatePayment"),$form); $form = str_replace('__PaymentMode__',$outputlangs->trans("PaymentMode"),$form); // $form = str_replace('__CodeDon__',$CodeDon,$form); - $form = str_replace('__Name__',$outputlangs->trans("Name"),$form); - $form = str_replace('__Address__',$outputlangs->trans("Address"),$form); - $form = str_replace('__Zip__',$outputlangs->trans("Zip"),$form); - $form = str_replace('__Town__',$outputlangs->trans("Town"),$form); + $form = str_replace('__Name__',$outputlangs->trans("Name"),$form); + $form = str_replace('__Address__',$outputlangs->trans("Address"),$form); + $form = str_replace('__Zip__',$outputlangs->trans("Zip"),$form); + $form = str_replace('__Town__',$outputlangs->trans("Town"),$form); $form = str_replace('__Object__',$outputlangs->trans("Object"),$form); - $form = str_replace('__Donor__',$outputlangs->trans("Donor"),$form); - $form = str_replace('__Date__',$outputlangs->trans("Date"),$form); - $form = str_replace('__Signature__',$outputlangs->trans("Signature"),$form); - $form = str_replace('__Message__',$outputlangs->trans("Message"),$form); - $form = str_replace('__IConfirmDonationReception__',$outputlangs->trans("IConfirmDonationReception"),$form); - $form = str_replace('__DonationMessage__',$conf->global->DONATION_MESSAGE,$form); + $form = str_replace('__Donor__',$outputlangs->trans("Donor"),$form); + $form = str_replace('__Date__',$outputlangs->trans("Date"),$form); + $form = str_replace('__Signature__',$outputlangs->trans("Signature"),$form); + $form = str_replace('__Message__',$outputlangs->trans("Message"),$form); + $form = str_replace('__IConfirmDonationReception__',$outputlangs->trans("IConfirmDonationReception"),$form); + $form = str_replace('__DonationMessage__',$conf->global->DONATION_MESSAGE,$form); $frencharticle=''; - if (preg_match('/fr/i',$outputlangs->defaultlang)) $frencharticle='<font size="+1">Article 200, 238 bis et 885-0 V bis A du code général des impôts (CGI)</font>'; + if (preg_match('/fr/i',$outputlangs->defaultlang)) $frencharticle='<font size="+1">Article 200, 238 bis et 885-0 V bis A du code général des impôts (CGI)</font>'; $form = str_replace('__FrenchArticle__',$frencharticle,$form); $frencheligibility=''; @@ -252,176 +252,176 @@ class html_cerfafr extends ModeleDon $form = str_replace('__ARTICLE885__',$art885,$form); // Save file on disk - dol_syslog("html_cerfafr::write_file $file"); - $handle=fopen($file,"w"); - fwrite($handle,$form); - fclose($handle); + dol_syslog("html_cerfafr::write_file $file"); + $handle=fopen($file,"w"); + fwrite($handle,$form); + fclose($handle); if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); $this->result = array('fullpath'=>$file); - return 1; - } - else - { - $this->error=$langs->trans("ErrorCanNotCreateDir",$dir); - return 0; - } - } - else - { - $this->error=$langs->trans("ErrorConstantNotDefined","DON_OUTPUTDIR"); - return 0; + return 1; + } + else + { + $this->error=$langs->trans("ErrorCanNotCreateDir",$dir); + return 0; + } + } + else + { + $this->error=$langs->trans("ErrorConstantNotDefined","DON_OUTPUTDIR"); + return 0; } - } + } } function chiffre_en_lettre($montant, $devise1='', $devise2='') { - if(empty($devise1)) $dev1='euros'; - else $dev1=$devise1; - if(empty($devise2)) $dev2='centimes'; - else $dev2=$devise2; - $valeur_entiere=intval($montant); - $valeur_decimal=intval(round($montant-intval($montant), 2)*100); - $dix_c=intval($valeur_decimal%100/10); - $cent_c=intval($valeur_decimal%1000/100); - $unite[1]=$valeur_entiere%10; - $dix[1]=intval($valeur_entiere%100/10); - $cent[1]=intval($valeur_entiere%1000/100); - $unite[2]=intval($valeur_entiere%10000/1000); - $dix[2]=intval($valeur_entiere%100000/10000); - $cent[2]=intval($valeur_entiere%1000000/100000); - $unite[3]=intval($valeur_entiere%10000000/1000000); - $dix[3]=intval($valeur_entiere%100000000/10000000); - $cent[3]=intval($valeur_entiere%1000000000/100000000); - $chif=array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf'); - $secon_c=''; - $trio_c=''; - for($i=1; $i<=3; $i++){ - $prim[$i]=''; - $secon[$i]=''; - $trio[$i]=''; - if($dix[$i]==0){ - $secon[$i]=''; - $prim[$i]=$chif[$unite[$i]]; - } - else if($dix[$i]==1){ - $secon[$i]=''; - $prim[$i]=$chif[($unite[$i]+10)]; - } - else if($dix[$i]==2){ - if($unite[$i]==1){ - $secon[$i]='vingt et'; - $prim[$i]=$chif[$unite[$i]]; - } - else { - $secon[$i]='vingt'; - $prim[$i]=$chif[$unite[$i]]; - } - } - else if($dix[$i]==3){ - if($unite[$i]==1){ - $secon[$i]='trente et'; - $prim[$i]=$chif[$unite[$i]]; - } - else { - $secon[$i]='trente'; - $prim[$i]=$chif[$unite[$i]]; - } - } - else if($dix[$i]==4){ - if($unite[$i]==1){ - $secon[$i]='quarante et'; - $prim[$i]=$chif[$unite[$i]]; - } - else { - $secon[$i]='quarante'; - $prim[$i]=$chif[$unite[$i]]; - } - } - else if($dix[$i]==5){ - if($unite[$i]==1){ - $secon[$i]='cinquante et'; - $prim[$i]=$chif[$unite[$i]]; - } - else { - $secon[$i]='cinquante'; - $prim[$i]=$chif[$unite[$i]]; - } - } - else if($dix[$i]==6){ - if($unite[$i]==1){ - $secon[$i]='soixante et'; - $prim[$i]=$chif[$unite[$i]]; - } - else { - $secon[$i]='soixante'; - $prim[$i]=$chif[$unite[$i]]; - } - } - else if($dix[$i]==7){ - if($unite[$i]==1){ - $secon[$i]='soixante et'; - $prim[$i]=$chif[$unite[$i]+10]; - } - else { - $secon[$i]='soixante'; - $prim[$i]=$chif[$unite[$i]+10]; - } - } - else if($dix[$i]==8){ - if($unite[$i]==1){ - $secon[$i]='quatre-vingts et'; - $prim[$i]=$chif[$unite[$i]]; - } - else { - $secon[$i]='quatre-vingt'; - $prim[$i]=$chif[$unite[$i]]; - } - } - else if($dix[$i]==9){ - if($unite[$i]==1){ - $secon[$i]='quatre-vingts et'; - $prim[$i]=$chif[$unite[$i]+10]; - } - else { - $secon[$i]='quatre-vingts'; - $prim[$i]=$chif[$unite[$i]+10]; - } - } - if($cent[$i]==1) $trio[$i]='cent'; - else if($cent[$i]!=0 || $cent[$i]!='') $trio[$i]=$chif[$cent[$i]] .' cents'; - } + if(empty($devise1)) $dev1='euros'; + else $dev1=$devise1; + if(empty($devise2)) $dev2='centimes'; + else $dev2=$devise2; + $valeur_entiere=intval($montant); + $valeur_decimal=intval(round($montant-intval($montant), 2)*100); + $dix_c=intval($valeur_decimal%100/10); + $cent_c=intval($valeur_decimal%1000/100); + $unite[1]=$valeur_entiere%10; + $dix[1]=intval($valeur_entiere%100/10); + $cent[1]=intval($valeur_entiere%1000/100); + $unite[2]=intval($valeur_entiere%10000/1000); + $dix[2]=intval($valeur_entiere%100000/10000); + $cent[2]=intval($valeur_entiere%1000000/100000); + $unite[3]=intval($valeur_entiere%10000000/1000000); + $dix[3]=intval($valeur_entiere%100000000/10000000); + $cent[3]=intval($valeur_entiere%1000000000/100000000); + $chif=array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf'); + $secon_c=''; + $trio_c=''; + for($i=1; $i<=3; $i++){ + $prim[$i]=''; + $secon[$i]=''; + $trio[$i]=''; + if($dix[$i]==0){ + $secon[$i]=''; + $prim[$i]=$chif[$unite[$i]]; + } + else if($dix[$i]==1){ + $secon[$i]=''; + $prim[$i]=$chif[($unite[$i]+10)]; + } + else if($dix[$i]==2){ + if($unite[$i]==1){ + $secon[$i]='vingt et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='vingt'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==3){ + if($unite[$i]==1){ + $secon[$i]='trente et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='trente'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==4){ + if($unite[$i]==1){ + $secon[$i]='quarante et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='quarante'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==5){ + if($unite[$i]==1){ + $secon[$i]='cinquante et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='cinquante'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==6){ + if($unite[$i]==1){ + $secon[$i]='soixante et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='soixante'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==7){ + if($unite[$i]==1){ + $secon[$i]='soixante et'; + $prim[$i]=$chif[$unite[$i]+10]; + } + else { + $secon[$i]='soixante'; + $prim[$i]=$chif[$unite[$i]+10]; + } + } + else if($dix[$i]==8){ + if($unite[$i]==1){ + $secon[$i]='quatre-vingts et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='quatre-vingt'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==9){ + if($unite[$i]==1){ + $secon[$i]='quatre-vingts et'; + $prim[$i]=$chif[$unite[$i]+10]; + } + else { + $secon[$i]='quatre-vingts'; + $prim[$i]=$chif[$unite[$i]+10]; + } + } + if($cent[$i]==1) $trio[$i]='cent'; + else if($cent[$i]!=0 || $cent[$i]!='') $trio[$i]=$chif[$cent[$i]] .' cents'; + } $chif2=array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix'); - $secon_c=$chif2[$dix_c]; - if($cent_c==1) $trio_c='cent'; - else if($cent_c!=0 || $cent_c!='') $trio_c=$chif[$cent_c] .' cents'; + $secon_c=$chif2[$dix_c]; + if($cent_c==1) $trio_c='cent'; + else if($cent_c!=0 || $cent_c!='') $trio_c=$chif[$cent_c] .' cents'; - if(($cent[3]==0 || $cent[3]=='') && ($dix[3]==0 || $dix[3]=='') && ($unite[3]==1)) - $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' million '; - else if(($cent[3]!=0 && $cent[3]!='') || ($dix[3]!=0 && $dix[3]!='') || ($unite[3]!=0 && $unite[3]!='')) - $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' millions '; - else - $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]; + if(($cent[3]==0 || $cent[3]=='') && ($dix[3]==0 || $dix[3]=='') && ($unite[3]==1)) + $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' million '; + else if(($cent[3]!=0 && $cent[3]!='') || ($dix[3]!=0 && $dix[3]!='') || ($unite[3]!=0 && $unite[3]!='')) + $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' millions '; + else + $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]; - if(($cent[2]==0 || $cent[2]=='') && ($dix[2]==0 || $dix[2]=='') && ($unite[2]==1)) - $somme = $somme.' mille '; - else if(($cent[2]!=0 && $cent[2]!='') || ($dix[2]!=0 && $dix[2]!='') || ($unite[2]!=0 && $unite[2]!='')) - $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]. ' milles '; - else - $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]; + if(($cent[2]==0 || $cent[2]=='') && ($dix[2]==0 || $dix[2]=='') && ($unite[2]==1)) + $somme = $somme.' mille '; + else if(($cent[2]!=0 && $cent[2]!='') || ($dix[2]!=0 && $dix[2]!='') || ($unite[2]!=0 && $unite[2]!='')) + $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]. ' milles '; + else + $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]; - $somme = $somme. $trio[1]. ' ' .$secon[1]. ' ' . $prim[1]; + $somme = $somme. $trio[1]. ' ' .$secon[1]. ' ' . $prim[1]; - $somme = $somme. ' '. $dev1 .' ' ; + $somme = $somme. ' '. $dev1 .' ' ; - if(($cent_c=='0' || $cent_c=='') && ($dix_c=='0' || $dix_c=='')) - return $somme. ' et zéro '. $dev2; - else - return $somme. $trio_c. ' ' .$secon_c. ' ' . $dev2; + if(($cent_c=='0' || $cent_c=='') && ($dix_c=='0' || $dix_c=='')) + return $somme. ' et zéro '. $dev2; + else + return $somme. $trio_c. ' ' .$secon_c. ' ' . $dev2; } diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index b0acad95c97b174d8c277555519f9c19db141a8b..8698b08a5c33a3ca0e35a82fdc9f8ebafa72f7bd 100644 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -35,18 +35,18 @@ class InterfaceNotification extends DolibarrTriggers public $version = self::VERSION_DOLIBARR; public $picto = 'email'; - var $listofmanagedevents=array( - 'BILL_VALIDATE', - 'BILL_PAYED', - 'ORDER_VALIDATE', - 'PROPAL_VALIDATE', - 'PROPAL_CLOSE_SIGNED', - 'FICHINTER_VALIDATE', - 'FICHINTER_ADD_CONTACT', - 'ORDER_SUPPLIER_VALIDATE', - 'ORDER_SUPPLIER_APPROVE', - 'ORDER_SUPPLIER_REFUSE', - 'SHIPPING_VALIDATE' + var $listofmanagedevents=array( + 'BILL_VALIDATE', + 'BILL_PAYED', + 'ORDER_VALIDATE', + 'PROPAL_VALIDATE', + 'PROPAL_CLOSE_SIGNED', + 'FICHINTER_VALIDATE', + 'FICHINTER_ADD_CONTACT', + 'ORDER_SUPPLIER_VALIDATE', + 'ORDER_SUPPLIER_APPROVE', + 'ORDER_SUPPLIER_REFUSE', + 'SHIPPING_VALIDATE' ); /** @@ -74,62 +74,62 @@ class InterfaceNotification extends DolibarrTriggers $notify->send($action, $object); return 1; - } - - - /** - * Return list of events managed by notification module - * - * @return array Array of events managed by notification module - */ - function getListOfManagedEvents() - { - global $conf; - - $ret=array(); - - $sql = "SELECT rowid, code, label, description, elementtype"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_action_trigger"; - $sql.= $this->db->order("rang, elementtype, code"); - dol_syslog("getListOfManagedEvents Get list of notifications", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $num=$this->db->num_rows($resql); - $i=0; - while ($i < $num) - { - $obj=$this->db->fetch_object($resql); - - $qualified=0; - // Check is this event is supported by notification module - if (in_array($obj->code,$this->listofmanagedevents)) $qualified=1; - // Check if module for this event is active - if ($qualified) - { - //print 'xx'.$obj->code; - $element=$obj->elementtype; - - // Exclude events if related module is disabled - if ($element == 'order_supplier' && empty($conf->fournisseur->enabled)) $qualified=0; - elseif ($element == 'invoice_supplier' && empty($conf->fournisseur->enabled)) $qualified=0; - elseif ($element == 'withdraw' && empty($conf->prelevement->enabled)) $qualified=0; - elseif ($element == 'shipping' && empty($conf->expedition->enabled)) $qualified=0; - elseif ($element == 'member' && empty($conf->adherent->enabled)) $qualified=0; - elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member')) && empty($conf->$element->enabled)) $qualified=0; - } - - if ($qualified) - { - $ret[]=array('rowid'=>$obj->rowid,'code'=>$obj->code,'label'=>$obj->label,'description'=>$obj->description,'elementtype'=>$obj->elementtype); - } - - $i++; - } - } - else dol_print_error($this->db); - - return $ret; - } + } + + + /** + * Return list of events managed by notification module + * + * @return array Array of events managed by notification module + */ + function getListOfManagedEvents() + { + global $conf; + + $ret=array(); + + $sql = "SELECT rowid, code, label, description, elementtype"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_action_trigger"; + $sql.= $this->db->order("rang, elementtype, code"); + dol_syslog("getListOfManagedEvents Get list of notifications", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $num=$this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj=$this->db->fetch_object($resql); + + $qualified=0; + // Check is this event is supported by notification module + if (in_array($obj->code,$this->listofmanagedevents)) $qualified=1; + // Check if module for this event is active + if ($qualified) + { + //print 'xx'.$obj->code; + $element=$obj->elementtype; + + // Exclude events if related module is disabled + if ($element == 'order_supplier' && empty($conf->fournisseur->enabled)) $qualified=0; + elseif ($element == 'invoice_supplier' && empty($conf->fournisseur->enabled)) $qualified=0; + elseif ($element == 'withdraw' && empty($conf->prelevement->enabled)) $qualified=0; + elseif ($element == 'shipping' && empty($conf->expedition->enabled)) $qualified=0; + elseif ($element == 'member' && empty($conf->adherent->enabled)) $qualified=0; + elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member')) && empty($conf->$element->enabled)) $qualified=0; + } + + if ($qualified) + { + $ret[]=array('rowid'=>$obj->rowid,'code'=>$obj->code,'label'=>$obj->label,'description'=>$obj->description,'elementtype'=>$obj->elementtype); + } + + $i++; + } + } + else dol_print_error($this->db); + + return $ret; + } } diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 7af07c8675bffd46c90ed7edb42e8e82d36b3f35..540c30ec2863a3df2c90c60f963d9ff0b2ee7080 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -88,7 +88,7 @@ class EcmFiles //extends CommonObject */ public function create(User $user, $notrigger = false) { - global $conf; + global $conf; dol_syslog(__METHOD__, LOG_DEBUG); @@ -140,25 +140,25 @@ class EcmFiles //extends CommonObject if (isset($this->acl)) { $this->acl = trim($this->acl); } - if (empty($this->date_c)) $this->date_c = dol_now(); + if (empty($this->date_c)) $this->date_c = dol_now(); - // If ref not defined - $ref = dol_hash($this->filepath.'/'.$this->filename, 3); + // If ref not defined + $ref = dol_hash($this->filepath.'/'.$this->filename, 3); if (! empty($this->ref)) $ref=$this->ref; - $maxposition=0; + $maxposition=0; if (empty($this->position)) // Get max used { - $sql = "SELECT MAX(position) as maxposition FROM " . MAIN_DB_PREFIX . $this->table_element; - $sql.= " WHERE filepath ='".$this->db->escape($this->filepath)."'"; + $sql = "SELECT MAX(position) as maxposition FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql.= " WHERE filepath ='".$this->db->escape($this->filepath)."'"; - $resql = $this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - $maxposition = (int) $obj->maxposition; - } - else dol_print_error($this->db); + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $maxposition = (int) $obj->maxposition; + } + else dol_print_error($this->db); } $maxposition=$maxposition+1; @@ -217,7 +217,7 @@ class EcmFiles //extends CommonObject if (!$error) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); - $this->position = $maxposition; + $this->position = $maxposition; if (!$notrigger) { // Uncomment this and change MYOBJECT to your own tag if you @@ -408,7 +408,7 @@ class EcmFiles //extends CommonObject $sql .= $this->db->order($sortfield,$sortorder); } if (!empty($limit)) { - $sql .= ' ' . $this->db->plimit($limit, $offset); + $sql .= ' ' . $this->db->plimit($limit, $offset); } $this->lines = array(); @@ -676,49 +676,49 @@ class EcmFiles //extends CommonObject * * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) * @param string $option On what the link point to - * @param int $notooltip 1=Disable tooltip - * @param int $maxlen Max length of visible user name - * @param string $morecss Add more css on link + * @param int $notooltip 1=Disable tooltip + * @param int $maxlen Max length of visible user name + * @param string $morecss Add more css on link * @return string String with URL */ function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') { global $db, $conf, $langs; - global $dolibarr_main_authentication, $dolibarr_main_demo; - global $menumanager; + global $dolibarr_main_authentication, $dolibarr_main_demo; + global $menumanager; - if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips - $result = ''; - $companylink = ''; + $result = ''; + $companylink = ''; - $label = '<u>' . $langs->trans("MyModule") . '</u>'; - $label.= '<br>'; - $label.= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; + $label = '<u>' . $langs->trans("MyModule") . '</u>'; + $label.= '<br>'; + $label.= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; - $url = DOL_URL_ROOT.'/ecm/'.$this->table_name.'_card.php?id='.$this->id; + $url = DOL_URL_ROOT.'/ecm/'.$this->table_name.'_card.php?id='.$this->id; - $linkclose=''; - if (empty($notooltip)) - { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label=$langs->trans("ShowProject"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; - } - else $linkclose = ($morecss?' class="'.$morecss.'"':''); + $linkclose=''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowProject"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } + else $linkclose = ($morecss?' class="'.$morecss.'"':''); $linkstart = '<a href="'.$url.'"'; $linkstart.=$linkclose.'>'; $linkend='</a>'; - if ($withpicto) - { - $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); - if ($withpicto != 2) $result.=' '; + if ($withpicto) + { + $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); + if ($withpicto != 2) $result.=' '; } $result.= $linkstart . $this->ref . $linkend; return $result; @@ -793,7 +793,7 @@ class EcmFiles //extends CommonObject */ public function initAsSpecimen() { - global $conf,$user; + global $conf,$user; $this->id = 0; diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index f26efeadc4a16451baf8d13a4a63ec56d99777b1..d440396d0c31ee355dd778f2efd1f1badab5ad4c 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -48,7 +48,7 @@ class Expedition extends CommonObject public $table_element="expedition"; public $table_element_line="expeditiondet"; protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - public $picto = 'sending'; + public $picto = 'sending'; var $socid; var $ref_customer; @@ -131,29 +131,29 @@ class Expedition extends CommonObject global $langs, $conf; $langs->load("sendings"); - if (!empty($conf->global->EXPEDITION_ADDON_NUMBER)) - { + if (!empty($conf->global->EXPEDITION_ADDON_NUMBER)) + { $mybool = false; $file = $conf->global->EXPEDITION_ADDON_NUMBER.".php"; $classname = $conf->global->EXPEDITION_ADDON_NUMBER; - // Include file with class - $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach ($dirmodels as $reldir) { + foreach ($dirmodels as $reldir) { - $dir = dol_buildpath($reldir."core/modules/expedition/"); + $dir = dol_buildpath($reldir."core/modules/expedition/"); - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } - if (! $mybool) - { - dol_print_error('',"Failed to include file ".$file); - return ''; - } + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } $obj = new $classname(); $numref = ""; @@ -168,19 +168,19 @@ class Expedition extends CommonObject dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); return ""; } - } - else - { - print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined"); - return ""; - } + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined"); + return ""; + } } /** * Create expedition en base * * @param User $user Objet du user qui cree - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 si erreur, id expedition creee si ok */ function create($user, $notrigger=0) @@ -249,8 +249,8 @@ class Expedition extends CommonObject $sql.= ", ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null"); $sql.= ", ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null"); $sql.= ", ".(!empty($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null"); - $sql.= ", ".(int) $this->fk_incoterms; - $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; + $sql.= ", ".(int) $this->fk_incoterms; + $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; $sql.= ")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); @@ -315,10 +315,10 @@ class Expedition extends CommonObject if (! $error && ! $notrigger) { - // Call trigger - $result=$this->call_trigger('SHIPPING_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('SHIPPING_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers if (! $error) { @@ -393,7 +393,7 @@ class Expedition extends CommonObject $resql = $this->db->query($sql); if ($resql) { - $line_id = $this->db->last_insert_id(MAIN_DB_PREFIX."expeditiondet"); + $line_id = $this->db->last_insert_id(MAIN_DB_PREFIX."expeditiondet"); } else { @@ -471,7 +471,7 @@ class Expedition extends CommonObject * @param int $id Id of object to load * @param string $ref Ref of object * @param string $ref_ext External reference of object - * @param string $ref_int Internal reference of other object + * @param string $ref_int Internal reference of other object * @return int >0 if OK, 0 if not found, <0 if KO */ function fetch($id, $ref='', $ref_ext='', $ref_int='') @@ -487,16 +487,16 @@ class Expedition extends CommonObject $sql.= ", e.fk_shipping_method, e.tracking_number"; $sql.= ", el.fk_source as origin_id, el.sourcetype as origin"; $sql.= ", e.note_private, e.note_public"; - $sql.= ', e.fk_incoterms, e.location_incoterms'; - $sql.= ', i.libelle as libelle_incoterms'; + $sql.= ', e.fk_incoterms, e.location_incoterms'; + $sql.= ', i.libelle as libelle_incoterms'; $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."'"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON e.fk_incoterms = i.rowid'; $sql.= " WHERE e.entity IN (".getEntity('expedition').")"; if ($id) $sql.= " AND e.rowid=".$id; - if ($ref) $sql.= " AND e.ref='".$this->db->escape($ref)."'"; - if ($ref_ext) $sql.= " AND e.ref_ext='".$this->db->escape($ref_ext)."'"; - if ($ref_int) $sql.= " AND e.ref_int='".$this->db->escape($ref_int)."'"; + if ($ref) $sql.= " AND e.ref='".$this->db->escape($ref)."'"; + if ($ref_ext) $sql.= " AND e.ref_ext='".$this->db->escape($ref_ext)."'"; + if ($ref_int) $sql.= " AND e.ref_int='".$this->db->escape($ref_int)."'"; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $result = $this->db->query($sql); @@ -600,14 +600,14 @@ class Expedition extends CommonObject * Validate object and update stock if option enabled * * @param User $user Object user that validate - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if OK, >0 if KO */ function valid($user, $notrigger=0) { global $conf, $langs; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; dol_syslog(get_class($this)."::valid"); @@ -618,8 +618,8 @@ class Expedition extends CommonObject return 0; } - if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->shipping_advance->validate)))) + if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->shipping_advance->validate)))) { $this->error='Permission denied'; dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); @@ -646,7 +646,7 @@ class Expedition extends CommonObject { $numref = "EXP".$this->id; } - $this->newref = $numref; + $this->newref = $numref; $now=dol_now(); @@ -725,7 +725,7 @@ class Expedition extends CommonObject // line with batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record. - // Note: ->fk_origin_stock = id into table llx_product_batch (may be rename into llx_product_stock_batch in another version) + // Note: ->fk_origin_stock = id into table llx_product_batch (may be rename into llx_product_stock_batch in another version) $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); if ($result < 0) { $error++; @@ -748,22 +748,22 @@ class Expedition extends CommonObject // Change status of order to "shipment in process" $ret = $this->setStatut(Commande::STATUS_SHIPMENTONPROCESS, $this->origin_id, $this->origin); - if (! $ret) + if (! $ret) { - $error++; + $error++; } if (! $error && ! $notrigger) { - // Call trigger - $result=$this->call_trigger('SHIPPING_VALIDATE',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('SHIPPING_VALIDATE',$user); + if ($result < 0) { $error++; } + // End call triggers } if (! $error) { - $this->oldref = $this->ref; + $this->oldref = $this->ref; // Rename directory if dir was a temporary ref if (preg_match('/^[\(]?PROV/i', $this->ref)) @@ -780,17 +780,17 @@ class Expedition extends CommonObject if (@rename($dirsource, $dirdest)) { - dol_syslog("Rename ok"); - // Rename docs starting with $oldref with $newref - $listoffiles=dol_dir_list($conf->expedition->dir_output.'/sending/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); - foreach($listoffiles as $fileentry) - { - $dirsource=$fileentry['name']; - $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); - $dirsource=$fileentry['path'].'/'.$dirsource; - $dirdest=$fileentry['path'].'/'.$dirdest; - @rename($dirsource, $dirdest); - } + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->expedition->dir_output.'/sending/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } } } } @@ -812,8 +812,8 @@ class Expedition extends CommonObject { foreach($this->errors as $errmsg) { - dol_syslog(get_class($this)."::valid ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); + dol_syslog(get_class($this)."::valid ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); } $this->db->rollback(); return -1*$error; @@ -885,14 +885,14 @@ class Expedition extends CommonObject if (! ($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS)) { - $langs->load("errors"); + $langs->load("errors"); $this->error=$langs->trans("ErrorWarehouseRequiredIntoShipmentLine"); return -1; } if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) { - // Check must be done for stock of product into warehouse if $entrepot_id defined + // Check must be done for stock of product into warehouse if $entrepot_id defined $product=new Product($this->db); $result=$product->fetch($fk_product); @@ -906,8 +906,8 @@ class Expedition extends CommonObject $product_type=$product->type; if ($product_type == 0 && $product_stock < $qty) { - $langs->load("errors"); - $this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref); + $langs->load("errors"); + $this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref); $this->db->rollback(); return -3; } @@ -917,8 +917,8 @@ class Expedition extends CommonObject // If product need a batch number, we should not have called this function but addline_batch instead. if (! empty($conf->productbatch->enabled) && ! empty($orderline->fk_product) && ! empty($orderline->product_tobatch)) { - $this->error='ADDLINE_WAS_CALLED_INSTEAD_OF_ADDLINEBATCH'; - return -4; + $this->error='ADDLINE_WAS_CALLED_INSTEAD_OF_ADDLINEBATCH'; + return -4; } // extrafields @@ -928,7 +928,7 @@ class Expedition extends CommonObject $this->lines[$num] = $line; } - /** + /** * Add a shipment line with batch record * * @param array $dbatch Array of value (key 'detail' -> Array, key 'qty' total quantity for line, key ix_l : original line index) @@ -952,7 +952,7 @@ class Expedition extends CommonObject // $value['id_batch']=id into llx_product_batch of record to move //var_dump($value); - $linebatch = new ExpeditionLineBatch($this->db); + $linebatch = new ExpeditionLineBatch($this->db); $ret=$linebatch->fetchFromStock($value['id_batch']); // load serial, sellby, eatby if ($ret<0) { @@ -970,8 +970,8 @@ class Expedition extends CommonObject if ($prod_batch->qty < $linebatch->dluo_qty) { - $langs->load("errors"); - $this->errors[]=$langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $prod_batch->fk_product); + $langs->load("errors"); + $this->errors[]=$langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $prod_batch->fk_product); dol_syslog(get_class($this)."::addline_batch error=Product ".$prod_batch->batch.": ".$this->errorsToString(), LOG_ERR); $this->db->rollback(); return -1; @@ -996,16 +996,16 @@ class Expedition extends CommonObject } } - /** - * Update database - * - * @param User $user User that modify - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function update($user=null, $notrigger=0) - { - global $conf; + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=null, $notrigger=0) + { + global $conf; $error=0; // Clean parameters @@ -1035,8 +1035,8 @@ class Expedition extends CommonObject // Check parameters // Put here code to add control on parameters values - // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX."expedition SET"; + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."expedition SET"; $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; @@ -1063,32 +1063,32 @@ class Expedition extends CommonObject $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").","; $sql.= " entity=".$conf->entity; - $sql.= " WHERE rowid=".$this->id; + $sql.= " WHERE rowid=".$this->id; $this->db->begin(); dol_syslog(get_class($this)."::update", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } if (! $error) { if (! $notrigger) { - // Call trigger - $result=$this->call_trigger('SHIPPING_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers - } + // Call trigger + $result=$this->call_trigger('SHIPPING_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } } - // Commit or rollback + // Commit or rollback if ($error) { foreach($this->errors as $errmsg) { - dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); } $this->db->rollback(); return -1*$error; @@ -1098,7 +1098,7 @@ class Expedition extends CommonObject $this->db->commit(); return 1; } - } + } /** * Delete shipment. @@ -1231,18 +1231,18 @@ class Expedition extends CommonObject if (! empty($this->origin) && $this->origin_id > 0) { - $this->fetch_origin(); - $origin=$this->origin; - if ($this->$origin->statut == Commande::STATUS_SHIPMENTONPROCESS) // If order source of shipment is "shipment in progress" - { - // Check if there is no more shipment. If not, we can move back status of order to "validated" instead of "shipment in progress" - $this->$origin->loadExpeditions(); - //var_dump($this->$origin->expeditions);exit; - if (count($this->$origin->expeditions) <= 0) - { - $this->$origin->setStatut(Commande::STATUS_VALIDATED); - } - } + $this->fetch_origin(); + $origin=$this->origin; + if ($this->$origin->statut == Commande::STATUS_SHIPMENTONPROCESS) // If order source of shipment is "shipment in progress" + { + // Check if there is no more shipment. If not, we can move back status of order to "validated" instead of "shipment in progress" + $this->$origin->loadExpeditions(); + //var_dump($this->$origin->expeditions);exit; + if (count($this->$origin->expeditions) <= 0) + { + $this->$origin->setStatut(Commande::STATUS_VALIDATED); + } + } } if (! $error) @@ -1354,13 +1354,13 @@ class Expedition extends CommonObject { $obj = $this->db->fetch_object($resql); - if ($originline == $obj->fk_origin_line) { - $line->entrepot_id = 0; // entrepod_id in details_entrepot - $line->qty_shipped += $obj->qty_shipped; + if ($originline == $obj->fk_origin_line) { + $line->entrepot_id = 0; // entrepod_id in details_entrepot + $line->qty_shipped += $obj->qty_shipped; } else { - $line = new ExpeditionLigne($this->db); - $line->entrepot_id = $obj->fk_entrepot; - $line->qty_shipped = $obj->qty_shipped; + $line = new ExpeditionLigne($this->db); + $line->entrepot_id = $obj->fk_entrepot; + $line->qty_shipped = $obj->qty_shipped; } $detail_entrepot = new stdClass; @@ -1368,13 +1368,13 @@ class Expedition extends CommonObject $detail_entrepot->qty_shipped = $obj->qty_shipped; $line->details_entrepot[] = $detail_entrepot; - $line->line_id = $obj->line_id; - $line->rowid = $obj->line_id; // TODO deprecated - $line->id = $obj->line_id; + $line->line_id = $obj->line_id; + $line->rowid = $obj->line_id; // TODO deprecated + $line->id = $obj->line_id; - $line->fk_origin = 'orderline'; - $line->fk_origin_line = $obj->fk_origin_line; - $line->origin_line_id = $obj->fk_origin_line; // TODO deprecated + $line->fk_origin = 'orderline'; + $line->fk_origin_line = $obj->fk_origin_line; + $line->origin_line_id = $obj->fk_origin_line; // TODO deprecated $line->fk_expedition = $this->id; // id of parent @@ -1382,8 +1382,8 @@ class Expedition extends CommonObject $line->fk_product = $obj->fk_product; $line->fk_product_type = $obj->fk_product_type; $line->ref = $obj->product_ref; // TODO deprecated - $line->product_ref = $obj->product_ref; - $line->product_label = $obj->product_label; + $line->product_ref = $obj->product_ref; + $line->product_label = $obj->product_label; $line->libelle = $obj->product_label; // TODO deprecated $line->product_tobatch = $obj->product_tobatch; $line->label = $obj->custom_label; @@ -1440,34 +1440,34 @@ class Expedition extends CommonObject // Eat-by date if (! empty($conf->productbatch->enabled) && $obj->line_id > 0) { - require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php'; - - $newdetailbatch = ExpeditionLineBatch::fetchAll($this->db,$obj->line_id); - if (is_array($newdetailbatch)) - { - if ($originline != $obj->fk_origin_line) - { - $line->detail_batch = $newdetailbatch; - } - else + require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php'; + + $newdetailbatch = ExpeditionLineBatch::fetchAll($this->db,$obj->line_id); + if (is_array($newdetailbatch)) + { + if ($originline != $obj->fk_origin_line) + { + $line->detail_batch = $newdetailbatch; + } + else { - $line->detail_batch = array_merge($line->detail_batch, $newdetailbatch); - } - } + $line->detail_batch = array_merge($line->detail_batch, $newdetailbatch); + } + } } if ($originline != $obj->fk_origin_line) { - $this->lines[$lineindex] = $line; - $lineindex++; + $this->lines[$lineindex] = $line; + $lineindex++; } else { - $line->total_ht += $tabprice[0]; - $line->total_localtax1 += $tabprice[9]; - $line->total_localtax2 += $tabprice[10]; - $line->total_ttc += $tabprice[2]; - $line->total_tva += $tabprice[1]; + $line->total_ht += $tabprice[0]; + $line->total_localtax1 += $tabprice[9]; + $line->total_localtax2 += $tabprice[10]; + $line->total_ttc += $tabprice[2]; + $line->total_tva += $tabprice[1]; } $i++; @@ -1484,24 +1484,24 @@ class Expedition extends CommonObject } /** - * Return clicable link of object (with eventually picto) - * - * @param int $withpicto Add picto into link - * @param string $option Where the link point to - * @param int $max Max length to show - * @param int $short Use short labels - * @param int $notooltip 1=No tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string String with URL - */ + * Return clicable link of object (with eventually picto) + * + * @param int $withpicto Add picto into link + * @param string $option Where the link point to + * @param int $max Max length to show + * @param int $short Use short labels + * @param int $notooltip 1=No tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ function getNomUrl($withpicto=0, $option='', $max=0, $short=0, $notooltip=0, $save_lastsearch_value=-1) { global $langs; $result=''; - $label = '<u>' . $langs->trans("ShowSending") . '</u>'; - $label .= '<br><b>' . $langs->trans('Ref') . ':</b> '.$this->ref; - $label .= '<br><b>'.$langs->trans('RefCustomer').':</b> '.($this->ref_customer ? $this->ref_customer : $this->ref_client); + $label = '<u>' . $langs->trans("ShowSending") . '</u>'; + $label .= '<br><b>' . $langs->trans('Ref') . ':</b> '.$this->ref; + $label .= '<br><b>'.$langs->trans('RefCustomer').':</b> '.($this->ref_customer ? $this->ref_customer : $this->ref_client); $url = DOL_URL_ROOT.'/expedition/card.php?id='.$this->id; @@ -1518,16 +1518,16 @@ class Expedition extends CommonObject $linkclose=''; if (empty($notooltip)) { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label=$langs->trans("ShowSending"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip"'; + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowSending"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; } - $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; $linkend='</a>'; $picto='sending'; @@ -1539,11 +1539,11 @@ class Expedition extends CommonObject } /** - * Return status label - * - * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto - * @return string Libelle - */ + * Return status label + * + * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto + * @return string Libelle + */ function getLibStatut($mode=0) { return $this->LibStatut($this->statut,$mode); @@ -1593,11 +1593,11 @@ class Expedition extends CommonObject } /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void */ function initAsSpecimen() { @@ -1607,7 +1607,7 @@ class Expedition extends CommonObject dol_syslog(get_class($this)."::initAsSpecimen"); - // Load array of products prodids + // Load array of products prodids $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; @@ -1648,11 +1648,11 @@ class Expedition extends CommonObject $this->commande_id = 0; $this->commande = $order; - $this->origin_id = 1; - $this->origin = 'commande'; + $this->origin_id = 1; + $this->origin = 'commande'; - $this->note_private = 'Private note'; - $this->note_public = 'Public note'; + $this->note_private = 'Private note'; + $this->note_public = 'Public note'; $nbp = 5; $xnbp = 0; @@ -1732,99 +1732,99 @@ class Expedition extends CommonObject } } - /** - * Fetch all deliveries method and return an array. Load array this->listmeths. - * - * @param id $id only this carrier, all if none - * @return void - */ - function list_delivery_methods($id='') - { - global $langs; - - $this->listmeths = array(); - $i=0; - - $sql = "SELECT em.rowid, em.code, em.libelle, em.description, em.tracking, em.active"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em"; - if ($id!='') $sql.= " WHERE em.rowid=".$id; - - $resql = $this->db->query($sql); - if ($resql) - { - while ($obj = $this->db->fetch_object($resql)) - { - $this->listmeths[$i]['rowid'] = $obj->rowid; - $this->listmeths[$i]['code'] = $obj->code; - $label=$langs->trans('SendingMethod'.$obj->code); - $this->listmeths[$i]['libelle'] = ($label != 'SendingMethod'.$obj->code?$label:$obj->libelle); - $this->listmeths[$i]['description'] = $obj->description; - $this->listmeths[$i]['tracking'] = $obj->tracking; - $this->listmeths[$i]['active'] = $obj->active; - $i++; - } - } - } - - /** - * Update/create delivery method. - * - * @param string $id id method to activate - * - * @return void - */ - function update_delivery_method($id='') - { - if ($id=='') - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_shipment_mode (code, libelle, description, tracking)"; - $sql.=" VALUES ('".$this->db->escape($this->update['code'])."','".$this->db->escape($this->update['libelle'])."','".$this->db->escape($this->update['description'])."','".$this->db->escape($this->update['tracking'])."')"; - $resql = $this->db->query($sql); - } - else - { - $sql = "UPDATE ".MAIN_DB_PREFIX."c_shipment_mode SET"; - $sql.= " code='".$this->db->escape($this->update['code'])."'"; - $sql.= ",libelle='".$this->db->escape($this->update['libelle'])."'"; - $sql.= ",description='".$this->db->escape($this->update['description'])."'"; - $sql.= ",tracking='".$this->db->escape($this->update['tracking'])."'"; - $sql.= " WHERE rowid=".$id; - $resql = $this->db->query($sql); - } - if ($resql < 0) dol_print_error($this->db,''); - } - - /** - * Activate delivery method. - * - * @param id $id id method to activate - * - * @return void - */ - function activ_delivery_method($id) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=1'; - $sql.= ' WHERE rowid='.$id; - - $resql = $this->db->query($sql); - - } - - /** - * DesActivate delivery method. - * - * @param id $id id method to desactivate - * - * @return void - */ - function disable_delivery_method($id) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=0'; - $sql.= ' WHERE rowid='.$id; - - $resql = $this->db->query($sql); - - } + /** + * Fetch all deliveries method and return an array. Load array this->listmeths. + * + * @param id $id only this carrier, all if none + * @return void + */ + function list_delivery_methods($id='') + { + global $langs; + + $this->listmeths = array(); + $i=0; + + $sql = "SELECT em.rowid, em.code, em.libelle, em.description, em.tracking, em.active"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em"; + if ($id!='') $sql.= " WHERE em.rowid=".$id; + + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + $this->listmeths[$i]['rowid'] = $obj->rowid; + $this->listmeths[$i]['code'] = $obj->code; + $label=$langs->trans('SendingMethod'.$obj->code); + $this->listmeths[$i]['libelle'] = ($label != 'SendingMethod'.$obj->code?$label:$obj->libelle); + $this->listmeths[$i]['description'] = $obj->description; + $this->listmeths[$i]['tracking'] = $obj->tracking; + $this->listmeths[$i]['active'] = $obj->active; + $i++; + } + } + } + + /** + * Update/create delivery method. + * + * @param string $id id method to activate + * + * @return void + */ + function update_delivery_method($id='') + { + if ($id=='') + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_shipment_mode (code, libelle, description, tracking)"; + $sql.=" VALUES ('".$this->db->escape($this->update['code'])."','".$this->db->escape($this->update['libelle'])."','".$this->db->escape($this->update['description'])."','".$this->db->escape($this->update['tracking'])."')"; + $resql = $this->db->query($sql); + } + else + { + $sql = "UPDATE ".MAIN_DB_PREFIX."c_shipment_mode SET"; + $sql.= " code='".$this->db->escape($this->update['code'])."'"; + $sql.= ",libelle='".$this->db->escape($this->update['libelle'])."'"; + $sql.= ",description='".$this->db->escape($this->update['description'])."'"; + $sql.= ",tracking='".$this->db->escape($this->update['tracking'])."'"; + $sql.= " WHERE rowid=".$id; + $resql = $this->db->query($sql); + } + if ($resql < 0) dol_print_error($this->db,''); + } + + /** + * Activate delivery method. + * + * @param id $id id method to activate + * + * @return void + */ + function activ_delivery_method($id) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=1'; + $sql.= ' WHERE rowid='.$id; + + $resql = $this->db->query($sql); + + } + + /** + * DesActivate delivery method. + * + * @param id $id id method to desactivate + * + * @return void + */ + function disable_delivery_method($id) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=0'; + $sql.= ' WHERE rowid='.$id; + + $resql = $this->db->query($sql); + + } /** @@ -1959,8 +1959,8 @@ class Expedition extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentClassifyClosedInDolibarr",$numref)); if ($result < 0) { - $this->error = $mouvS->error; - $this->errors = $mouvS->errors; + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; $error++; break; } } @@ -1971,9 +1971,9 @@ class Expedition extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentClassifyClosedInDolibarr",$numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); if ($result < 0) { - $this->error = $mouvS->error; - $this->errors = $mouvS->errors; - $error++; break; + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; } } } @@ -1988,27 +1988,27 @@ class Expedition extends CommonObject // Call trigger if (! $error) { - $result=$this->call_trigger('SHIPPING_CLOSED',$user); - if ($result < 0) { - $error++; - } + $result=$this->call_trigger('SHIPPING_CLOSED',$user); + if ($result < 0) { + $error++; + } } } else { dol_print_error($this->db); - $error++; + $error++; } if (! $error) { - $this->db->commit(); - return 1; + $this->db->commit(); + return 1; } else { - $this->db->rollback(); - return -1; + $this->db->rollback(); + return -1; } } @@ -2019,7 +2019,7 @@ class Expedition extends CommonObject */ function set_billed() { - global $user; + global $user; $error=0; $this->db->begin(); @@ -2125,8 +2125,8 @@ class Expedition extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ShipmentUnClassifyCloseddInDolibarr",$numref)); if ($result < 0) { - $this->error = $mouvS->error; - $this->errors = $mouvS->errors; + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; $error++; break; } } @@ -2137,9 +2137,9 @@ class Expedition extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ShipmentUnClassifyCloseddInDolibarr",$numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); if ($result < 0) { - $this->error = $mouvS->error; - $this->errors = $mouvS->errors; - $error++; break; + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; } } } @@ -2153,11 +2153,11 @@ class Expedition extends CommonObject if (! $error) { - // Call trigger - $result=$this->call_trigger('SHIPPING_REOPEN',$user); - if ($result < 0) { - $error++; - } + // Call trigger + $result=$this->call_trigger('SHIPPING_REOPEN',$user); + if ($result < 0) { + $error++; + } } } else { @@ -2280,11 +2280,11 @@ class ExpeditionLigne extends CommonObjectLine */ var $libelle; - /** - * Constructor - * - * @param DoliDB $db Database handler - */ + /** + * Constructor + * + * @param DoliDB $db Database handler + */ function __construct($db) { $this->db=$db; diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index b67e5073144e4bd1f5f8f22ad65efcb9d8760557..f9b6bddf80c7b2eb735f8388ff15916103921c4d 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -38,7 +38,7 @@ class Fichinter extends CommonObject public $table_element='fichinter'; public $fk_element='fk_fichinter'; public $table_element_line='fichinterdet'; - public $picto = 'intervention'; + public $picto = 'intervention'; /** * {@inheritdoc} @@ -83,7 +83,7 @@ class Fichinter extends CommonObject * Constructor * * @param DoliDB $db Database handler - */ + */ function __construct($db) { $this->db = $db; @@ -152,7 +152,7 @@ class Fichinter extends CommonObject * Create an intervention into data base * * @param User $user Objet user that make creation - * @param int $notrigger Disable all triggers + * @param int $notrigger Disable all triggers * @return int <0 if KO, >0 if OK */ function create($user, $notrigger=0) @@ -237,13 +237,13 @@ class Fichinter extends CommonObject } if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } // Add linked object if (! $error && $this->origin && $this->origin_id) @@ -253,13 +253,13 @@ class Fichinter extends CommonObject } - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('FICHINTER_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('FICHINTER_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } if (! $error) { @@ -287,7 +287,7 @@ class Fichinter extends CommonObject * Update an intervention * * @param User $user Objet user that make creation - * @param int $notrigger Disable all triggers + * @param int $notrigger Disable all triggers * @return int <0 if KO, >0 if OK */ function update($user, $notrigger=0) @@ -316,10 +316,10 @@ class Fichinter extends CommonObject if (! $notrigger) { - // Call trigger - $result=$this->call_trigger('FICHINTER_MODIFY',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers + // Call trigger + $result=$this->call_trigger('FICHINTER_MODIFY',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers } $this->db->commit(); @@ -446,7 +446,7 @@ class Fichinter extends CommonObject * Validate a intervention * * @param User $user User that validate - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, >0 if OK */ function setValid($user, $notrigger=0) @@ -471,7 +471,7 @@ class Fichinter extends CommonObject { $num = $this->ref; } - $this->newref = $num; + $this->newref = $num; $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter"; $sql.= " SET fk_statut = 1"; @@ -492,10 +492,10 @@ class Fichinter extends CommonObject if (! $error && ! $notrigger) { - // Call trigger - $result=$this->call_trigger('FICHINTER_VALIDATE',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('FICHINTER_VALIDATE',$user); + if ($result < 0) { $error++; } + // End call triggers } if (! $error) @@ -517,17 +517,17 @@ class Fichinter extends CommonObject if (@rename($dirsource, $dirdest)) { - dol_syslog("Rename ok"); - // Rename docs starting with $oldref with $newref - $listoffiles=dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); - foreach($listoffiles as $fileentry) - { - $dirsource=$fileentry['name']; - $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); - $dirsource=$fileentry['path'].'/'.$dirsource; - $dirdest=$fileentry['path'].'/'.$dirdest; - @rename($dirsource, $dirdest); - } + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } } } } @@ -647,7 +647,7 @@ class Fichinter extends CommonObject if ($mode == 5) return '<span class="hideonsmartphone">'.$langs->trans($this->statuts_short[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),$this->statuts_logo[$statut]); if ($mode == 6) - return '<span class="hideonsmartphone">'.$langs->trans($this->statuts[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),$this->statuts_logo[$statut]); + return '<span class="hideonsmartphone">'.$langs->trans($this->statuts[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),$this->statuts_logo[$statut]); return ''; } @@ -657,8 +657,8 @@ class Fichinter extends CommonObject * * @param int $withpicto 0=_No picto, 1=Includes the picto in the linkn, 2=Picto only * @param string $option Options - * @param int $notooltip 1=Disable tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @param int $notooltip 1=Disable tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @return string String with URL */ function getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1) @@ -667,20 +667,20 @@ class Fichinter extends CommonObject $result=''; - $label = '<u>' . $langs->trans("ShowIntervention") . '</u>'; - if (! empty($this->ref)) - $label .= '<br><b>' . $langs->trans('Ref') . ':</b> '.$this->ref; + $label = '<u>' . $langs->trans("ShowIntervention") . '</u>'; + if (! empty($this->ref)) + $label .= '<br><b>' . $langs->trans('Ref') . ':</b> '.$this->ref; - $picto='intervention'; - $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id; + $picto='intervention'; + $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id; - if ($option !== 'nolink') - { - // Add param to save lastsearch_values or not - $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; - if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; - } + if ($option !== 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; + if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; + } $linkclose=''; if (empty($notooltip)) @@ -698,7 +698,7 @@ class Fichinter extends CommonObject $linkstart.=$linkclose.'>'; $linkend='</a>'; - if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; if ($withpicto != 2) $result.=$linkstart.$this->ref.$linkend; return $result; @@ -833,7 +833,7 @@ class Fichinter extends CommonObject function delete($user, $notrigger=0) { global $conf,$langs; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $error=0; @@ -899,10 +899,10 @@ class Fichinter extends CommonObject if (! $notrigger) { - // Call trigger - $result=$this->call_trigger('FICHINTER_DELETE',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers + // Call trigger + $result=$this->call_trigger('FICHINTER_DELETE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers } $this->db->commit(); @@ -1024,98 +1024,98 @@ class Fichinter extends CommonObject - /** - * Load an object from its id and create a new one in database - * - * @param int $socid Id of thirdparty - * @return int New id of clone - */ - function createFromClone($socid=0) - { - global $user,$hookmanager; + /** + * Load an object from its id and create a new one in database + * + * @param int $socid Id of thirdparty + * @return int New id of clone + */ + function createFromClone($socid=0) + { + global $user,$hookmanager; - $error=0; + $error=0; - $this->context['createfromclone'] = 'createfromclone'; + $this->context['createfromclone'] = 'createfromclone'; - $this->db->begin(); + $this->db->begin(); // get extrafields so they will be clone foreach($this->lines as $line) $line->fetch_optionals($line->rowid); - // Load source object - $objFrom = clone $this; + // Load source object + $objFrom = clone $this; - // Change socid if needed - if (! empty($socid) && $socid != $this->socid) - { - $objsoc = new Societe($this->db); + // Change socid if needed + if (! empty($socid) && $socid != $this->socid) + { + $objsoc = new Societe($this->db); - if ($objsoc->fetch($socid)>0) - { - $this->socid = $objsoc->id; - //$this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); - //$this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); - $this->fk_project = ''; - $this->fk_delivery_address = ''; - } + if ($objsoc->fetch($socid)>0) + { + $this->socid = $objsoc->id; + //$this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + //$this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); + $this->fk_project = ''; + $this->fk_delivery_address = ''; + } - // TODO Change product price if multi-prices - } + // TODO Change product price if multi-prices + } - $this->id=0; + $this->id=0; $this->ref = ''; - $this->statut=0; - - // Clear fields - $this->user_author_id = $user->id; - $this->user_valid = ''; - $this->date_creation = ''; - $this->date_validation = ''; - $this->ref_client = ''; - - // Create clone - $result=$this->create($user); - if ($result < 0) $error++; - - if (! $error) - { - // Add lines because it is not included into create function - foreach ($this->lines as $line) - { - $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration); - } - - // Hook of thirdparty module - if (is_object($hookmanager)) - { - $parameters=array('objFrom'=>$objFrom); - $action=''; - $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) $error++; - } - - // Call trigger - $result=$this->call_trigger('INTERVENTION_CLONE',$user); - if ($result < 0) $error++; - // End call triggers - } - - unset($this->context['createfromclone']); - - // End - if (! $error) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->db->rollback(); - return -1; - } - } + $this->statut=0; + + // Clear fields + $this->user_author_id = $user->id; + $this->user_valid = ''; + $this->date_creation = ''; + $this->date_validation = ''; + $this->ref_client = ''; + + // Create clone + $result=$this->create($user); + if ($result < 0) $error++; + + if (! $error) + { + // Add lines because it is not included into create function + foreach ($this->lines as $line) + { + $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration); + } + + // Hook of thirdparty module + if (is_object($hookmanager)) + { + $parameters=array('objFrom'=>$objFrom); + $action=''; + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) $error++; + } + + // Call trigger + $result=$this->call_trigger('INTERVENTION_CLONE',$user); + if ($result < 0) $error++; + // End call triggers + } + + unset($this->context['createfromclone']); + + // End + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -1; + } + } /** @@ -1338,7 +1338,7 @@ class FichinterLigne extends CommonObjectLine * Insert the line into database * * @param User $user Objet user that make creation - * @param int $notrigger Disable all triggers + * @param int $notrigger Disable all triggers * @return int <0 if ko, >0 if ok */ function insert($user, $notrigger=0) @@ -1386,14 +1386,14 @@ class FichinterLigne extends CommonObjectLine $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'fichinterdet'); if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $this->id=$this->rowid; - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } + { + $this->id=$this->rowid; + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } $result=$this->update_total(); @@ -1404,10 +1404,10 @@ class FichinterLigne extends CommonObjectLine if (! $notrigger) { - // Call trigger - $result=$this->call_trigger('LINEFICHINTER_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('LINEFICHINTER_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers } } @@ -1434,7 +1434,7 @@ class FichinterLigne extends CommonObjectLine * Update intervention into database * * @param User $user Objet user that make creation - * @param int $notrigger Disable all triggers + * @param int $notrigger Disable all triggers * @return int <0 if ko, >0 if ok */ function update($user,$notrigger=0) @@ -1457,14 +1457,14 @@ class FichinterLigne extends CommonObjectLine { if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $this->id=$this->rowid; - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } + { + $this->id=$this->rowid; + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } $result=$this->update_total(); if ($result > 0) @@ -1472,10 +1472,10 @@ class FichinterLigne extends CommonObjectLine if (! $notrigger) { - // Call trigger - $result=$this->call_trigger('LINEFICHINTER_UPDATE',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('LINEFICHINTER_UPDATE',$user); + if ($result < 0) { $error++; } + // End call triggers } } @@ -1555,7 +1555,7 @@ class FichinterLigne extends CommonObjectLine * Delete a intervention line * * @param User $user Objet user that make creation - * @param int $notrigger Disable all triggers + * @param int $notrigger Disable all triggers * @return int >0 if ok, <0 if ko */ function deleteline($user,$notrigger=0) @@ -1577,14 +1577,14 @@ class FichinterLigne extends CommonObjectLine { if (! $notrigger) { - // Call trigger - $result=$this->call_trigger('LINEFICHINTER_DELETE',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers + // Call trigger + $result=$this->call_trigger('LINEFICHINTER_DELETE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers } - $this->db->commit(); - return $result; + $this->db->commit(); + return $result; } else { diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index aff4eb838af9b4fa3906deaf67dd00cc148bd6fa..8e161cda2c026b343d5ed127b8211ef5a329b988 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -39,217 +39,217 @@ require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; */ class CommandeFournisseur extends CommonOrder { - public $element='order_supplier'; - public $table_element='commande_fournisseur'; - public $table_element_line = 'commande_fournisseurdet'; - public $fk_element = 'fk_commande'; - protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - public $picto='order'; + public $element='order_supplier'; + public $table_element='commande_fournisseur'; + public $table_element_line = 'commande_fournisseurdet'; + public $fk_element = 'fk_commande'; + protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + public $picto='order'; - /** - * {@inheritdoc} - */ - protected $table_ref_field = 'ref'; + /** + * {@inheritdoc} + */ + protected $table_ref_field = 'ref'; - public $id; + public $id; /** * Supplier order reference * @var string */ - public $ref; - public $ref_supplier; - public $brouillon; - public $statut; // 0=Draft -> 1=Validated -> 2=Approved -> 3=Process runing -> 4=Received partially -> 5=Received totally -> (reopen) 4=Received partially - // -> 7=Canceled/Never received -> (reopen) 3=Process runing - // -> 6=Canceled -> (reopen) 2=Approved - // -> 9=Refused -> (reopen) 1=Validated - // Note: billed or not is on another field "billed" - public $statuts; // List of status - - public $socid; - public $fourn_id; - public $date; - public $date_valid; - public $date_approve; - public $date_approve2; // Used when SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set - public $date_commande; - - /** - * Delivery date - */ - public $date_livraison; - public $total_ht; - public $total_tva; - public $total_localtax1; // Total Local tax 1 - public $total_localtax2; // Total Local tax 2 - public $total_ttc; - public $source; + public $ref; + public $ref_supplier; + public $brouillon; + public $statut; // 0=Draft -> 1=Validated -> 2=Approved -> 3=Process runing -> 4=Received partially -> 5=Received totally -> (reopen) 4=Received partially + // -> 7=Canceled/Never received -> (reopen) 3=Process runing + // -> 6=Canceled -> (reopen) 2=Approved + // -> 9=Refused -> (reopen) 1=Validated + // Note: billed or not is on another field "billed" + public $statuts; // List of status + + public $socid; + public $fourn_id; + public $date; + public $date_valid; + public $date_approve; + public $date_approve2; // Used when SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set + public $date_commande; + + /** + * Delivery date + */ + public $date_livraison; + public $total_ht; + public $total_tva; + public $total_localtax1; // Total Local tax 1 + public $total_localtax2; // Total Local tax 2 + public $total_ttc; + public $source; /** * @deprecated * @see note_private, note_public */ - public $note; + public $note; public $note_private; - public $note_public; - public $model_pdf; - public $fk_project; - public $cond_reglement_id; - public $cond_reglement_code; - public $fk_account; - public $mode_reglement_id; - public $mode_reglement_code; - public $user_author_id; - public $user_valid_id; - public $user_approve_id; - public $user_approve_id2; // Used when SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set + public $note_public; + public $model_pdf; + public $fk_project; + public $cond_reglement_id; + public $cond_reglement_code; + public $fk_account; + public $mode_reglement_id; + public $mode_reglement_code; + public $user_author_id; + public $user_valid_id; + public $user_approve_id; + public $user_approve_id2; // Used when SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set //Incoterms - public $fk_incoterms; - public $location_incoterms; - public $libelle_incoterms; //Used into tooltip + public $fk_incoterms; + public $location_incoterms; + public $libelle_incoterms; //Used into tooltip - public $extraparams=array(); + public $extraparams=array(); /** * @var CommandeFournisseurLigne[] */ public $lines = array(); //Add for supplier_proposal - public $origin; - public $origin_id; - public $linked_objects=array(); + public $origin; + public $origin_id; + public $linked_objects=array(); // Multicurrency - public $fk_multicurrency; - public $multicurrency_code; - public $multicurrency_tx; - public $multicurrency_total_ht; - public $multicurrency_total_tva; - public $multicurrency_total_ttc; + public $fk_multicurrency; + public $multicurrency_code; + public $multicurrency_tx; + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; + + /** + * Draft status + */ + const STATUS_DRAFT = 0; - /** - * Draft status - */ - const STATUS_DRAFT = 0; + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf; + + $this->db = $db; + $this->products = array(); + + // List of language codes for status + $this->statuts[0] = 'StatusOrderDraft'; + $this->statuts[1] = 'StatusOrderValidated'; + $this->statuts[2] = 'StatusOrderApproved'; + if (empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) $this->statuts[3] = 'StatusOrderOnProcess'; + else $this->statuts[3] = 'StatusOrderOnProcessWithValidation'; + $this->statuts[4] = 'StatusOrderReceivedPartially'; + $this->statuts[5] = 'StatusOrderReceivedAll'; + $this->statuts[6] = 'StatusOrderCanceled'; // Approved->Canceled + $this->statuts[7] = 'StatusOrderCanceled'; // Process running->canceled + //$this->statuts[8] = 'StatusOrderBilled'; // Everything is finished, order received totally and bill received + $this->statuts[9] = 'StatusOrderRefused'; + } + /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - global $conf; - - $this->db = $db; - $this->products = array(); - - // List of language codes for status - $this->statuts[0] = 'StatusOrderDraft'; - $this->statuts[1] = 'StatusOrderValidated'; - $this->statuts[2] = 'StatusOrderApproved'; - if (empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) $this->statuts[3] = 'StatusOrderOnProcess'; - else $this->statuts[3] = 'StatusOrderOnProcessWithValidation'; - $this->statuts[4] = 'StatusOrderReceivedPartially'; - $this->statuts[5] = 'StatusOrderReceivedAll'; - $this->statuts[6] = 'StatusOrderCanceled'; // Approved->Canceled - $this->statuts[7] = 'StatusOrderCanceled'; // Process running->canceled - //$this->statuts[8] = 'StatusOrderBilled'; // Everything is finished, order received totally and bill received - $this->statuts[9] = 'StatusOrderRefused'; - } - - - /** - * Get object and lines from database - * - * @param int $id Id of order to load - * @param string $ref Ref of object - * @return int >0 if OK, <0 if KO, 0 if not found - */ - public function fetch($id,$ref='') - { - global $conf; - - // Check parameters - if (empty($id) && empty($ref)) return -1; - - $sql = "SELECT c.rowid, c.ref, ref_supplier, c.fk_soc, c.fk_statut, c.amount_ht, c.total_ht, c.total_ttc, c.tva as total_vat,"; - $sql.= " c.localtax1, c.localtax2, "; - $sql.= " c.date_creation, c.date_valid, c.date_approve, c.date_approve2,"; - $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_approve, c.fk_user_approve2,"; - $sql.= " c.date_commande as date_commande, c.date_livraison as date_livraison, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_projet as fk_project, c.remise_percent, c.source, c.fk_input_method,"; - $sql.= " c.fk_account,"; - $sql.= " c.note_private, c.note_public, c.model_pdf, c.extraparams, c.billed,"; + * Get object and lines from database + * + * @param int $id Id of order to load + * @param string $ref Ref of object + * @return int >0 if OK, <0 if KO, 0 if not found + */ + public function fetch($id,$ref='') + { + global $conf; + + // Check parameters + if (empty($id) && empty($ref)) return -1; + + $sql = "SELECT c.rowid, c.ref, ref_supplier, c.fk_soc, c.fk_statut, c.amount_ht, c.total_ht, c.total_ttc, c.tva as total_vat,"; + $sql.= " c.localtax1, c.localtax2, "; + $sql.= " c.date_creation, c.date_valid, c.date_approve, c.date_approve2,"; + $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_approve, c.fk_user_approve2,"; + $sql.= " c.date_commande as date_commande, c.date_livraison as date_livraison, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_projet as fk_project, c.remise_percent, c.source, c.fk_input_method,"; + $sql.= " c.fk_account,"; + $sql.= " c.note_private, c.note_public, c.model_pdf, c.extraparams, c.billed,"; $sql.= " c.fk_multicurrency, c.multicurrency_code, c.multicurrency_tx, c.multicurrency_total_ht, c.multicurrency_total_tva, c.multicurrency_total_ttc,"; - $sql.= " cm.libelle as methode_commande,"; - $sql.= " cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle,"; - $sql.= " p.code as mode_reglement_code, p.libelle as mode_reglement_libelle"; - $sql.= ', c.fk_incoterms, c.location_incoterms'; - $sql.= ', i.libelle as libelle_incoterms'; - $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_payment_term as cr ON (c.fk_cond_reglement = cr.rowid AND cr.entity = " . getEntity('c_payment_term') . ")"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON (c.fk_mode_reglement = p.id AND p.entity = " . getEntity('c_paiement') . ")"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_input_method as cm ON cm.rowid = c.fk_input_method"; + $sql.= " cm.libelle as methode_commande,"; + $sql.= " cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle,"; + $sql.= " p.code as mode_reglement_code, p.libelle as mode_reglement_libelle"; + $sql.= ', c.fk_incoterms, c.location_incoterms'; + $sql.= ', i.libelle as libelle_incoterms'; + $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_payment_term as cr ON (c.fk_cond_reglement = cr.rowid AND cr.entity = " . getEntity('c_payment_term') . ")"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON (c.fk_mode_reglement = p.id AND p.entity = " . getEntity('c_paiement') . ")"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_input_method as cm ON cm.rowid = c.fk_input_method"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid'; - $sql.= " WHERE c.entity = ".$conf->entity; - if ($ref) $sql.= " AND c.ref='".$this->db->escape($ref)."'"; - else $sql.= " AND c.rowid=".$id; - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - if (! $obj) - { - $this->error='Bill with id '.$id.' not found'; - dol_syslog(get_class($this).'::fetch '.$this->error); - return 0; - } - - $this->id = $obj->rowid; - $this->ref = $obj->ref; - $this->ref_supplier = $obj->ref_supplier; - $this->socid = $obj->fk_soc; - $this->fourn_id = $obj->fk_soc; - $this->statut = $obj->fk_statut; - $this->billed = $obj->billed; - $this->user_author_id = $obj->fk_user_author; - $this->user_valid_id = $obj->fk_user_valid; - $this->user_approve_id = $obj->fk_user_approve; - $this->user_approve_id2 = $obj->fk_user_approve2; - $this->total_ht = $obj->total_ht; - $this->total_tva = $obj->total_vat; - $this->total_localtax1 = $obj->localtax1; - $this->total_localtax2 = $obj->localtax2; - $this->total_ttc = $obj->total_ttc; - $this->date = $this->db->jdate($obj->date_creation); - $this->date_valid = $this->db->jdate($obj->date_valid); - $this->date_approve = $this->db->jdate($obj->date_approve); - $this->date_approve2 = $this->db->jdate($obj->date_approve2); - $this->date_commande = $this->db->jdate($obj->date_commande); // date we make the order to supplier + $sql.= " WHERE c.entity = ".$conf->entity; + if ($ref) $sql.= " AND c.ref='".$this->db->escape($ref)."'"; + else $sql.= " AND c.rowid=".$id; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + if (! $obj) + { + $this->error='Bill with id '.$id.' not found'; + dol_syslog(get_class($this).'::fetch '.$this->error); + return 0; + } + + $this->id = $obj->rowid; + $this->ref = $obj->ref; + $this->ref_supplier = $obj->ref_supplier; + $this->socid = $obj->fk_soc; + $this->fourn_id = $obj->fk_soc; + $this->statut = $obj->fk_statut; + $this->billed = $obj->billed; + $this->user_author_id = $obj->fk_user_author; + $this->user_valid_id = $obj->fk_user_valid; + $this->user_approve_id = $obj->fk_user_approve; + $this->user_approve_id2 = $obj->fk_user_approve2; + $this->total_ht = $obj->total_ht; + $this->total_tva = $obj->total_vat; + $this->total_localtax1 = $obj->localtax1; + $this->total_localtax2 = $obj->localtax2; + $this->total_ttc = $obj->total_ttc; + $this->date = $this->db->jdate($obj->date_creation); + $this->date_valid = $this->db->jdate($obj->date_valid); + $this->date_approve = $this->db->jdate($obj->date_approve); + $this->date_approve2 = $this->db->jdate($obj->date_approve2); + $this->date_commande = $this->db->jdate($obj->date_commande); // date we make the order to supplier $this->date_livraison = $this->db->jdate($obj->date_livraison); - $this->remise_percent = $obj->remise_percent; - $this->methode_commande_id = $obj->fk_input_method; - $this->methode_commande = $obj->methode_commande; - - $this->source = $obj->source; - $this->fk_project = $obj->fk_project; - $this->cond_reglement_id = $obj->fk_cond_reglement; - $this->cond_reglement_code = $obj->cond_reglement_code; - $this->cond_reglement = $obj->cond_reglement_libelle; - $this->cond_reglement_doc = $obj->cond_reglement_libelle; - $this->fk_account = $obj->fk_account; - $this->mode_reglement_id = $obj->fk_mode_reglement; - $this->mode_reglement_code = $obj->mode_reglement_code; - $this->mode_reglement = $obj->mode_reglement_libelle; - $this->note = $obj->note_private; // deprecated - $this->note_private = $obj->note_private; - $this->note_public = $obj->note_public; - $this->modelpdf = $obj->model_pdf; + $this->remise_percent = $obj->remise_percent; + $this->methode_commande_id = $obj->fk_input_method; + $this->methode_commande = $obj->methode_commande; + + $this->source = $obj->source; + $this->fk_project = $obj->fk_project; + $this->cond_reglement_id = $obj->fk_cond_reglement; + $this->cond_reglement_code = $obj->cond_reglement_code; + $this->cond_reglement = $obj->cond_reglement_libelle; + $this->cond_reglement_doc = $obj->cond_reglement_libelle; + $this->fk_account = $obj->fk_account; + $this->mode_reglement_id = $obj->fk_mode_reglement; + $this->mode_reglement_code = $obj->mode_reglement_code; + $this->mode_reglement = $obj->mode_reglement_libelle; + $this->note = $obj->note_private; // deprecated + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->modelpdf = $obj->model_pdf; //Incoterms $this->fk_incoterms = $obj->fk_incoterms; @@ -264,86 +264,86 @@ class CommandeFournisseur extends CommonOrder $this->multicurrency_total_tva = $obj->multicurrency_total_tva; $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc; - $this->extraparams = (array) json_decode($obj->extraparams, true); + $this->extraparams = (array) json_decode($obj->extraparams, true); - $this->db->free($resql); + $this->db->free($resql); - // Retrieve all extrafields - // fetch optionals attributes and labels - require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); - $extrafields=new ExtraFields($this->db); - $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); - $this->fetch_optionals($this->id,$extralabels); + // Retrieve all extrafields + // fetch optionals attributes and labels + require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); - if ($this->statut == 0) $this->brouillon = 1; + if ($this->statut == 0) $this->brouillon = 1; $this->fetchObjectLinked(); //$result=$this->fetch_lines(); - $this->lines=array(); - - $sql = "SELECT l.rowid, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,"; - $sql.= " l.vat_src_code, l.tva_tx, l.remise_percent, l.subprice,"; - $sql.= " l.localtax1_tx, l. localtax2_tx, l.localtax1_type, l. localtax2_type, l.total_localtax1, l.total_localtax2,"; - $sql.= " l.total_ht, l.total_tva, l.total_ttc, l.special_code, l.fk_parent_line, l.rang,"; - $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc,"; - $sql.= " l.fk_unit,"; - $sql.= " l.date_start, l.date_end,"; + $this->lines=array(); + + $sql = "SELECT l.rowid, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,"; + $sql.= " l.vat_src_code, l.tva_tx, l.remise_percent, l.subprice,"; + $sql.= " l.localtax1_tx, l. localtax2_tx, l.localtax1_type, l. localtax2_type, l.total_localtax1, l.total_localtax2,"; + $sql.= " l.total_ht, l.total_tva, l.total_ttc, l.special_code, l.fk_parent_line, l.rang,"; + $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc,"; + $sql.= " l.fk_unit,"; + $sql.= " l.date_start, l.date_end,"; $sql.= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc'; - $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l"; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; - $sql.= " WHERE l.fk_commande = ".$this->id; - $sql.= " ORDER BY l.rang, l.rowid"; - //print $sql; - - dol_syslog(get_class($this)."::fetch get lines", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - - $line = new CommandeFournisseurLigne($this->db); - - $line->id = $objp->rowid; - $line->desc = $objp->description; - $line->description = $objp->description; - $line->qty = $objp->qty; - $line->tva_tx = $objp->tva_tx; - $line->localtax1_tx = $objp->localtax1_tx; - $line->localtax2_tx = $objp->localtax2_tx; - $line->localtax1_type = $objp->localtax1_type; - $line->localtax2_type = $objp->localtax2_type; - $line->subprice = $objp->subprice; - $line->pu_ht = $objp->subprice; - $line->remise_percent = $objp->remise_percent; - - $line->vat_src_code = $objp->vat_src_code; - $line->total_ht = $objp->total_ht; - $line->total_tva = $objp->total_tva; - $line->total_localtax1 = $objp->total_localtax1; - $line->total_localtax2 = $objp->total_localtax2; - $line->total_ttc = $objp->total_ttc; - $line->product_type = $objp->product_type; - - $line->fk_product = $objp->fk_product; - - $line->libelle = $objp->product_label; - $line->product_label = $objp->product_label; - $line->product_desc = $objp->product_desc; - - $line->ref = $objp->product_ref; // Ref of product - $line->product_ref = $objp->product_ref; // Ref of product - $line->ref_fourn = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since - $line->ref_supplier = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since - - $line->date_start = $this->db->jdate($objp->date_start); - $line->date_end = $this->db->jdate($objp->date_end); - $line->fk_unit = $objp->fk_unit; + $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l"; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; + $sql.= " WHERE l.fk_commande = ".$this->id; + $sql.= " ORDER BY l.rang, l.rowid"; + //print $sql; + + dol_syslog(get_class($this)."::fetch get lines", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + + $line = new CommandeFournisseurLigne($this->db); + + $line->id = $objp->rowid; + $line->desc = $objp->description; + $line->description = $objp->description; + $line->qty = $objp->qty; + $line->tva_tx = $objp->tva_tx; + $line->localtax1_tx = $objp->localtax1_tx; + $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; + $line->subprice = $objp->subprice; + $line->pu_ht = $objp->subprice; + $line->remise_percent = $objp->remise_percent; + + $line->vat_src_code = $objp->vat_src_code; + $line->total_ht = $objp->total_ht; + $line->total_tva = $objp->total_tva; + $line->total_localtax1 = $objp->total_localtax1; + $line->total_localtax2 = $objp->total_localtax2; + $line->total_ttc = $objp->total_ttc; + $line->product_type = $objp->product_type; + + $line->fk_product = $objp->fk_product; + + $line->libelle = $objp->product_label; + $line->product_label = $objp->product_label; + $line->product_desc = $objp->product_desc; + + $line->ref = $objp->product_ref; // Ref of product + $line->product_ref = $objp->product_ref; // Ref of product + $line->ref_fourn = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since + $line->ref_supplier = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since + + $line->date_start = $this->db->jdate($objp->date_start); + $line->date_end = $this->db->jdate($objp->date_end); + $line->fk_unit = $objp->fk_unit; // Multicurrency $line->fk_multicurrency = $objp->fk_multicurrency; @@ -353,924 +353,924 @@ class CommandeFournisseur extends CommonOrder $line->multicurrency_total_tva = $objp->multicurrency_total_tva; $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc; - $line->special_code = $objp->special_code; - $line->fk_parent_line = $objp->fk_parent_line; - - $line->rang = $objp->rang; - - $this->lines[$i] = $line; - - $i++; - } - $this->db->free($result); - - return 1; - } - else - { - $this->error=$this->db->error()." sql=".$sql; - return -1; - } - } - else - { - $this->error=$this->db->error()." sql=".$sql; - return -1; - } - } - - /** - * Validate an order - * - * @param User $user Validator User - * @param int $idwarehouse Id of warehouse to use for stock decrease - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - public function valid($user,$idwarehouse=0,$notrigger=0) - { - global $langs,$conf; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $error=0; - - dol_syslog(get_class($this)."::valid"); - $result = 0; - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->commande->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_order_advance->validate))) - { - $this->db->begin(); - - // Definition of supplier order numbering model name - $soc = new Societe($this->db); - $soc->fetch($this->fourn_id); - - // Check if object has a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life - { - $num = $this->getNextNumRef($soc); - } - else - { - $num = $this->ref; - } - $this->newref = $num; - - $sql = 'UPDATE '.MAIN_DB_PREFIX."commande_fournisseur"; - $sql.= " SET ref='".$this->db->escape($num)."',"; - $sql.= " fk_statut = 1,"; - $sql.= " date_valid='".$this->db->idate(dol_now())."',"; - $sql.= " fk_user_valid = ".$user->id; - $sql.= " WHERE rowid = ".$this->id; - $sql.= " AND fk_statut = 0"; - - $resql=$this->db->query($sql); - if (! $resql) - { - dol_print_error($this->db); - $error++; - } - - if (! $error && ! $notrigger) - { + $line->special_code = $objp->special_code; + $line->fk_parent_line = $objp->fk_parent_line; + + $line->rang = $objp->rang; + + $this->lines[$i] = $line; + + $i++; + } + $this->db->free($result); + + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + return -1; + } + } + else + { + $this->error=$this->db->error()." sql=".$sql; + return -1; + } + } + + /** + * Validate an order + * + * @param User $user Validator User + * @param int $idwarehouse Id of warehouse to use for stock decrease + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + public function valid($user,$idwarehouse=0,$notrigger=0) + { + global $langs,$conf; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error=0; + + dol_syslog(get_class($this)."::valid"); + $result = 0; + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->commande->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_order_advance->validate))) + { + $this->db->begin(); + + // Definition of supplier order numbering model name + $soc = new Societe($this->db); + $soc->fetch($this->fourn_id); + + // Check if object has a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef($soc); + } + else + { + $num = $this->ref; + } + $this->newref = $num; + + $sql = 'UPDATE '.MAIN_DB_PREFIX."commande_fournisseur"; + $sql.= " SET ref='".$this->db->escape($num)."',"; + $sql.= " fk_statut = 1,"; + $sql.= " date_valid='".$this->db->idate(dol_now())."',"; + $sql.= " fk_user_valid = ".$user->id; + $sql.= " WHERE rowid = ".$this->id; + $sql.= " AND fk_statut = 0"; + + $resql=$this->db->query($sql); + if (! $resql) + { + dol_print_error($this->db); + $error++; + } + + if (! $error && ! $notrigger) + { // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_VALIDATE',$user); if ($result < 0) $error++; // End call triggers - } - - if (! $error) - { - $this->oldref = $this->ref; - - // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - // We rename directory ($this->ref = ancienne ref, $num = nouvelle ref) - // in order not to lose the attached files - $oldref = dol_sanitizeFileName($this->ref); - $newref = dol_sanitizeFileName($num); - $dirsource = $conf->fournisseur->commande->dir_output.'/'.$oldref; - $dirdest = $conf->fournisseur->commande->dir_output.'/'.$newref; - if (file_exists($dirsource)) - { - dol_syslog(get_class($this)."::valid rename dir ".$dirsource." into ".$dirdest); - - if (@rename($dirsource, $dirdest)) - { - dol_syslog("Rename ok"); - // Rename docs starting with $oldref with $newref - $listoffiles=dol_dir_list($conf->fournisseur->commande->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); - foreach($listoffiles as $fileentry) - { - $dirsource=$fileentry['name']; - $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); - $dirsource=$fileentry['path'].'/'.$dirsource; - $dirdest=$fileentry['path'].'/'.$dirdest; - @rename($dirsource, $dirdest); - } - } - } - } - } - - if (! $error) - { - $result = 1; - $this->statut = 1; - $this->ref = $num; - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error='NotAuthorized'; - dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); - return -1; - } - } - - /** - * Return label of the status of object - * + } + + if (! $error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // We rename directory ($this->ref = ancienne ref, $num = nouvelle ref) + // in order not to lose the attached files + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->fournisseur->commande->dir_output.'/'.$oldref; + $dirdest = $conf->fournisseur->commande->dir_output.'/'.$newref; + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::valid rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->fournisseur->commande->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + if (! $error) + { + $result = 1; + $this->statut = 1; + $this->ref = $num; + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error='NotAuthorized'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + } + } + + /** + * Return label of the status of object + * * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=short label + picto - * @return string Label - */ - public function getLibStatut($mode=0) - { - return $this->LibStatut($this->statut,$mode,$this->billed); - } - - /** - * Return label of a status - * - * @param int $statut Id statut - * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto - * @param int $billed 1=Billed - * @return string Label of status - */ - function LibStatut($statut,$mode=0,$billed=0) - { - global $langs; - $langs->load('orders'); - - $billedtext=''; + * @return string Label + */ + public function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut,$mode,$this->billed); + } + + /** + * Return label of a status + * + * @param int $statut Id statut + * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto + * @param int $billed 1=Billed + * @return string Label of status + */ + function LibStatut($statut,$mode=0,$billed=0) + { + global $langs; + $langs->load('orders'); + + $billedtext=''; //if ($statut==5 && $this->billed == 1) $statut = 8; - if ($billed == 1) $billedtext=$langs->trans("Billed"); - - // List of language codes for status - $statutshort[0] = 'StatusOrderDraftShort'; - $statutshort[1] = 'StatusOrderValidatedShort'; - $statutshort[2] = 'StatusOrderApprovedShort'; - $statutshort[3] = 'StatusOrderOnProcessShort'; - $statutshort[4] = 'StatusOrderReceivedPartiallyShort'; - $statutshort[5] = 'StatusOrderReceivedAllShort'; - $statutshort[6] = 'StatusOrderCanceledShort'; - $statutshort[7] = 'StatusOrderCanceledShort'; - //$statutshort[8] = 'StatusOrderBilledShort'; - $statutshort[9] = 'StatusOrderRefusedShort'; - - if ($mode == 0) - { - return $langs->trans($this->statuts[$statut]); - } - if ($mode == 1) - { - return $langs->trans($statutshort[$statut]); - } - if ($mode == 2) - { - return $langs->trans($this->statuts[$statut]); - } - if ($mode == 3) - { - if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0'); - if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1'); - if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3'); - if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3'); - if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3'); - if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6'); - if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5'); + if ($billed == 1) $billedtext=$langs->trans("Billed"); + + // List of language codes for status + $statutshort[0] = 'StatusOrderDraftShort'; + $statutshort[1] = 'StatusOrderValidatedShort'; + $statutshort[2] = 'StatusOrderApprovedShort'; + $statutshort[3] = 'StatusOrderOnProcessShort'; + $statutshort[4] = 'StatusOrderReceivedPartiallyShort'; + $statutshort[5] = 'StatusOrderReceivedAllShort'; + $statutshort[6] = 'StatusOrderCanceledShort'; + $statutshort[7] = 'StatusOrderCanceledShort'; + //$statutshort[8] = 'StatusOrderBilledShort'; + $statutshort[9] = 'StatusOrderRefusedShort'; + + if ($mode == 0) + { + return $langs->trans($this->statuts[$statut]); + } + if ($mode == 1) + { + return $langs->trans($statutshort[$statut]); + } + if ($mode == 2) + { + return $langs->trans($this->statuts[$statut]); + } + if ($mode == 3) + { + if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0'); + if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1'); + if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3'); + if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3'); + if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3'); + if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6'); + if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5'); if ($statut==8) return img_picto($langs->trans($this->statuts[$statut]),'statut6'); - if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5'); - } - if ($mode == 4) - { - if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5'); + } + if ($mode == 4) + { + if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); if ($statut==8) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); - } - if ($mode == 5) - { - if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut0'); - if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut1'); - if ($statut==2) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3'); - if ($statut==3) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3'); - if ($statut==4) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3'); - if ($statut==5) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6'); - if ($statut==6 || $statut==7) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5'); - if ($statut==8) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6'); - if ($statut==9) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5'); - } - } - - - /** - * Return clicable name (with picto eventually) - * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param string $option On what the link points - * @param int $notooltip 1=Disable tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string Chain with URL - */ - public function getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1) - { - global $langs, $conf; - - $result=''; - $label = '<u>' . $langs->trans("ShowOrder") . '</u>'; - if (! empty($this->ref)) - $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; - if (! empty($this->ref_supplier)) - $label.= '<br><b>' . $langs->trans('RefSupplier') . ':</b> ' . $this->ref_supplier; - if (! empty($this->total_ht)) - $label.= '<br><b>' . $langs->trans('AmountHT') . ':</b> ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_tva)) - $label.= '<br><b>' . $langs->trans('VAT') . ':</b> ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - if (! empty($this->total_ttc)) - $label.= '<br><b>' . $langs->trans('AmountTTC') . ':</b> ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - - $picto='order'; - $url = DOL_URL_ROOT.'/fourn/commande/card.php?id='.$this->id; - - if ($option !== 'nolink') - { - // Add param to save lastsearch_values or not - $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; - if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; - } - - $linkclose=''; - if (empty($notooltip)) - { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label=$langs->trans("ShowOrder"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip"'; - } - - $linkstart = '<a href="'.$url.'"'; - $linkstart.=$linkclose.'>'; - $linkend='</a>'; - - if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - $result.=$linkstart.$this->ref.$linkend; - return $result; - } - - - /** - * Returns the following order reference not used depending on the numbering model activated - * defined within COMMANDE_SUPPLIER_ADDON_NUMBER - * - * @param Company $soc company object - * @return string free reference for the invoice - */ - public function getNextNumRef($soc) - { - global $db, $langs, $conf; - $langs->load("orders"); - - if (! empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER)) - { - $mybool = false; - - $file = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER.'.php'; - $classname=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER; - - // Include file with class - $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); - - foreach ($dirmodels as $reldir) { - - $dir = dol_buildpath($reldir."core/modules/supplier_order/"); - - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } - - if (! $mybool) - { - dol_print_error('',"Failed to include file ".$file); - return ''; - } - - $obj = new $classname(); - $numref = $obj->getNextValue($soc,$this); - - if ( $numref != "") - { - return $numref; - } - else - { - $this->error = $obj->error; - return -1; - } - } - else - { - $this->error = "Error_COMMANDE_SUPPLIER_ADDON_NotDefined"; - return -2; - } - } + if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:''); + } + if ($mode == 5) + { + if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut0'); + if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut1'); + if ($statut==2) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3'); + if ($statut==3) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3'); + if ($statut==4) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3'); + if ($statut==5) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6'); + if ($statut==6 || $statut==7) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5'); + if ($statut==8) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6'); + if ($statut==9) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5'); + } + } + + + /** + * Return clicable name (with picto eventually) + * + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param string $option On what the link points + * @param int $notooltip 1=Disable tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string Chain with URL + */ + public function getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1) + { + global $langs, $conf; + + $result=''; + $label = '<u>' . $langs->trans("ShowOrder") . '</u>'; + if (! empty($this->ref)) + $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; + if (! empty($this->ref_supplier)) + $label.= '<br><b>' . $langs->trans('RefSupplier') . ':</b> ' . $this->ref_supplier; + if (! empty($this->total_ht)) + $label.= '<br><b>' . $langs->trans('AmountHT') . ':</b> ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_tva)) + $label.= '<br><b>' . $langs->trans('VAT') . ':</b> ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + if (! empty($this->total_ttc)) + $label.= '<br><b>' . $langs->trans('AmountTTC') . ':</b> ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + + $picto='order'; + $url = DOL_URL_ROOT.'/fourn/commande/card.php?id='.$this->id; + + if ($option !== 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; + if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; + } + + $linkclose=''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowOrder"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; + } + + $linkstart = '<a href="'.$url.'"'; + $linkstart.=$linkclose.'>'; + $linkend='</a>'; + + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); + if ($withpicto && $withpicto != 2) $result.=' '; + $result.=$linkstart.$this->ref.$linkend; + return $result; + } + + + /** + * Returns the following order reference not used depending on the numbering model activated + * defined within COMMANDE_SUPPLIER_ADDON_NUMBER + * + * @param Company $soc company object + * @return string free reference for the invoice + */ + public function getNextNumRef($soc) + { + global $db, $langs, $conf; + $langs->load("orders"); + + if (! empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER)) + { + $mybool = false; + + $file = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER.'.php'; + $classname=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/supplier_order/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } + + $obj = new $classname(); + $numref = $obj->getNextValue($soc,$this); + + if ( $numref != "") + { + return $numref; + } + else + { + $this->error = $obj->error; + return -1; + } + } + else + { + $this->error = "Error_COMMANDE_SUPPLIER_ADDON_NotDefined"; + return -2; + } + } /** - * Class invoiced the supplier order - * - * @param User $user Object user making the change - * @return int <0 if KO, >0 if KO - */ - public function classifyBilled(User $user) - { - $error=0; - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur SET billed = 1'; - $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0 '; - if ($this->db->query($sql)) - { - if (! $error) - { - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_CLASSIFY_BILLED',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->billed=1; - - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - dol_print_error($this->db); - - $this->db->rollback(); + * Class invoiced the supplier order + * + * @param User $user Object user making the change + * @return int <0 if KO, >0 if KO + */ + public function classifyBilled(User $user) + { + $error=0; + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur SET billed = 1'; + $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0 '; + if ($this->db->query($sql)) + { + if (! $error) + { + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_CLASSIFY_BILLED',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->billed=1; + + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + dol_print_error($this->db); + + $this->db->rollback(); return -1; - } - } - - /** - * Approve a supplier order - * - * @param User $user Object user - * @param int $idwarehouse Id of warhouse for stock change - * @param int $secondlevel 0=Standard approval, 1=Second level approval (used when option SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set) - * @return int <0 if KO, >0 if OK - */ - public function approve($user, $idwarehouse=0, $secondlevel=0) - { - global $langs,$conf; + } + } + + /** + * Approve a supplier order + * + * @param User $user Object user + * @param int $idwarehouse Id of warhouse for stock change + * @param int $secondlevel 0=Standard approval, 1=Second level approval (used when option SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set) + * @return int <0 if KO, >0 if OK + */ + public function approve($user, $idwarehouse=0, $secondlevel=0) + { + global $langs,$conf; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $error=0; + $error=0; - dol_syslog(get_class($this)."::approve"); + dol_syslog(get_class($this)."::approve"); - if ($user->rights->fournisseur->commande->approuver) - { - $now = dol_now(); + if ($user->rights->fournisseur->commande->approuver) + { + $now = dol_now(); - $this->db->begin(); + $this->db->begin(); // Definition of order numbering model name - $soc = new Societe($this->db); - $soc->fetch($this->fourn_id); + $soc = new Societe($this->db); + $soc->fetch($this->fourn_id); - // Check if object has a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life - { - $num = $this->getNextNumRef($soc); - } - else + // Check if object has a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef($soc); + } + else { - $num = $this->ref; - } - $this->newref = $num; + $num = $this->ref; + } + $this->newref = $num; - // Do we have to change status now ? (If double approval is required and first approval, we keep status to 1 = validated) + // Do we have to change status now ? (If double approval is required and first approval, we keep status to 1 = validated) $movetoapprovestatus=true; $comment=''; - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; $sql.= " SET ref='".$this->db->escape($num)."',"; if (empty($secondlevel)) // standard or first level approval { - $sql.= " date_approve='".$this->db->idate($now)."',"; - $sql.= " fk_user_approve = ".$user->id; - if (! empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $this->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) - { - if (empty($this->user_approve_id2)) - { - $movetoapprovestatus=false; // second level approval not done - $comment=' (first level)'; - } - } + $sql.= " date_approve='".$this->db->idate($now)."',"; + $sql.= " fk_user_approve = ".$user->id; + if (! empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $this->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) + { + if (empty($this->user_approve_id2)) + { + $movetoapprovestatus=false; // second level approval not done + $comment=' (first level)'; + } + } } else // request a second level approval { - $sql.= " date_approve2='".$this->db->idate($now)."',"; - $sql.= " fk_user_approve2 = ".$user->id; - if (empty($this->user_approve_id)) $movetoapprovestatus=false; // first level approval not done - $comment=' (second level)'; + $sql.= " date_approve2='".$this->db->idate($now)."',"; + $sql.= " fk_user_approve2 = ".$user->id; + if (empty($this->user_approve_id)) $movetoapprovestatus=false; // first level approval not done + $comment=' (second level)'; } // If double approval is required and first approval, we keep status to 1 = validated if ($movetoapprovestatus) $sql.= ", fk_statut = 2"; else $sql.= ", fk_statut = 1"; - $sql.= " WHERE rowid = ".$this->id; - $sql.= " AND fk_statut = 1"; + $sql.= " WHERE rowid = ".$this->id; + $sql.= " AND fk_statut = 1"; - if ($this->db->query($sql)) - { - if (! empty($conf->global->SUPPLIER_ORDER_AUTOADD_USER_CONTACT)) - { + if ($this->db->query($sql)) + { + if (! empty($conf->global->SUPPLIER_ORDER_AUTOADD_USER_CONTACT)) + { $result=$this->add_contact($user->id, 'SALESREPFOLL', 'internal', 1); if ($result < 0 && $result != -2) // -2 means already exists { $error++; } - } - - // If stock is incremented on validate order, we must increment it - if (! $error && $movetoapprovestatus && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)) - { - require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; - $langs->load("agenda"); - - $cpt=count($this->lines); - for ($i = 0; $i < $cpt; $i++) - { - // Product with reference - if ($this->lines[$i]->fk_product > 0) - { - $this->line = $this->lines[$i]; - $mouvP = new MouvementStock($this->db); - $mouvP->origin = &$this; - // We decrement stock of product (and sub-products) - $up_ht_disc=$this->lines[$i]->subprice; - if (! empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) $up_ht_disc=price2num($up_ht_disc * (100 - $this->lines[$i]->remise_percent) / 100, 'MU'); - $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("OrderApprovedInDolibarr",$this->ref)); - if ($result < 0) { $error++; } - unset($this->line); - } - } - } - - if (! $error) - { + } + + // If stock is incremented on validate order, we must increment it + if (! $error && $movetoapprovestatus && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + $langs->load("agenda"); + + $cpt=count($this->lines); + for ($i = 0; $i < $cpt; $i++) + { + // Product with reference + if ($this->lines[$i]->fk_product > 0) + { + $this->line = $this->lines[$i]; + $mouvP = new MouvementStock($this->db); + $mouvP->origin = &$this; + // We decrement stock of product (and sub-products) + $up_ht_disc=$this->lines[$i]->subprice; + if (! empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) $up_ht_disc=price2num($up_ht_disc * (100 - $this->lines[$i]->remise_percent) / 100, 'MU'); + $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("OrderApprovedInDolibarr",$this->ref)); + if ($result < 0) { $error++; } + unset($this->line); + } + } + } + + if (! $error) + { // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_APPROVE',$user); if ($result < 0) $error++; // End call triggers - } + } - if (! $error) - { - $this->ref = $this->newref; + if (! $error) + { + $this->ref = $this->newref; - if ($movetoapprovestatus) $this->statut = 2; + if ($movetoapprovestatus) $this->statut = 2; else $this->statut = 1; - if (empty($secondlevel)) // standard or first level approval + if (empty($secondlevel)) // standard or first level approval { - $this->date_approve = $now; - $this->user_approve_id = $user->id; + $this->date_approve = $now; + $this->user_approve_id = $user->id; } else // request a second level approval { - $this->date_approve2 = $now; - $this->user_approve_id2 = $user->id; + $this->date_approve2 = $now; + $this->user_approve_id2 = $user->id; } - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -1; - } - } - else - { - dol_syslog(get_class($this)."::approve Not Authorized", LOG_ERR); - } - return -1; - } - - /** - * Refuse an order - * - * @param User $user User making action - * @return int 0 if Ok, <0 if Ko - */ - public function refuse($user) - { - global $conf, $langs; + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } + else + { + dol_syslog(get_class($this)."::approve Not Authorized", LOG_ERR); + } + return -1; + } + + /** + * Refuse an order + * + * @param User $user User making action + * @return int 0 if Ok, <0 if Ko + */ + public function refuse($user) + { + global $conf, $langs; $error=0; - dol_syslog(get_class($this)."::refuse"); - $result = 0; - if ($user->rights->fournisseur->commande->approuver) - { - $this->db->begin(); + dol_syslog(get_class($this)."::refuse"); + $result = 0; + if ($user->rights->fournisseur->commande->approuver) + { + $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur SET fk_statut = 9"; - $sql .= " WHERE rowid = ".$this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur SET fk_statut = 9"; + $sql .= " WHERE rowid = ".$this->id; - if ($this->db->query($sql)) - { - $result = 0; + if ($this->db->query($sql)) + { + $result = 0; - if ($error == 0) - { + if ($error == 0) + { // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_REFUSE',$user); if ($result < 0) - { - $error++; - $this->db->rollback(); - } - else - $this->db->commit(); + { + $error++; + $this->db->rollback(); + } + else + $this->db->commit(); // End call triggers - } - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - dol_syslog(get_class($this)."::refuse Error -1"); - $result = -1; - } - } - else - { - dol_syslog(get_class($this)."::refuse Not Authorized"); - } - return $result ; - } - - /** - * Cancel an approved order. - * The cancellation is done after approval - * - * @param User $user User making action - * @param int $idwarehouse Id warehouse to use for stock change (not used for supplier orders). - * @return int >0 if Ok, <0 if Ko - */ - function Cancel($user, $idwarehouse=-1) - { - global $langs,$conf; + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::refuse Error -1"); + $result = -1; + } + } + else + { + dol_syslog(get_class($this)."::refuse Not Authorized"); + } + return $result ; + } + + /** + * Cancel an approved order. + * The cancellation is done after approval + * + * @param User $user User making action + * @param int $idwarehouse Id warehouse to use for stock change (not used for supplier orders). + * @return int >0 if Ok, <0 if Ko + */ + function Cancel($user, $idwarehouse=-1) + { + global $langs,$conf; $error=0; - //dol_syslog("CommandeFournisseur::Cancel"); - $result = 0; - if ($user->rights->fournisseur->commande->commander) - { - $statut = 6; + //dol_syslog("CommandeFournisseur::Cancel"); + $result = 0; + if ($user->rights->fournisseur->commande->commander) + { + $statut = 6; - $this->db->begin(); + $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur SET fk_statut = ".$statut; - $sql .= " WHERE rowid = ".$this->id; - dol_syslog(get_class($this)."::cancel", LOG_DEBUG); - if ($this->db->query($sql)) - { - $result = 0; + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur SET fk_statut = ".$statut; + $sql .= " WHERE rowid = ".$this->id; + dol_syslog(get_class($this)."::cancel", LOG_DEBUG); + if ($this->db->query($sql)) + { + $result = 0; // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_CANCEL',$user); if ($result < 0) $error++; // End call triggers - if ($error == 0) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - dol_syslog(get_class($this)."::cancel ".$this->error); - return -1; - } - } - else - { - dol_syslog(get_class($this)."::cancel Not Authorized"); - return -1; - } - } - - - /** - * Submit a supplier order to supplier - * - * @param User $user User making change - * @param date $date Date - * @param int $methode Method - * @param string $comment Comment - * @return int <0 if KO, >0 if OK - */ - public function commande($user, $date, $methode, $comment='') - { - global $langs; - dol_syslog(get_class($this)."::commande"); - $error = 0; - if ($user->rights->fournisseur->commande->commander) - { - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur SET fk_statut = 3, fk_input_method=".$methode.", date_commande='".$this->db->idate($date)."'"; - $sql .= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::commande", LOG_DEBUG); - if ($this->db->query($sql)) - { - $this->statut = 3; - $this->methode_commande_id = $methode; - $this->date_commande = $date; - - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_SUBMIT',$user); - if ($result < 0) $error++; - // End call triggers - } - else - { - $error++; - $this->error = $this->db->lasterror(); - $this->errors[] = $this->db->lasterror(); - } - - if (! $error) - { - $this->db->commit(); - } - else - { - $this->db->rollback(); - } - } - else - { - $error++; - $this->error = $langs->trans('NotAuthorized'); - $this->errors[] = $langs->trans('NotAuthorized'); - dol_syslog(get_class($this)."::commande User not Authorized", LOG_WARNING); - } - - return ($error ? -1 : 1); - } - - /** - * Create order with draft status - * - * @param User $user User making creation - * @param int $notrigger Disable all triggers - * @return int <0 if KO, Id of supplier order if OK - */ - public function create($user, $notrigger=0) - { - global $langs,$conf,$hookmanager; - - $this->db->begin(); - - $error=0; - $now=dol_now(); - - // Clean parameters - if (empty($this->source)) $this->source = 0; - - // Multicurrency (test on $this->multicurrency_tx because we sould take the default rate only if not using origin rate) - if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); - else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code); - if (empty($this->fk_multicurrency)) + if ($error == 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::cancel ".$this->error); + return -1; + } + } + else + { + dol_syslog(get_class($this)."::cancel Not Authorized"); + return -1; + } + } + + + /** + * Submit a supplier order to supplier + * + * @param User $user User making change + * @param date $date Date + * @param int $methode Method + * @param string $comment Comment + * @return int <0 if KO, >0 if OK + */ + public function commande($user, $date, $methode, $comment='') + { + global $langs; + dol_syslog(get_class($this)."::commande"); + $error = 0; + if ($user->rights->fournisseur->commande->commander) + { + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur SET fk_statut = 3, fk_input_method=".$methode.", date_commande='".$this->db->idate($date)."'"; + $sql .= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::commande", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->statut = 3; + $this->methode_commande_id = $methode; + $this->date_commande = $date; + + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_SUBMIT',$user); + if ($result < 0) $error++; + // End call triggers + } + else + { + $error++; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + } + + if (! $error) + { + $this->db->commit(); + } + else + { + $this->db->rollback(); + } + } + else + { + $error++; + $this->error = $langs->trans('NotAuthorized'); + $this->errors[] = $langs->trans('NotAuthorized'); + dol_syslog(get_class($this)."::commande User not Authorized", LOG_WARNING); + } + + return ($error ? -1 : 1); + } + + /** + * Create order with draft status + * + * @param User $user User making creation + * @param int $notrigger Disable all triggers + * @return int <0 if KO, Id of supplier order if OK + */ + public function create($user, $notrigger=0) + { + global $langs,$conf,$hookmanager; + + $this->db->begin(); + + $error=0; + $now=dol_now(); + + // Clean parameters + if (empty($this->source)) $this->source = 0; + + // Multicurrency (test on $this->multicurrency_tx because we sould take the default rate only if not using origin rate) + if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); + else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code); + if (empty($this->fk_multicurrency)) { $this->multicurrency_code = $conf->currency; $this->fk_multicurrency = 0; $this->multicurrency_tx = 1; } - // We set order into draft status - $this->brouillon = 1; - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseur ("; - $sql.= "ref"; - $sql.= ", ref_supplier"; - $sql.= ", note_private"; - $sql.= ", note_public"; - $sql.= ", entity"; - $sql.= ", fk_soc"; - $sql.= ", fk_projet"; - $sql.= ", date_creation"; + // We set order into draft status + $this->brouillon = 1; + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseur ("; + $sql.= "ref"; + $sql.= ", ref_supplier"; + $sql.= ", note_private"; + $sql.= ", note_public"; + $sql.= ", entity"; + $sql.= ", fk_soc"; + $sql.= ", fk_projet"; + $sql.= ", date_creation"; $sql.= ", date_livraison"; - $sql.= ", fk_user_author"; - $sql.= ", fk_statut"; - $sql.= ", source"; - $sql.= ", model_pdf"; - $sql.= ", fk_mode_reglement"; + $sql.= ", fk_user_author"; + $sql.= ", fk_statut"; + $sql.= ", source"; + $sql.= ", model_pdf"; + $sql.= ", fk_mode_reglement"; $sql.= ", fk_cond_reglement"; - $sql.= ", fk_account"; + $sql.= ", fk_account"; $sql.= ", fk_incoterms, location_incoterms"; - $sql.= ", fk_multicurrency"; - $sql.= ", multicurrency_code"; - $sql.= ", multicurrency_tx"; - $sql.= ") "; - $sql.= " VALUES ("; - $sql.= "''"; - $sql.= ", '".$this->db->escape($this->ref_supplier)."'"; - $sql.= ", '".$this->db->escape($this->note_private)."'"; - $sql.= ", '".$this->db->escape($this->note_public)."'"; - $sql.= ", ".$conf->entity; - $sql.= ", ".$this->socid; - $sql.= ", ".($this->fk_project > 0 ? $this->fk_project : "null"); - $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ", fk_multicurrency"; + $sql.= ", multicurrency_code"; + $sql.= ", multicurrency_tx"; + $sql.= ") "; + $sql.= " VALUES ("; + $sql.= "''"; + $sql.= ", '".$this->db->escape($this->ref_supplier)."'"; + $sql.= ", '".$this->db->escape($this->note_private)."'"; + $sql.= ", '".$this->db->escape($this->note_public)."'"; + $sql.= ", ".$conf->entity; + $sql.= ", ".$this->socid; + $sql.= ", ".($this->fk_project > 0 ? $this->fk_project : "null"); + $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", ".($this->date_livraison?"'".$this->db->idate($this->date_livraison)."'":"null"); - $sql.= ", ".$user->id; - $sql.= ", 0"; - $sql.= ", ".$this->db->escape($this->source); - $sql.= ", '".$conf->global->COMMANDE_SUPPLIER_ADDON_PDF."'"; - $sql.= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id : 'null'); - $sql.= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id : 'null'); - $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); - $sql.= ", ".(int) $this->fk_incoterms; - $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; + $sql.= ", ".$user->id; + $sql.= ", 0"; + $sql.= ", ".$this->db->escape($this->source); + $sql.= ", '".$conf->global->COMMANDE_SUPPLIER_ADDON_PDF."'"; + $sql.= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id : 'null'); + $sql.= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id : 'null'); + $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); + $sql.= ", ".(int) $this->fk_incoterms; + $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; $sql.= ", ".(int) $this->fk_multicurrency; $sql.= ", '".$this->db->escape($this->multicurrency_code)."'"; $sql.= ", ".(double) $this->multicurrency_tx; - $sql.= ")"; + $sql.= ")"; - dol_syslog(get_class($this)."::create", LOG_DEBUG); - if ($this->db->query($sql)) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."commande_fournisseur"); + dol_syslog(get_class($this)."::create", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."commande_fournisseur"); if ($this->id) { $num=count($this->lines); - // insert products details into database - for ($i=0;$i<$num;$i++) - { - $result = $this->addline( // This include test on qty if option SUPPLIER_ORDER_WITH_NOPRICEDEFINED is not set - $this->lines[$i]->desc, - $this->lines[$i]->subprice, - $this->lines[$i]->qty, - $this->lines[$i]->tva_tx, - $this->lines[$i]->localtax1_tx, - $this->lines[$i]->localtax2_tx, - $this->lines[$i]->fk_product, - 0, - $this->lines[$i]->ref_fourn, // $this->lines[$i]->ref_fourn comes from field ref into table of lines. Value may ba a ref that does not exists anymore, so we first try with value of product - $this->lines[$i]->remise_percent, - 'HT', - 0, - $this->lines[$i]->product_type, - $this->lines[$i]->info_bits, - false, - $this->lines[$i]->date_start, - $this->lines[$i]->date_end, - 0, - $this->lines[$i]->fk_unit - ); - if ($result < 0) - { - dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING); // do not use dol_print_error here as it may be a functionnal error - $this->db->rollback(); - return -1; - } - } - - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; - $sql.= " SET ref='(PROV".$this->id.")'"; - $sql.= " WHERE rowid=".$this->id; - dol_syslog(get_class($this)."::create", LOG_DEBUG); - if ($this->db->query($sql)) - { + // insert products details into database + for ($i=0;$i<$num;$i++) + { + $result = $this->addline( // This include test on qty if option SUPPLIER_ORDER_WITH_NOPRICEDEFINED is not set + $this->lines[$i]->desc, + $this->lines[$i]->subprice, + $this->lines[$i]->qty, + $this->lines[$i]->tva_tx, + $this->lines[$i]->localtax1_tx, + $this->lines[$i]->localtax2_tx, + $this->lines[$i]->fk_product, + 0, + $this->lines[$i]->ref_fourn, // $this->lines[$i]->ref_fourn comes from field ref into table of lines. Value may ba a ref that does not exists anymore, so we first try with value of product + $this->lines[$i]->remise_percent, + 'HT', + 0, + $this->lines[$i]->product_type, + $this->lines[$i]->info_bits, + false, + $this->lines[$i]->date_start, + $this->lines[$i]->date_end, + 0, + $this->lines[$i]->fk_unit + ); + if ($result < 0) + { + dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING); // do not use dol_print_error here as it may be a functionnal error + $this->db->rollback(); + return -1; + } + } + + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; + $sql.= " SET ref='(PROV".$this->id.")'"; + $sql.= " WHERE rowid=".$this->id; + dol_syslog(get_class($this)."::create", LOG_DEBUG); + if ($this->db->query($sql)) + { // Add link with price request and supplier order if ($this->id) - { - $this->ref="(PROV".$this->id.")"; - - // Add object linked - if (is_array($this->linked_objects) && ! empty($this->linked_objects)) - { - foreach($this->linked_objects as $origin => $origin_id) - { - $ret = $this->add_object_linked($origin, $origin_id); - if (! $ret) - { - dol_print_error($this->db); - $error++; - } - } - } - } - - if (! $error) - { - $result=$this->insertExtraFields(); - if ($result < 0) $error++; - } + { + $this->ref="(PROV".$this->id.")"; + + // Add object linked + if (is_array($this->linked_objects) && ! empty($this->linked_objects)) + { + foreach($this->linked_objects as $origin => $origin_id) + { + $ret = $this->add_object_linked($origin, $origin_id); + if (! $ret) + { + dol_print_error($this->db); + $error++; + } + } + } + } + + if (! $error) + { + $result=$this->insertExtraFields(); + if ($result < 0) $error++; + } if (! $error && ! $notrigger) - { + { // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_CREATE',$user); if ($result < 0) - { - $this->db->rollback(); - return -1; - } + { + $this->db->rollback(); + return -1; + } // End call triggers - } - - $this->db->commit(); - return $this->id; - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -2; - } - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Load an object from its id and create a new one in database - * - * @return int New id of clone - */ - public function createFromClone() - { - global $conf,$user,$langs,$hookmanager; - - $error=0; + } + + $this->db->commit(); + return $this->id; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -2; + } + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + /** + * Load an object from its id and create a new one in database + * + * @return int New id of clone + */ + public function createFromClone() + { + global $conf,$user,$langs,$hookmanager; + + $error=0; $this->context['createfromclone'] = 'createfromclone'; @@ -1279,1431 +1279,1431 @@ class CommandeFournisseur extends CommonOrder // Load source object $objFrom = clone $this; - $this->id=0; - $this->statut=0; - - // Clear fields - $this->user_author_id = $user->id; - $this->user_valid = ''; - $this->date_creation = ''; - $this->date_validation = ''; - $this->ref_supplier = ''; - $this->user_approve_id = ''; - $this->user_approve_id2 = ''; - $this->date_approve = ''; - $this->date_approve2 = ''; - - // Create clone - $result=$this->create($user); - if ($result < 0) $error++; - - if (! $error) - { - // Hook of thirdparty module - if (is_object($hookmanager)) - { - $parameters=array('objFrom'=>$objFrom); - $action=''; - $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) $error++; - } + $this->id=0; + $this->statut=0; + + // Clear fields + $this->user_author_id = $user->id; + $this->user_valid = ''; + $this->date_creation = ''; + $this->date_validation = ''; + $this->ref_supplier = ''; + $this->user_approve_id = ''; + $this->user_approve_id2 = ''; + $this->date_approve = ''; + $this->date_approve2 = ''; + + // Create clone + $result=$this->create($user); + if ($result < 0) $error++; + + if (! $error) + { + // Hook of thirdparty module + if (is_object($hookmanager)) + { + $parameters=array('objFrom'=>$objFrom); + $action=''; + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) $error++; + } // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_CLONE',$user); if ($result < 0) $error++; // End call triggers - } + } unset($this->context['createfromclone']); // End - if (! $error) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->db->rollback(); - return -1; - } - } - - /** - * Add order line - * - * @param string $desc Description - * @param float $pu_ht Unit price - * @param float $qty Quantity - * @param float $txtva Taux tva - * @param float $txlocaltax1 Localtax1 tax - * @param float $txlocaltax2 Localtax2 tax - * @param int $fk_product Id product - * @param int $fk_prod_fourn_price Id supplier price - * @param string $fourn_ref Supplier reference price - * @param float $remise_percent Remise - * @param string $price_base_type HT or TTC - * @param float $pu_ttc Unit price TTC - * @param int $type Type of line (0=product, 1=service) - * @param int $info_bits More information - * @param bool $notrigger Disable triggers - * @param int $date_start Date start of service - * @param int $date_end Date end of service + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Add order line + * + * @param string $desc Description + * @param float $pu_ht Unit price + * @param float $qty Quantity + * @param float $txtva Taux tva + * @param float $txlocaltax1 Localtax1 tax + * @param float $txlocaltax2 Localtax2 tax + * @param int $fk_product Id product + * @param int $fk_prod_fourn_price Id supplier price + * @param string $fourn_ref Supplier reference price + * @param float $remise_percent Remise + * @param string $price_base_type HT or TTC + * @param float $pu_ttc Unit price TTC + * @param int $type Type of line (0=product, 1=service) + * @param int $info_bits More information + * @param bool $notrigger Disable triggers + * @param int $date_start Date start of service + * @param int $date_end Date end of service * @param array $array_options extrafields array - * @param string $fk_unit Code of the unit to use. Null to use the default one + * @param string $fk_unit Code of the unit to use. Null to use the default one * @param string $pu_ht_devise Amount in currency * @param string $origin 'order', ... * @param int $origin_id Id of origin object - * @return int <=0 if KO, >0 if OK - */ + * @return int <=0 if KO, >0 if OK + */ public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $fk_prod_fourn_price=0, $fourn_ref='', $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $type=0, $info_bits=0, $notrigger=false, $date_start=null, $date_end=null, $array_options=0, $fk_unit=null, $pu_ht_devise=0, $origin='', $origin_id=0) - { - global $langs,$mysoc,$conf; + { + global $langs,$mysoc,$conf; - $error = 0; + $error = 0; - dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $fk_prod_fourn_price, $fourn_ref, $remise_percent, $price_base_type, $pu_ttc, $type, $fk_unit"); - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $fk_prod_fourn_price, $fourn_ref, $remise_percent, $price_base_type, $pu_ttc, $type, $fk_unit"); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - // Clean parameters - if (! $qty) $qty=1; - if (! $info_bits) $info_bits=0; - if (empty($txtva)) $txtva=0; - if (empty($txlocaltax1)) $txlocaltax1=0; - if (empty($txlocaltax2)) $txlocaltax2=0; + // Clean parameters + if (! $qty) $qty=1; + if (! $info_bits) $info_bits=0; + if (empty($txtva)) $txtva=0; + if (empty($txlocaltax1)) $txlocaltax1=0; + if (empty($txlocaltax2)) $txlocaltax2=0; if (empty($remise_percent)) $remise_percent=0; - $remise_percent=price2num($remise_percent); - $qty=price2num($qty); - $pu_ht=price2num($pu_ht); - $pu_ttc=price2num($pu_ttc); - $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); - if ($price_base_type=='HT') - { - $pu=$pu_ht; - } - else - { - $pu=$pu_ttc; - } - $desc=trim($desc); - $ref_supplier=''; // Ref of supplier price when we add line - - // Check parameters - if ($qty < 1 && ! $fk_product) - { - $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("Product")); - return -1; - } - if ($type < 0) return -1; - - if ($this->statut == 0) - { - $this->db->begin(); - - if ($fk_product > 0) - { - if (empty($conf->global->SUPPLIER_ORDER_WITH_NOPRICEDEFINED)) - { - // Check quantity is enough - dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." fk_prod_fourn_price=".$fk_prod_fourn_price." qty=".$qty." fourn_ref=".$fourn_ref); - $prod = new Product($this->db, $fk_product); - if ($prod->fetch($fk_product) > 0) - { - $product_type = $prod->type; - $label = $prod->label; - - // We use 'none' instead of $fourn_ref, because fourn_ref may not exists anymore. So we will take the first supplier price ok. - // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. - $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', $this->fk_soc); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$fourn_ref/$this->fk_soc - if ($result > 0) - { - $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice - $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice - // is remise percent not keyed but present for the product we add it - if ($remise_percent == 0 && $prod->remise_percent !=0) - $remise_percent =$prod->remise_percent; - - - } - if ($result == 0) // If result == 0, we failed to found the supplier reference price - { - $langs->load("errors"); - $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); - $this->db->rollback(); - dol_syslog(get_class($this)."::addline we did not found supplier price, so we can't guess unit price"); - //$pu = $prod->fourn_pu; // We do not overwrite unit price - //$ref = $prod->ref_fourn; // We do not overwrite ref supplier price - return -1; - } - if ($result == -1) - { - $langs->load("errors"); - $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); - $this->db->rollback(); - dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_DEBUG); - return -1; - } - if ($result < -1) - { - $this->error=$prod->error; - $this->db->rollback(); - dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_ERR); - return -1; - } - } - else - { - $this->error=$prod->error; - return -1; - } - } - } - else - { - $product_type = $type; - } - - // Calcul du total TTC et de la TVA pour la ligne a partir de - // qty, pu, remise_percent et txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - - $localtaxes_type=getLocalTaxesFromRate($txtva,0,$mysoc,$this->thirdparty); - - // Clean vat code - $vat_src_code=''; - if (preg_match('/\((.*)\)/', $txtva, $reg)) - { - $vat_src_code = $reg[1]; - $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. - } - - $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx,$pu_ht_devise); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + $pu_ht=price2num($pu_ht); + $pu_ttc=price2num($pu_ttc); + $txtva = price2num($txtva); + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); + if ($price_base_type=='HT') + { + $pu=$pu_ht; + } + else + { + $pu=$pu_ttc; + } + $desc=trim($desc); + $ref_supplier=''; // Ref of supplier price when we add line + + // Check parameters + if ($qty < 1 && ! $fk_product) + { + $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("Product")); + return -1; + } + if ($type < 0) return -1; + + if ($this->statut == 0) + { + $this->db->begin(); + + if ($fk_product > 0) + { + if (empty($conf->global->SUPPLIER_ORDER_WITH_NOPRICEDEFINED)) + { + // Check quantity is enough + dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." fk_prod_fourn_price=".$fk_prod_fourn_price." qty=".$qty." fourn_ref=".$fourn_ref); + $prod = new Product($this->db, $fk_product); + if ($prod->fetch($fk_product) > 0) + { + $product_type = $prod->type; + $label = $prod->label; + + // We use 'none' instead of $fourn_ref, because fourn_ref may not exists anymore. So we will take the first supplier price ok. + // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. + $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', $this->fk_soc); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$fourn_ref/$this->fk_soc + if ($result > 0) + { + $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice + $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice + // is remise percent not keyed but present for the product we add it + if ($remise_percent == 0 && $prod->remise_percent !=0) + $remise_percent =$prod->remise_percent; + + + } + if ($result == 0) // If result == 0, we failed to found the supplier reference price + { + $langs->load("errors"); + $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); + $this->db->rollback(); + dol_syslog(get_class($this)."::addline we did not found supplier price, so we can't guess unit price"); + //$pu = $prod->fourn_pu; // We do not overwrite unit price + //$ref = $prod->ref_fourn; // We do not overwrite ref supplier price + return -1; + } + if ($result == -1) + { + $langs->load("errors"); + $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); + $this->db->rollback(); + dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_DEBUG); + return -1; + } + if ($result < -1) + { + $this->error=$prod->error; + $this->db->rollback(); + dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_ERR); + return -1; + } + } + else + { + $this->error=$prod->error; + return -1; + } + } + } + else + { + $product_type = $type; + } + + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $localtaxes_type=getLocalTaxesFromRate($txtva,0,$mysoc,$this->thirdparty); + + // Clean vat code + $vat_src_code=''; + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { + $vat_src_code = $reg[1]; + $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. + } + + $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx,$pu_ht_devise); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; $pu_ht = $tabprice[3]; // MultiCurrency $multicurrency_total_ht = $tabprice[16]; - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; $pu_ht_devise = $tabprice[19]; - $localtax1_type=$localtaxes_type[0]; + $localtax1_type=$localtaxes_type[0]; $localtax2_type=$localtaxes_type[2]; - $subprice = price2num($pu,'MU'); - - $rangmax = $this->line_max(); - $rang = $rangmax + 1; - - // Insert line - $this->line=new CommandeFournisseurLigne($this->db); - - $this->line->context = $this->context; - - $this->line->fk_commande=$this->id; - $this->line->label=$label; - $this->line->ref_fourn = $ref_supplier; - $this->line->ref_supplier = $ref_supplier; - $this->line->desc=$desc; - $this->line->qty=$qty; - $this->line->tva_tx=$txtva; - $this->line->localtax1_tx=$txlocaltax1; - $this->line->localtax2_tx=$txlocaltax2; - $this->line->localtax1_type = $localtaxes_type[0]; - $this->line->localtax2_type = $localtaxes_type[2]; - $this->line->fk_product=$fk_product; - $this->line->product_type=$product_type; - $this->line->remise_percent=$remise_percent; - $this->line->subprice=$pu_ht; - $this->line->rang=$this->rang; - $this->line->info_bits=$info_bits; - - $this->line->vat_src_code=$vat_src_code; - $this->line->total_ht=$total_ht; - $this->line->total_tva=$total_tva; - $this->line->total_localtax1=$total_localtax1; - $this->line->total_localtax2=$total_localtax2; - $this->line->total_ttc=$total_ttc; - $this->line->product_type=$type; - $this->line->special_code=$this->special_code; - $this->line->origin=$origin; - $this->line->origin_id=$origin_id; - $this->line->fk_unit=$fk_unit; - - $this->line->date_start=$date_start; - $this->line->date_end=$date_end; - - // Multicurrency - $this->line->fk_multicurrency = $this->fk_multicurrency; - $this->line->multicurrency_code = $this->multicurrency_code; - $this->line->multicurrency_subprice = $pu_ht_devise; - $this->line->multicurrency_total_ht = $multicurrency_total_ht; - $this->line->multicurrency_total_tva = $multicurrency_total_tva; - $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; - - $this->line->subprice=$pu_ht; - $this->line->price=$this->line->subprice; - - $this->line->remise_percent=$remise_percent; - - if (is_array($array_options) && count($array_options)>0) { - $this->line->array_options=$array_options; - } - - $result=$this->line->insert($notrigger); - if ($result > 0) - { - // Reorder if child line - if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); - - // Mise a jour informations denormalisees au niveau de la commande meme - $result=$this->update_price(1,'auto',0,$this->thirdparty); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. - if ($result > 0) - { - $this->db->commit(); - return $this->line->id; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->line->error; - $this->errors=$this->line->errors; - dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR); - $this->db->rollback(); - return -1; - } - } - } - - - /** - * Save a receiving into the tracking table of receiving (commande_fournisseur_dispatch) and add product into stock warehouse. - * - * @param User $user User object making change - * @param int $product Id of product to dispatch - * @param double $qty Qty to dispatch - * @param int $entrepot Id of warehouse to add product - * @param double $price Unit Price for PMP value calculation (Unit price without Tax and taking into account discount) - * @param string $comment Comment for stock movement + $subprice = price2num($pu,'MU'); + + $rangmax = $this->line_max(); + $rang = $rangmax + 1; + + // Insert line + $this->line=new CommandeFournisseurLigne($this->db); + + $this->line->context = $this->context; + + $this->line->fk_commande=$this->id; + $this->line->label=$label; + $this->line->ref_fourn = $ref_supplier; + $this->line->ref_supplier = $ref_supplier; + $this->line->desc=$desc; + $this->line->qty=$qty; + $this->line->tva_tx=$txtva; + $this->line->localtax1_tx=$txlocaltax1; + $this->line->localtax2_tx=$txlocaltax2; + $this->line->localtax1_type = $localtaxes_type[0]; + $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->fk_product=$fk_product; + $this->line->product_type=$product_type; + $this->line->remise_percent=$remise_percent; + $this->line->subprice=$pu_ht; + $this->line->rang=$this->rang; + $this->line->info_bits=$info_bits; + + $this->line->vat_src_code=$vat_src_code; + $this->line->total_ht=$total_ht; + $this->line->total_tva=$total_tva; + $this->line->total_localtax1=$total_localtax1; + $this->line->total_localtax2=$total_localtax2; + $this->line->total_ttc=$total_ttc; + $this->line->product_type=$type; + $this->line->special_code=$this->special_code; + $this->line->origin=$origin; + $this->line->origin_id=$origin_id; + $this->line->fk_unit=$fk_unit; + + $this->line->date_start=$date_start; + $this->line->date_end=$date_end; + + // Multicurrency + $this->line->fk_multicurrency = $this->fk_multicurrency; + $this->line->multicurrency_code = $this->multicurrency_code; + $this->line->multicurrency_subprice = $pu_ht_devise; + $this->line->multicurrency_total_ht = $multicurrency_total_ht; + $this->line->multicurrency_total_tva = $multicurrency_total_tva; + $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; + + $this->line->subprice=$pu_ht; + $this->line->price=$this->line->subprice; + + $this->line->remise_percent=$remise_percent; + + if (is_array($array_options) && count($array_options)>0) { + $this->line->array_options=$array_options; + } + + $result=$this->line->insert($notrigger); + if ($result > 0) + { + // Reorder if child line + if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); + + // Mise a jour informations denormalisees au niveau de la commande meme + $result=$this->update_price(1,'auto',0,$this->thirdparty); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if ($result > 0) + { + $this->db->commit(); + return $this->line->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->line->error; + $this->errors=$this->line->errors; + dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR); + $this->db->rollback(); + return -1; + } + } + } + + + /** + * Save a receiving into the tracking table of receiving (commande_fournisseur_dispatch) and add product into stock warehouse. + * + * @param User $user User object making change + * @param int $product Id of product to dispatch + * @param double $qty Qty to dispatch + * @param int $entrepot Id of warehouse to add product + * @param double $price Unit Price for PMP value calculation (Unit price without Tax and taking into account discount) + * @param string $comment Comment for stock movement * @param date $eatby eat-by date * @param date $sellby sell-by date * @param string $batch Lot number * @param int $fk_commandefourndet Id of supplier order line - * @param int $notrigger 1 = notrigger - * @return int <0 if KO, >0 if OK - */ - public function dispatchProduct($user, $product, $qty, $entrepot, $price=0, $comment='', $eatby='', $sellby='', $batch='', $fk_commandefourndet=0, $notrigger=0) - { - global $conf, $langs; - - $error = 0; - require_once DOL_DOCUMENT_ROOT .'/product/stock/class/mouvementstock.class.php'; - - // Check parameters (if test are wrong here, there is bug into caller) - if ($entrepot <= 0) - { - $this->error='ErrorBadValueForParameterWarehouse'; - return -1; - } - if ($qty <= 0) - { - $this->error='ErrorBadValueForParameterQty'; - return -1; - } - - $dispatchstatus = 1; - if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) $dispatchstatus = 0; // Setting dispatch status (a validation step after receiving products) will be done manually to 1 or 2 if this option is on - - $now=dol_now(); - - if (($this->statut == 3 || $this->statut == 4 || $this->statut == 5)) - { - $this->db->begin(); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseur_dispatch"; - $sql.= " (fk_commande, fk_product, qty, fk_entrepot, fk_user, datec, fk_commandefourndet, status, comment, eatby, sellby, batch) VALUES"; - $sql.= " ('".$this->id."','".$product."','".$qty."',".($entrepot>0?"'".$entrepot."'":"null").",'".$user->id."','".$this->db->idate($now)."','".$fk_commandefourndet."', ".$dispatchstatus.", '".$this->db->escape($comment)."', "; - $sql.= ($eatby?"'".$this->db->idate($eatby)."'":"null").", ".($sellby?"'".$this->db->idate($sellby)."'":"null").", ".($batch?"'".$batch."'":"null"); - $sql.= ")"; - - dol_syslog(get_class($this)."::dispatchProduct", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - if (! $notrigger) - { - global $conf, $langs, $user; + * @param int $notrigger 1 = notrigger + * @return int <0 if KO, >0 if OK + */ + public function dispatchProduct($user, $product, $qty, $entrepot, $price=0, $comment='', $eatby='', $sellby='', $batch='', $fk_commandefourndet=0, $notrigger=0) + { + global $conf, $langs; + + $error = 0; + require_once DOL_DOCUMENT_ROOT .'/product/stock/class/mouvementstock.class.php'; + + // Check parameters (if test are wrong here, there is bug into caller) + if ($entrepot <= 0) + { + $this->error='ErrorBadValueForParameterWarehouse'; + return -1; + } + if ($qty <= 0) + { + $this->error='ErrorBadValueForParameterQty'; + return -1; + } + + $dispatchstatus = 1; + if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) $dispatchstatus = 0; // Setting dispatch status (a validation step after receiving products) will be done manually to 1 or 2 if this option is on + + $now=dol_now(); + + if (($this->statut == 3 || $this->statut == 4 || $this->statut == 5)) + { + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseur_dispatch"; + $sql.= " (fk_commande, fk_product, qty, fk_entrepot, fk_user, datec, fk_commandefourndet, status, comment, eatby, sellby, batch) VALUES"; + $sql.= " ('".$this->id."','".$product."','".$qty."',".($entrepot>0?"'".$entrepot."'":"null").",'".$user->id."','".$this->db->idate($now)."','".$fk_commandefourndet."', ".$dispatchstatus.", '".$this->db->escape($comment)."', "; + $sql.= ($eatby?"'".$this->db->idate($eatby)."'":"null").", ".($sellby?"'".$this->db->idate($sellby)."'":"null").", ".($batch?"'".$batch."'":"null"); + $sql.= ")"; + + dol_syslog(get_class($this)."::dispatchProduct", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + if (! $notrigger) + { + global $conf, $langs, $user; // Call trigger $result=$this->call_trigger('LINEORDER_SUPPLIER_DISPATCH',$user); if ($result < 0) - { - $error++; - return -1; - } + { + $error++; + return -1; + } // End call triggers - } - } - else - { - $this->error=$this->db->lasterror(); - $error++; - } - - // Si module stock gere et que incrementation faite depuis un dispatching en stock - if (! $error && $entrepot > 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) - { - - $mouv = new MouvementStock($this->db); - if ($product > 0) - { - // $price should take into account discount (except if option STOCK_EXCLUDE_DISCOUNT_FOR_PMP is on) - $mouv->origin = &$this; + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + + // Si module stock gere et que incrementation faite depuis un dispatching en stock + if (! $error && $entrepot > 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) + { + + $mouv = new MouvementStock($this->db); + if ($product > 0) + { + // $price should take into account discount (except if option STOCK_EXCLUDE_DISCOUNT_FOR_PMP is on) + $mouv->origin = &$this; $result=$mouv->reception($user, $product, $entrepot, $qty, $price, $comment, $eatby, $sellby, $batch); - if ($result < 0) - { - $this->error=$mouv->error; - $this->errors=$mouv->errors; - dol_syslog(get_class($this)."::dispatchProduct ".$this->error." ".join(',',$this->errors), LOG_ERR); - $error++; - } - } - } - - if ($error == 0) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error='BadStatusForObject'; - return -2; - } - } - - /** - * Delete line - * - * @param int $idline Id of line to delete - * @param int $notrigger 1=Disable call to triggers - * @return int <0 if KO, >0 if OK - */ - public function deleteline($idline, $notrigger=0) - { - if ($this->statut == 0) - { - $line = new CommandeFournisseurLigne($this->db); - - if ($line->fetch($idline) <= 0) - { - return 0; - } - - if ($line->delete($notrigger) > 0) - { - $this->update_price(); - return 1; - } - else - { - $this->error = $line->error; - $this->errors = $line->errors; - return -1; - } - } - else - { - return -2; - } - } - - /** - * Delete an order - * - * @param User $user Object user - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - public function delete(User $user, $notrigger=0) - { - global $langs,$conf; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $error = 0; - - $this->db->begin(); - - if (empty($notrigger)) - { - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user); - if ($result < 0) - { - $this->errors[]='ErrorWhenRunningTrigger'; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - return -1; - } - // End call triggers - } - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =". $this->id ; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - if (! $this->db->query($sql) ) - { - $this->error=$this->db->lasterror(); - $this->errors[]=$this->db->lasterror(); - $error++; - } - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseur WHERE rowid =".$this->id; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - if ($resql = $this->db->query($sql) ) - { - if ($this->db->affected_rows($resql) < 1) - { - $this->error=$this->db->lasterror(); - $this->errors[]=$this->db->lasterror(); - $error++; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->errors[]=$this->db->lasterror(); - $error++; - } - - // Remove extrafields - if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used - { - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $this->error='FailToDeleteExtraFields'; - $this->errors[]='FailToDeleteExtraFields'; - $error++; - dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); - } - } + if ($result < 0) + { + $this->error=$mouv->error; + $this->errors=$mouv->errors; + dol_syslog(get_class($this)."::dispatchProduct ".$this->error." ".join(',',$this->errors), LOG_ERR); + $error++; + } + } + } - // Delete linked object - $res = $this->deleteObjectLinked(); - if ($res < 0) { - $this->error='FailToDeleteObjectLinked'; - $this->errors[]='FailToDeleteObjectLinked'; - $error++; - } - - if (! $error) - { - // We remove directory - $ref = dol_sanitizeFileName($this->ref); - if ($conf->fournisseur->commande->dir_output) - { - $dir = $conf->fournisseur->commande->dir_output . "/" . $ref ; - $file = $dir . "/" . $ref . ".pdf"; - if (file_exists($file)) - { - if (! dol_delete_file($file,0,0,0,$this)) // For triggers - { - $this->error='ErrorFailToDeleteFile'; - $this->errors[]='ErrorFailToDeleteFile'; - $error++; - } - } - if (file_exists($dir)) - { - $res=@dol_delete_dir_recursive($dir); - if (! $res) - { - $this->error='ErrorFailToDeleteDir'; - $this->errors[]='ErrorFailToDeleteDir'; - $error++; - } - } - } - } + if ($error == 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error='BadStatusForObject'; + return -2; + } + } - if (! $error) + /** + * Delete line + * + * @param int $idline Id of line to delete + * @param int $notrigger 1=Disable call to triggers + * @return int <0 if KO, >0 if OK + */ + public function deleteline($idline, $notrigger=0) + { + if ($this->statut == 0) { - dol_syslog(get_class($this)."::delete $this->id by $user->id", LOG_DEBUG); - $this->db->commit(); - return 1; + $line = new CommandeFournisseurLigne($this->db); + + if ($line->fetch($idline) <= 0) + { + return 0; + } + + if ($line->delete($notrigger) > 0) + { + $this->update_price(); + return 1; + } + else + { + $this->error = $line->error; + $this->errors = $line->errors; + return -1; + } } else { - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -$error; + return -2; } - } - - /** - * Get list of order methods - * - * @return 0 if Ok, <0 if Ko - */ - function get_methodes_commande() - { - $sql = "SELECT rowid, libelle"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_input_method"; - $sql.= " WHERE active = 1"; - - $resql=$this->db->query($sql); - if ($resql) - { - $i = 0; - $num = $this->db->num_rows($resql); - $this->methodes_commande = array(); - while ($i < $num) - { - $row = $this->db->fetch_row($resql); - - $this->methodes_commande[$row[0]] = $row[1]; - - $i++; - } - return 0; - } - else - { - return -1; - } - } - - /** - * Return array of dispathed lines waiting to be approved for this order + } + + /** + * Delete an order * - * @param int $status Filter on stats (-1 = no filter, 0 = lines draft to be approved, 1 = approved lines) - * @return array Array of lines - */ - public function getDispachedLines($status=-1) - { - $ret = array(); + * @param User $user Object user + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger=0) + { + global $langs,$conf; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - // List of already dispatched lines - $sql = "SELECT p.ref, p.label,"; - $sql.= " e.rowid as warehouse_id, e.label as entrepot,"; - $sql.= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status"; - $sql.= " FROM ".MAIN_DB_PREFIX."product as p,"; - $sql.= " ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as cfd"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e ON cfd.fk_entrepot = e.rowid"; - $sql.= " WHERE cfd.fk_commande = ".$this->id; - $sql.= " AND cfd.fk_product = p.rowid"; - if ($status >= 0) $sql.=" AND cfd.status = ".$status; - $sql.= " ORDER BY cfd.rowid ASC"; + $error = 0; - $resql = $this->db->query($sql); - if ($resql) + $this->db->begin(); + + if (empty($notrigger)) + { + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user); + if ($result < 0) + { + $this->errors[]='ErrorWhenRunningTrigger'; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + return -1; + } + // End call triggers + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =". $this->id ; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if (! $this->db->query($sql) ) + { + $this->error=$this->db->lasterror(); + $this->errors[]=$this->db->lasterror(); + $error++; + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseur WHERE rowid =".$this->id; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if ($resql = $this->db->query($sql) ) + { + if ($this->db->affected_rows($resql) < 1) + { + $this->error=$this->db->lasterror(); + $this->errors[]=$this->db->lasterror(); + $error++; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->errors[]=$this->db->lasterror(); + $error++; + } + + // Remove extrafields + if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $this->error='FailToDeleteExtraFields'; + $this->errors[]='FailToDeleteExtraFields'; + $error++; + dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); + } + } + + // Delete linked object + $res = $this->deleteObjectLinked(); + if ($res < 0) { + $this->error='FailToDeleteObjectLinked'; + $this->errors[]='FailToDeleteObjectLinked'; + $error++; + } + + if (! $error) + { + // We remove directory + $ref = dol_sanitizeFileName($this->ref); + if ($conf->fournisseur->commande->dir_output) + { + $dir = $conf->fournisseur->commande->dir_output . "/" . $ref ; + $file = $dir . "/" . $ref . ".pdf"; + if (file_exists($file)) + { + if (! dol_delete_file($file,0,0,0,$this)) // For triggers + { + $this->error='ErrorFailToDeleteFile'; + $this->errors[]='ErrorFailToDeleteFile'; + $error++; + } + } + if (file_exists($dir)) + { + $res=@dol_delete_dir_recursive($dir); + if (! $res) + { + $this->error='ErrorFailToDeleteDir'; + $this->errors[]='ErrorFailToDeleteDir'; + $error++; + } + } + } + } + + if (! $error) + { + dol_syslog(get_class($this)."::delete $this->id by $user->id", LOG_DEBUG); + $this->db->commit(); + return 1; + } + else + { + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -$error; + } + } + + /** + * Get list of order methods + * + * @return 0 if Ok, <0 if Ko + */ + function get_methodes_commande() + { + $sql = "SELECT rowid, libelle"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_input_method"; + $sql.= " WHERE active = 1"; + + $resql=$this->db->query($sql); + if ($resql) + { + $i = 0; + $num = $this->db->num_rows($resql); + $this->methodes_commande = array(); + while ($i < $num) + { + $row = $this->db->fetch_row($resql); + + $this->methodes_commande[$row[0]] = $row[1]; + + $i++; + } + return 0; + } + else + { + return -1; + } + } + + /** + * Return array of dispathed lines waiting to be approved for this order + * + * @param int $status Filter on stats (-1 = no filter, 0 = lines draft to be approved, 1 = approved lines) + * @return array Array of lines + */ + public function getDispachedLines($status=-1) + { + $ret = array(); + + // List of already dispatched lines + $sql = "SELECT p.ref, p.label,"; + $sql.= " e.rowid as warehouse_id, e.label as entrepot,"; + $sql.= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as p,"; + $sql.= " ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as cfd"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e ON cfd.fk_entrepot = e.rowid"; + $sql.= " WHERE cfd.fk_commande = ".$this->id; + $sql.= " AND cfd.fk_product = p.rowid"; + if ($status >= 0) $sql.=" AND cfd.status = ".$status; + $sql.= " ORDER BY cfd.rowid ASC"; + + $resql = $this->db->query($sql); + if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < $num) - { - $objp = $this->db->fetch_object($resql); - if ($objp) $ret[]=array('id'=>$objp->dispatchedlineid, 'productid'=>$objp->fk_product, 'warehouseid'=>$objp->warehouse_id); + while ($i < $num) + { + $objp = $this->db->fetch_object($resql); + if ($objp) $ret[]=array('id'=>$objp->dispatchedlineid, 'productid'=>$objp->fk_product, 'warehouseid'=>$objp->warehouse_id); + + $i++; + } + } + else dol_print_error($this->db, 'Failed to execute request to get dispatched lines'); + + return $ret; + } + + + /** + * Set a delivery in database for this supplier order + * + * @param User $user User that input data + * @param date $date Date of reception + * @param string $type Type of receipt ('tot' = total/done, 'par' = partial, 'nev' = never, 'can' = cancel) + * @param string $comment Comment + * @return int <0 if KO, >0 if OK + */ + function Livraison($user, $date, $type, $comment) + { + global $conf, $langs; + + $result = 0; + $error = 0; + + dol_syslog(get_class($this)."::Livraison"); + + if ($user->rights->fournisseur->commande->receptionner) + { + if ($type == 'par') $statut = 4; + if ($type == 'tot') $statut = 5; + if ($type == 'nev') $statut = 7; + if ($type == 'can') $statut = 7; + + // Some checks to accept the record + if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) + { + // If option SUPPLIER_ORDER_USE_DISPATCH_STATUS is on, we check all reception are approved to allow status "total/done" + if (! $error && ($type == 'tot')) + { + $dispatchedlinearray=$this->getDispachedLines(0); + if (count($dispatchedlinearray) > 0) + { + $result=-1; + $error++; + $this->errors[]='ErrorCantSetReceptionToTotalDoneWithReceptionToApprove'; + dol_syslog('ErrorCantSetReceptionToTotalDoneWithReceptionToApprove', LOG_DEBUG); + } + + } + if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot')) // Accept to move to reception done, only if status of all line are ok (refuse denied) + { + $dispatcheddenied=$this->getDispachedLines(2); + if (count($dispatchedlinearray) > 0) + { + $result=-1; + $error++; + $this->errors[]='ErrorCantSetReceptionToTotalDoneWithReceptionDenied'; + dol_syslog('ErrorCantSetReceptionToTotalDoneWithReceptionDenied', LOG_DEBUG); + } + } + } + + // TODO LDR01 Add a control test to accept only if ALL predefined products are received (same qty). + + + if (! $error && ! ($statut == 4 or $statut == 5 or $statut == 7)) + { + $error++; + dol_syslog(get_class($this)."::Livraison Error -2", LOG_ERR); + $result = -2; + } + + if (! $error) + { + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; + $sql.= " SET fk_statut = ".$statut; + $sql.= " WHERE rowid = ".$this->id; + $sql.= " AND fk_statut IN (3,4)"; // Process running or Partially received + + dol_syslog(get_class($this)."::Livraison", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $result = 0; + $old_statut = $this->statut; + $this->statut = $statut; + $this->actionmsg2 = $comment; + + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_RECEIVE',$user); + if ($result < 0) $error++; + // End call triggers + + if (! $error) + { + $this->db->commit(); + } + else + { + $this->statut = $old_statut; + $this->db->rollback(); + $this->error=$this->db->lasterror(); + $result = -1; + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + $result = -1; + } + } + } + else + { + $this->error = $langs->trans('NotAuthorized'); + $this->errors[] = $langs->trans('NotAuthorized'); + dol_syslog(get_class($this)."::Livraison Not Authorized"); + $result = -3; + } + return $result ; + } + + /** + * Set the planned delivery date + * + * @param User $user Objet user making change + * @param timestamp $date_livraison Planned delivery date + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if KO, >0 if OK + */ + function set_date_livraison($user, $date_livraison, $notrigger=0) + { + if ($user->rights->fournisseur->commande->creer) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; + $sql.= " SET date_livraison = ".($date_livraison ? "'".$this->db->idate($date_livraison)."'" : 'null'); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->date_livraison = $date_livraison; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + else + { + return -2; + } + } + + /** + * Set the id projet + * + * @param User $user Objet utilisateur qui modifie + * @param int $id_projet Date de livraison + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 si ko, >0 si ok + */ + function set_id_projet($user, $id_projet, $notrigger=0) + { + if ($user->rights->fournisseur->commande->creer) + { + $error=0; + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; + $sql.= " SET fk_projet = ".($id_projet > 0 ? (int) $id_projet : 'null'); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (!$resql) + { + $this->errors[]=$this->db->error(); + $error++; + } + + if (! $error) + { + $this->oldcopy= clone $this; + $this->fk_projet = $id_projet; + } + + if (! $notrigger && empty($error)) + { + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_MODIFY',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + else + { + return -2; + } + } + + /** + * Update a supplier order from a customer order + * + * @param User $user User that create + * @param int $idc Id of supplier order to update + * @param int $comclientid Id of customer order to use as template + * @return int <0 if KO, >0 if OK + */ + public function updateFromCommandeClient($user, $idc, $comclientid) + { + $comclient = new Commande($this->db); + $comclient->fetch($comclientid); + + $this->id = $idc; + + $this->lines = array(); + + $num=count($comclient->lines); + for ($i = 0; $i < $num; $i++) + { + $prod = new Product($this->db); + if ($prod->fetch($comclient->lines[$i]->fk_product) > 0) + { + $libelle = $prod->libelle; + $ref = $prod->ref; + } + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseurdet"; + $sql .= " (fk_commande,label,description,fk_product, price, qty, tva_tx, localtax1_tx, localtax2_tx, remise_percent, subprice, remise, ref)"; + $sql .= " VALUES (".$idc.", '" . $this->db->escape($libelle) . "','" . $this->db->escape($comclient->lines[$i]->desc) . "'"; + $sql .= ",".$comclient->lines[$i]->fk_product.",'".price2num($comclient->lines[$i]->price)."'"; + $sql .= ", '".$comclient->lines[$i]->qty."', ".$comclient->lines[$i]->tva_tx.", ".$comclient->lines[$i]->localtax1_tx.", ".$comclient->lines[$i]->localtax2_tx.", ".$comclient->lines[$i]->remise_percent; + $sql .= ", '".price2num($comclient->lines[$i]->subprice)."','0','".$ref."');"; + if ($this->db->query($sql)) + { + $this->update_price(); + } + } + + return 1; + } + + /** + * Tag order with a particular status + * + * @param User $user Object user that change status + * @param int $status New status + * @return int <0 if KO, >0 if OK + */ + public function setStatus($user,$status) + { + global $conf,$langs; + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur'; + $sql.= ' SET fk_statut='.$status; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::setStatus", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + // Trigger names for each status + $trigger_name[0] = 'DRAFT'; + $trigger_name[1] = 'VALIDATED'; + $trigger_name[2] = 'APPROVED'; + $trigger_name[3] = 'ONPROCESS'; + $trigger_name[4] = 'RECEIVED_PARTIALLY'; + $trigger_name[5] = 'RECEIVED_ALL'; + $trigger_name[6] = 'CANCELED'; + $trigger_name[7] = 'CANCELED'; + $trigger_name[8] = 'BILLED'; + $trigger_name[9] = 'REFUSED'; + + // Call trigger + $result=$this->call_trigger("ORDER_SUPPLIER_STATUS_".$trigger_name[$status],$user); + if ($result < 0) { $error++; } + // End call triggers + } + else + { + $error++; + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::setStatus ".$this->error); + } + + if (! $error) + { + $this->statut = $status; + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Update line + * + * @param int $rowid Id de la ligne de facture + * @param string $desc Description de la ligne + * @param double $pu Prix unitaire + * @param double $qty Quantity + * @param double $remise_percent Pourcentage de remise de la ligne + * @param double $txtva Taux TVA + * @param double $txlocaltax1 Localtax1 tax + * @param double $txlocaltax2 Localtax2 tax + * @param double $price_base_type Type of price base + * @param int $info_bits Miscellaneous informations + * @param int $type Type of line (0=product, 1=service) + * @param int $notrigger Disable triggers + * @param timestamp $date_start Date start of service + * @param timestamp $date_end Date end of service + * @param array $array_options Extrafields array + * @param string $fk_unit Code of the unit to use. Null to use the default one + * @param double $pu_ht_devise Unit price in currency + * @return int < 0 if error, > 0 if ok + */ + public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $notrigger=false, $date_start='', $date_end='', $array_options=0, $fk_unit=null, $pu_ht_devise = 0) + { + global $mysoc, $conf; + dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $txtva, $price_base_type, $info_bits, $type, $fk_unit"); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + $error = 0; + + if ($this->brouillon) + { + $this->db->begin(); + + // Clean parameters + if (empty($qty)) $qty=0; + if (empty($info_bits)) $info_bits=0; + if (empty($txtva)) $txtva=0; + if (empty($txlocaltax1)) $txlocaltax1=0; + if (empty($txlocaltax2)) $txlocaltax2=0; + if (empty($remise)) $remise=0; + if (empty($remise_percent)) $remise_percent=0; + + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + if (! $qty) $qty=1; + $pu = price2num($pu); + $txtva=price2num($txtva); + $txlocaltax1=price2num($txlocaltax1); + $txlocaltax2=price2num($txlocaltax2); + + // Check parameters + if ($type < 0) return -1; + + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $localtaxes_type=getLocalTaxesFromRate($txtva,0,$mysoc, $this->thirdparty); + + // Clean vat code + $vat_src_code=''; + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { + $vat_src_code = $reg[1]; + $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. + } + + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; + $pu_ht = $tabprice[3]; + $pu_tva = $tabprice[4]; + $pu_ttc = $tabprice[5]; + + // MultiCurrency + $multicurrency_total_ht = $tabprice[16]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; + $pu_ht_devise = $tabprice[19]; + + $localtax1_type=$localtaxes_type[0]; + $localtax2_type=$localtaxes_type[2]; + + $subprice = price2num($pu_ht,'MU'); + + //Fetch current line from the database and then clone the object and set it in $oldline property + $this->line=new CommandeFournisseurLigne($this->db); + $this->line->fetch($rowid); + $oldline = clone $this->line; + $this->line->oldline = $oldline; + + $this->line->context = $this->context; + + $this->line->fk_commande=$this->id; + //$this->line->label=$label; + $this->line->desc=$desc; + $this->line->qty=$qty; + + $this->line->vat_src_code = $vat_src_code; + $this->line->tva_tx = $txtva; + $this->line->localtax1_tx = $txlocaltax1; + $this->line->localtax2_tx = $txlocaltax2; + $this->line->localtax1_type = $localtaxes_type[0]; + $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->remise_percent = $remise_percent; + $this->line->subprice = $pu_ht; + $this->line->rang = $this->rang; + $this->line->info_bits = $info_bits; + $this->line->total_ht = $total_ht; + $this->line->total_tva = $total_tva; + $this->line->total_localtax1= $total_localtax1; + $this->line->total_localtax2= $total_localtax2; + $this->line->total_ttc = $total_ttc; + $this->line->product_type = $type; + $this->line->special_code = $this->special_code; + $this->line->origin = $this->origin; + $this->line->fk_unit = $fk_unit; + + $this->line->date_start = $date_start; + $this->line->date_end = $date_end; + + // Multicurrency + $this->line->fk_multicurrency = $this->fk_multicurrency; + $this->line->multicurrency_code = $this->multicurrency_code; + $this->line->multicurrency_subprice = $pu_ht_devise; + $this->line->multicurrency_total_ht = $multicurrency_total_ht; + $this->line->multicurrency_total_tva = $multicurrency_total_tva; + $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; + + $this->line->subprice=$pu_ht; + $this->line->price=$this->line->subprice; + + $this->line->remise_percent=$remise_percent; + + if (is_array($array_options) && count($array_options)>0) { + $this->line->array_options=$array_options; + } + + $result=$this->line->update($notrigger); + + + // Mise a jour info denormalisees au niveau facture + if ($result >= 0) + { + $this->update_price('','auto'); + $this->db->commit(); + return $result; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + else + { + $this->error="Order status makes operation forbidden"; + dol_syslog(get_class($this)."::updateline ".$this->error, LOG_ERR); + return -2; + } + } + + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + public function initAsSpecimen() + { + global $user,$langs,$conf; + + dol_syslog(get_class($this)."::initAsSpecimen"); + + $now=dol_now(); + + // Find first product + $prodid=0; + $product=new ProductFournisseur($this->db); + $sql = "SELECT rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE entity IN (".getEntity('product').")"; + $sql.=$this->db->order("rowid","ASC"); + $sql.=$this->db->plimit(1); + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $prodid = $obj->rowid; + } + + // Initialise parametres + $this->id=0; + $this->ref = 'SPECIMEN'; + $this->specimen=1; + $this->socid = 1; + $this->date = $now; + $this->date_commande = $now; + $this->date_lim_reglement=$this->date+3600*24*30; + $this->cond_reglement_code = 'RECEP'; + $this->mode_reglement_code = 'CHQ'; + $this->note_public='This is a comment (public)'; + $this->note_private='This is a comment (private)'; + $this->statut=0; + + // Lines + $nbp = 5; + $xnbp = 0; + while ($xnbp < $nbp) + { + $line=new CommandeFournisseurLigne($this->db); + $line->desc=$langs->trans("Description")." ".$xnbp; + $line->qty=1; + $line->subprice=100; + $line->price=100; + $line->tva_tx=19.6; + $line->localtax1_tx=0; + $line->localtax2_tx=0; + if ($xnbp == 2) + { + $line->total_ht=50; + $line->total_ttc=59.8; + $line->total_tva=9.8; + $line->remise_percent=50; + } + else + { + $line->total_ht=100; + $line->total_ttc=119.6; + $line->total_tva=19.6; + $line->remise_percent=00; + } + $line->fk_product=$prodid; + + $this->lines[$xnbp]=$line; + + $this->total_ht += $line->total_ht; + $this->total_tva += $line->total_tva; + $this->total_ttc += $line->total_ttc; + + $xnbp++; + } + } + + /** + * Charge les informations d'ordre info dans l'objet facture + * + * @param int $id Id de la facture a charger + * @return void + */ + public function info($id) + { + $sql = 'SELECT c.rowid, date_creation as datec, tms as datem, date_valid as date_validation, date_approve as datea, date_approve2 as datea2,'; + $sql.= ' fk_user_author, fk_user_modif, fk_user_valid, fk_user_approve, fk_user_approve2'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseur as c'; + $sql.= ' WHERE c.rowid = '.$id; + + $result=$this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) $this->user_creation_id = $obj->fk_user_author; + if ($obj->fk_user_valid) $this->user_validation_id = $obj->fk_user_valid; + if ($obj->fk_user_modif) $this->user_modification_id =$obj->fk_user_modif; + if ($obj->fk_user_approve) $this->user_approve_id = $obj->fk_user_approve; + if ($obj->fk_user_approve2) $this->user_approve_id2 = $obj->fk_user_approve2; + + $this->date_creation = $this->db->idate($obj->datec); + $this->date_modification = $this->db->idate($obj->datem); + $this->date_approve = $this->db->idate($obj->datea); + $this->date_approve2 = $this->db->idate($obj->datea2); + $this->date_validation = $this->db->idate($obj->date_validation); + } + $this->db->free($result); + } + else + { + dol_print_error($this->db); + } + } + + /** + * Charge indicateurs this->nb de tableau de bord + * + * @return int <0 si ko, >0 si ok + */ + function load_state_board() + { + global $conf, $user; + + $this->nb=array(); + $clause = "WHERE"; + + $sql = "SELECT count(co.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as co"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON co.fk_soc = s.rowid"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = "AND"; + } + $sql.= " ".$clause." co.entity = ".$conf->entity; + + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["supplier_orders"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } + + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Objet user + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK + */ + function load_board($user) + { + global $conf, $langs; + + $clause = " WHERE"; - $i++; - } + $sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.fk_statut, c.date_livraison as delivery_date"; + $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = " AND"; } - else dol_print_error($this->db, 'Failed to execute request to get dispatched lines'); + $sql.= $clause." c.entity = ".$conf->entity; + $sql.= " AND (c.fk_statut BETWEEN 1 AND 2)"; + if ($user->societe_id) $sql.=" AND c.fk_soc = ".$user->societe_id; - return $ret; - } - - - /** - * Set a delivery in database for this supplier order - * - * @param User $user User that input data - * @param date $date Date of reception - * @param string $type Type of receipt ('tot' = total/done, 'par' = partial, 'nev' = never, 'can' = cancel) - * @param string $comment Comment - * @return int <0 if KO, >0 if OK - */ - function Livraison($user, $date, $type, $comment) - { - global $conf, $langs; - - $result = 0; - $error = 0; + $resql=$this->db->query($sql); + if ($resql) + { + $commandestatic = new CommandeFournisseur($this->db); - dol_syslog(get_class($this)."::Livraison"); + $response = new WorkboardResponse(); + $response->warning_delay=$conf->commande->fournisseur->warning_delay/60/60/24; + $response->label=$langs->trans("SuppliersOrdersToProcess"); + $response->url=DOL_URL_ROOT.'/fourn/commande/list.php?statut=1,2,3&mainmenu=commercial&leftmenu=orders_suppliers'; + $response->img=img_object('',"order"); - if ($user->rights->fournisseur->commande->receptionner) - { - if ($type == 'par') $statut = 4; - if ($type == 'tot') $statut = 5; - if ($type == 'nev') $statut = 7; - if ($type == 'can') $statut = 7; + while ($obj=$this->db->fetch_object($resql)) + { + $response->nbtodo++; - // Some checks to accept the record - if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) - { - // If option SUPPLIER_ORDER_USE_DISPATCH_STATUS is on, we check all reception are approved to allow status "total/done" - if (! $error && ($type == 'tot')) - { - $dispatchedlinearray=$this->getDispachedLines(0); - if (count($dispatchedlinearray) > 0) - { - $result=-1; - $error++; - $this->errors[]='ErrorCantSetReceptionToTotalDoneWithReceptionToApprove'; - dol_syslog('ErrorCantSetReceptionToTotalDoneWithReceptionToApprove', LOG_DEBUG); - } - - } - if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot')) // Accept to move to reception done, only if status of all line are ok (refuse denied) - { - $dispatcheddenied=$this->getDispachedLines(2); - if (count($dispatchedlinearray) > 0) - { - $result=-1; - $error++; - $this->errors[]='ErrorCantSetReceptionToTotalDoneWithReceptionDenied'; - dol_syslog('ErrorCantSetReceptionToTotalDoneWithReceptionDenied', LOG_DEBUG); - } - } - } - - // TODO LDR01 Add a control test to accept only if ALL predefined products are received (same qty). - - - if (! $error && ! ($statut == 4 or $statut == 5 or $statut == 7)) - { - $error++; - dol_syslog(get_class($this)."::Livraison Error -2", LOG_ERR); - $result = -2; - } - - if (! $error) - { - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; - $sql.= " SET fk_statut = ".$statut; - $sql.= " WHERE rowid = ".$this->id; - $sql.= " AND fk_statut IN (3,4)"; // Process running or Partially received - - dol_syslog(get_class($this)."::Livraison", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $result = 0; - $old_statut = $this->statut; - $this->statut = $statut; - $this->actionmsg2 = $comment; + $commandestatic->date_livraison = $this->db->jdate($obj->delivery_date); + $commandestatic->date_commande = $this->db->jdate($obj->date_commande); + $commandestatic->statut = $obj->fk_statut; - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_RECEIVE',$user); - if ($result < 0) $error++; - // End call triggers - - if (! $error) - { - $this->db->commit(); - } - else - { - $this->statut = $old_statut; - $this->db->rollback(); - $this->error=$this->db->lasterror(); - $result = -1; - } - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - $result = -1; - } - } - } - else - { - $this->error = $langs->trans('NotAuthorized'); - $this->errors[] = $langs->trans('NotAuthorized'); - dol_syslog(get_class($this)."::Livraison Not Authorized"); - $result = -3; - } - return $result ; - } + if ($commandestatic->hasDelay()) { + $response->nbtodolate++; + } + } - /** - * Set the planned delivery date - * - * @param User $user Objet user making change - * @param timestamp $date_livraison Planned delivery date - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function set_date_livraison($user, $date_livraison, $notrigger=0) - { - if ($user->rights->fournisseur->commande->creer) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; - $sql.= " SET date_livraison = ".($date_livraison ? "'".$this->db->idate($date_livraison)."'" : 'null'); - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->date_livraison = $date_livraison; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - else - { - return -2; - } - } + return $response; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } /** - * Set the id projet - * - * @param User $user Objet utilisateur qui modifie - * @param int $id_projet Date de livraison - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 si ko, >0 si ok - */ - function set_id_projet($user, $id_projet, $notrigger=0) - { - if ($user->rights->fournisseur->commande->creer) - { - $error=0; - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur"; - $sql.= " SET fk_projet = ".($id_projet > 0 ? (int) $id_projet : 'null'); - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if (!$resql) - { - $this->errors[]=$this->db->error(); - $error++; - } - - if (! $error) - { - $this->oldcopy= clone $this; - $this->fk_projet = $id_projet; - } - - if (! $notrigger && empty($error)) - { - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_MODIFY',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - foreach($this->errors as $errmsg) - { - dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - } - else - { - return -2; - } - } - - /** - * Update a supplier order from a customer order - * - * @param User $user User that create - * @param int $idc Id of supplier order to update - * @param int $comclientid Id of customer order to use as template - * @return int <0 if KO, >0 if OK - */ - public function updateFromCommandeClient($user, $idc, $comclientid) - { - $comclient = new Commande($this->db); - $comclient->fetch($comclientid); - - $this->id = $idc; - - $this->lines = array(); - - $num=count($comclient->lines); - for ($i = 0; $i < $num; $i++) - { - $prod = new Product($this->db); - if ($prod->fetch($comclient->lines[$i]->fk_product) > 0) - { - $libelle = $prod->libelle; - $ref = $prod->ref; - } - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseurdet"; - $sql .= " (fk_commande,label,description,fk_product, price, qty, tva_tx, localtax1_tx, localtax2_tx, remise_percent, subprice, remise, ref)"; - $sql .= " VALUES (".$idc.", '" . $this->db->escape($libelle) . "','" . $this->db->escape($comclient->lines[$i]->desc) . "'"; - $sql .= ",".$comclient->lines[$i]->fk_product.",'".price2num($comclient->lines[$i]->price)."'"; - $sql .= ", '".$comclient->lines[$i]->qty."', ".$comclient->lines[$i]->tva_tx.", ".$comclient->lines[$i]->localtax1_tx.", ".$comclient->lines[$i]->localtax2_tx.", ".$comclient->lines[$i]->remise_percent; - $sql .= ", '".price2num($comclient->lines[$i]->subprice)."','0','".$ref."');"; - if ($this->db->query($sql)) - { - $this->update_price(); - } - } - - return 1; - } - - /** - * Tag order with a particular status - * - * @param User $user Object user that change status - * @param int $status New status - * @return int <0 if KO, >0 if OK - */ - public function setStatus($user,$status) - { - global $conf,$langs; - $error=0; - - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur'; - $sql.= ' SET fk_statut='.$status; - $sql.= ' WHERE rowid = '.$this->id; - - dol_syslog(get_class($this)."::setStatus", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - // Trigger names for each status - $trigger_name[0] = 'DRAFT'; - $trigger_name[1] = 'VALIDATED'; - $trigger_name[2] = 'APPROVED'; - $trigger_name[3] = 'ONPROCESS'; - $trigger_name[4] = 'RECEIVED_PARTIALLY'; - $trigger_name[5] = 'RECEIVED_ALL'; - $trigger_name[6] = 'CANCELED'; - $trigger_name[7] = 'CANCELED'; - $trigger_name[8] = 'BILLED'; - $trigger_name[9] = 'REFUSED'; - - // Call trigger - $result=$this->call_trigger("ORDER_SUPPLIER_STATUS_".$trigger_name[$status],$user); - if ($result < 0) { $error++; } - // End call triggers - } - else - { - $error++; - $this->error=$this->db->lasterror(); - dol_syslog(get_class($this)."::setStatus ".$this->error); - } - - if (! $error) - { - $this->statut = $status; - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - - /** - * Update line - * - * @param int $rowid Id de la ligne de facture - * @param string $desc Description de la ligne - * @param double $pu Prix unitaire - * @param double $qty Quantity - * @param double $remise_percent Pourcentage de remise de la ligne - * @param double $txtva Taux TVA - * @param double $txlocaltax1 Localtax1 tax - * @param double $txlocaltax2 Localtax2 tax - * @param double $price_base_type Type of price base - * @param int $info_bits Miscellaneous informations - * @param int $type Type of line (0=product, 1=service) - * @param int $notrigger Disable triggers - * @param timestamp $date_start Date start of service - * @param timestamp $date_end Date end of service - * @param array $array_options Extrafields array - * @param string $fk_unit Code of the unit to use. Null to use the default one - * @param double $pu_ht_devise Unit price in currency - * @return int < 0 if error, > 0 if ok - */ - public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $notrigger=false, $date_start='', $date_end='', $array_options=0, $fk_unit=null, $pu_ht_devise = 0) - { - global $mysoc, $conf; - dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $txtva, $price_base_type, $info_bits, $type, $fk_unit"); - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - - $error = 0; - - if ($this->brouillon) - { - $this->db->begin(); - - // Clean parameters - if (empty($qty)) $qty=0; - if (empty($info_bits)) $info_bits=0; - if (empty($txtva)) $txtva=0; - if (empty($txlocaltax1)) $txlocaltax1=0; - if (empty($txlocaltax2)) $txlocaltax2=0; - if (empty($remise)) $remise=0; - if (empty($remise_percent)) $remise_percent=0; - - $remise_percent=price2num($remise_percent); - $qty=price2num($qty); - if (! $qty) $qty=1; - $pu = price2num($pu); - $txtva=price2num($txtva); - $txlocaltax1=price2num($txlocaltax1); - $txlocaltax2=price2num($txlocaltax2); - - // Check parameters - if ($type < 0) return -1; - - // Calcul du total TTC et de la TVA pour la ligne a partir de - // qty, pu, remise_percent et txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - - $localtaxes_type=getLocalTaxesFromRate($txtva,0,$mysoc, $this->thirdparty); - - // Clean vat code - $vat_src_code=''; - if (preg_match('/\((.*)\)/', $txtva, $reg)) - { - $vat_src_code = $reg[1]; - $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. - } - - $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; - $pu_ht = $tabprice[3]; - $pu_tva = $tabprice[4]; - $pu_ttc = $tabprice[5]; + * Returns the translated input method of object (defined if $this->methode_commande_id > 0). + * This function make a sql request to get translation. No cache yet, try to not use it inside a loop. + * + * @return string + */ + public function getInputMethod() + { + global $db, $langs; - // MultiCurrency - $multicurrency_total_ht = $tabprice[16]; - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; - $pu_ht_devise = $tabprice[19]; + if ($this->methode_commande_id > 0) + { + $sql = "SELECT rowid, code, libelle as label"; + $sql.= " FROM ".MAIN_DB_PREFIX.'c_input_method'; + $sql.= " WHERE active=1 AND rowid = ".$db->escape($this->methode_commande_id); - $localtax1_type=$localtaxes_type[0]; - $localtax2_type=$localtaxes_type[2]; + $resql = $db->query($sql); + if ($resql) + { + if ($db->num_rows($query)) + { + $obj = $db->fetch_object($query); - $subprice = price2num($pu_ht,'MU'); - - //Fetch current line from the database and then clone the object and set it in $oldline property - $this->line=new CommandeFournisseurLigne($this->db); - $this->line->fetch($rowid); - $oldline = clone $this->line; - $this->line->oldline = $oldline; - - $this->line->context = $this->context; - - $this->line->fk_commande=$this->id; - //$this->line->label=$label; - $this->line->desc=$desc; - $this->line->qty=$qty; - - $this->line->vat_src_code = $vat_src_code; - $this->line->tva_tx = $txtva; - $this->line->localtax1_tx = $txlocaltax1; - $this->line->localtax2_tx = $txlocaltax2; - $this->line->localtax1_type = $localtaxes_type[0]; - $this->line->localtax2_type = $localtaxes_type[2]; - $this->line->remise_percent = $remise_percent; - $this->line->subprice = $pu_ht; - $this->line->rang = $this->rang; - $this->line->info_bits = $info_bits; - $this->line->total_ht = $total_ht; - $this->line->total_tva = $total_tva; - $this->line->total_localtax1= $total_localtax1; - $this->line->total_localtax2= $total_localtax2; - $this->line->total_ttc = $total_ttc; - $this->line->product_type = $type; - $this->line->special_code = $this->special_code; - $this->line->origin = $this->origin; - $this->line->fk_unit = $fk_unit; - - $this->line->date_start = $date_start; - $this->line->date_end = $date_end; - - // Multicurrency - $this->line->fk_multicurrency = $this->fk_multicurrency; - $this->line->multicurrency_code = $this->multicurrency_code; - $this->line->multicurrency_subprice = $pu_ht_devise; - $this->line->multicurrency_total_ht = $multicurrency_total_ht; - $this->line->multicurrency_total_tva = $multicurrency_total_tva; - $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; - - $this->line->subprice=$pu_ht; - $this->line->price=$this->line->subprice; - - $this->line->remise_percent=$remise_percent; - - if (is_array($array_options) && count($array_options)>0) { - $this->line->array_options=$array_options; - } - - $result=$this->line->update($notrigger); - - - // Mise a jour info denormalisees au niveau facture - if ($result >= 0) - { - $this->update_price('','auto'); - $this->db->commit(); - return $result; - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - else - { - $this->error="Order status makes operation forbidden"; - dol_syslog(get_class($this)."::updateline ".$this->error, LOG_ERR); - return -2; - } - } - - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - public function initAsSpecimen() - { - global $user,$langs,$conf; - - dol_syslog(get_class($this)."::initAsSpecimen"); - - $now=dol_now(); - - // Find first product - $prodid=0; - $product=new ProductFournisseur($this->db); - $sql = "SELECT rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."product"; - $sql.= " WHERE entity IN (".getEntity('product').")"; - $sql.=$this->db->order("rowid","ASC"); - $sql.=$this->db->plimit(1); - $resql = $this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - $prodid = $obj->rowid; - } - - // Initialise parametres - $this->id=0; - $this->ref = 'SPECIMEN'; - $this->specimen=1; - $this->socid = 1; - $this->date = $now; - $this->date_commande = $now; - $this->date_lim_reglement=$this->date+3600*24*30; - $this->cond_reglement_code = 'RECEP'; - $this->mode_reglement_code = 'CHQ'; - $this->note_public='This is a comment (public)'; - $this->note_private='This is a comment (private)'; - $this->statut=0; - - // Lines - $nbp = 5; - $xnbp = 0; - while ($xnbp < $nbp) - { - $line=new CommandeFournisseurLigne($this->db); - $line->desc=$langs->trans("Description")." ".$xnbp; - $line->qty=1; - $line->subprice=100; - $line->price=100; - $line->tva_tx=19.6; - $line->localtax1_tx=0; - $line->localtax2_tx=0; - if ($xnbp == 2) - { - $line->total_ht=50; - $line->total_ttc=59.8; - $line->total_tva=9.8; - $line->remise_percent=50; - } - else - { - $line->total_ht=100; - $line->total_ttc=119.6; - $line->total_tva=19.6; - $line->remise_percent=00; - } - $line->fk_product=$prodid; - - $this->lines[$xnbp]=$line; - - $this->total_ht += $line->total_ht; - $this->total_tva += $line->total_tva; - $this->total_ttc += $line->total_ttc; - - $xnbp++; - } - } - - /** - * Charge les informations d'ordre info dans l'objet facture - * - * @param int $id Id de la facture a charger - * @return void - */ - public function info($id) - { - $sql = 'SELECT c.rowid, date_creation as datec, tms as datem, date_valid as date_validation, date_approve as datea, date_approve2 as datea2,'; - $sql.= ' fk_user_author, fk_user_modif, fk_user_valid, fk_user_approve, fk_user_approve2'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseur as c'; - $sql.= ' WHERE c.rowid = '.$id; - - $result=$this->db->query($sql); - if ($result) - { - if ($this->db->num_rows($result)) - { - $obj = $this->db->fetch_object($result); - $this->id = $obj->rowid; - if ($obj->fk_user_author) $this->user_creation_id = $obj->fk_user_author; - if ($obj->fk_user_valid) $this->user_validation_id = $obj->fk_user_valid; - if ($obj->fk_user_modif) $this->user_modification_id =$obj->fk_user_modif; - if ($obj->fk_user_approve) $this->user_approve_id = $obj->fk_user_approve; - if ($obj->fk_user_approve2) $this->user_approve_id2 = $obj->fk_user_approve2; - - $this->date_creation = $this->db->idate($obj->datec); - $this->date_modification = $this->db->idate($obj->datem); - $this->date_approve = $this->db->idate($obj->datea); - $this->date_approve2 = $this->db->idate($obj->datea2); - $this->date_validation = $this->db->idate($obj->date_validation); - } - $this->db->free($result); - } - else - { - dol_print_error($this->db); - } - } - - /** - * Charge indicateurs this->nb de tableau de bord - * - * @return int <0 si ko, >0 si ok - */ - function load_state_board() - { - global $conf, $user; - - $this->nb=array(); - $clause = "WHERE"; - - $sql = "SELECT count(co.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as co"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON co.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = "AND"; - } - $sql.= " ".$clause." co.entity = ".$conf->entity; - - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nb["supplier_orders"]=$obj->nb; - } - $this->db->free($resql); - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } - - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * - * @param User $user Objet user - * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK - */ - function load_board($user) - { - global $conf, $langs; - - $clause = " WHERE"; - - $sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.fk_statut, c.date_livraison as delivery_date"; - $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = " AND"; - } - $sql.= $clause." c.entity = ".$conf->entity; - $sql.= " AND (c.fk_statut BETWEEN 1 AND 2)"; - if ($user->societe_id) $sql.=" AND c.fk_soc = ".$user->societe_id; - - $resql=$this->db->query($sql); - if ($resql) - { - $commandestatic = new CommandeFournisseur($this->db); - - $response = new WorkboardResponse(); - $response->warning_delay=$conf->commande->fournisseur->warning_delay/60/60/24; - $response->label=$langs->trans("SuppliersOrdersToProcess"); - $response->url=DOL_URL_ROOT.'/fourn/commande/list.php?statut=1,2,3&mainmenu=commercial&leftmenu=orders_suppliers'; - $response->img=img_object('',"order"); - - while ($obj=$this->db->fetch_object($resql)) - { - $response->nbtodo++; - - $commandestatic->date_livraison = $this->db->jdate($obj->delivery_date); - $commandestatic->date_commande = $this->db->jdate($obj->date_commande); - $commandestatic->statut = $obj->fk_statut; - - if ($commandestatic->hasDelay()) { - $response->nbtodolate++; - } - } - - return $response; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } - - /** - * Returns the translated input method of object (defined if $this->methode_commande_id > 0). - * This function make a sql request to get translation. No cache yet, try to not use it inside a loop. - * - * @return string - */ - public function getInputMethod() - { - global $db, $langs; - - if ($this->methode_commande_id > 0) - { - $sql = "SELECT rowid, code, libelle as label"; - $sql.= " FROM ".MAIN_DB_PREFIX.'c_input_method'; - $sql.= " WHERE active=1 AND rowid = ".$db->escape($this->methode_commande_id); - - $resql = $db->query($sql); - if ($resql) - { - if ($db->num_rows($query)) - { - $obj = $db->fetch_object($query); - - $string = $langs->trans($obj->code); - if ($string == $obj->code) - { - $string = $obj->label != '-' ? $obj->label : ''; - } - return $string; - } - } - else dol_print_error($db); - } - - return ''; - } + $string = $langs->trans($obj->code); + if ($string == $obj->code) + { + $string = $obj->label != '-' ? $obj->label : ''; + } + return $string; + } + } + else dol_print_error($db); + } + + return ''; + } /** * Create a document onto disk according to template model. @@ -2738,12 +2738,12 @@ class CommandeFournisseur extends CommonOrder } /** - * Return the max number delivery delay in day - * - * @param Translate $langs Language object - * @return Translated string - */ - public function getMaxDeliveryTimeDay($langs) + * Return the max number delivery delay in day + * + * @param Translate $langs Language object + * @return Translated string + */ + public function getMaxDeliveryTimeDay($langs) { if (empty($this->lines)) return ''; @@ -2796,134 +2796,134 @@ class CommandeFournisseur extends CommonOrder return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } - /** - * Is the supplier order delayed? - * - * @return bool - */ - public function hasDelay() - { - global $conf; - - if (empty($this->date_delivery) && ! empty($this->date_livraison)) $this->date_delivery = $this->date_livraison; // For backward compatibility - - $now = dol_now(); - $date_to_test = empty($this->date_delivery) ? $this->date_commande : $this->date_delivery; - - return ($this->statut > 0 && $this->statut < 4) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); - } - - /** - * Show the customer delayed info - * - * @return string Show delayed information - */ - public function showDelay() - { - global $conf, $langs; - - if (empty($this->date_delivery) && ! empty($this->date_livraison)) $this->date_delivery = $this->date_livraison; // For backward compatibility - - if (empty($this->date_delivery)) $text=$langs->trans("OrderDate").' '.dol_print_date($this->date_commande, 'day'); - else $text=$text=$langs->trans("DeliveryDate").' '.dol_print_date($this->date_delivery, 'day'); - $text.=' '.($conf->commande->fournisseur->warning_delay>0?'+':'-').' '.round(abs($conf->commande->fournisseur->warning_delay)/3600/24,1).' '.$langs->trans("days").' < '.$langs->trans("Today"); - - return $text; - } - - - /** - * Calc status regarding to dispatched stock - * - * @param User $user User action - * @param int $closeopenorder Close if received - * @param string $comment Comment - * @return int <0 if KO, 0 if not applicable, >0 if OK - */ - public function calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='') - { - global $conf, $langs; - - if (! empty($conf->fournisseur->enabled)) - { - require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php'; - - $qtydelivered=array(); - $qtywished=array(); - - $supplierorderdispatch = new CommandeFournisseurDispatch($this->db); - $filter=array('t.fk_commande'=>$this->id); - if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) { - $filter['t.status']=1; // Restrict to lines with status validated - } - - $ret=$supplierorderdispatch->fetchAll('','',0,0,$filter); - if ($ret<0) - { - $this->error=$supplierorderdispatch->error; $this->errors=$supplierorderdispatch->errors; - return $ret; - } - else - { - if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines)>0) - { - $date_liv = dol_now(); - - // Build array with quantity deliverd by product - foreach($supplierorderdispatch->lines as $line) { - $qtydelivered[$line->fk_product]+=$line->qty; - } - foreach($this->lines as $line) { - $qtywished[$line->fk_product]+=$line->qty; - } - //Compare array - $diff_array=array_diff_assoc($qtydelivered,$qtywished); // Warning: $diff_array is done only on common keys. - $keysinwishednotindelivered=array_diff(array_keys($qtywished),array_keys($qtydelivered)); // To check we also have same number of keys - $keysindeliverednotinwished=array_diff(array_keys($qtydelivered),array_keys($qtywished)); // To check we also have same number of keys - /*var_dump(array_keys($qtydelivered)); + /** + * Is the supplier order delayed? + * + * @return bool + */ + public function hasDelay() + { + global $conf; + + if (empty($this->date_delivery) && ! empty($this->date_livraison)) $this->date_delivery = $this->date_livraison; // For backward compatibility + + $now = dol_now(); + $date_to_test = empty($this->date_delivery) ? $this->date_commande : $this->date_delivery; + + return ($this->statut > 0 && $this->statut < 4) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); + } + + /** + * Show the customer delayed info + * + * @return string Show delayed information + */ + public function showDelay() + { + global $conf, $langs; + + if (empty($this->date_delivery) && ! empty($this->date_livraison)) $this->date_delivery = $this->date_livraison; // For backward compatibility + + if (empty($this->date_delivery)) $text=$langs->trans("OrderDate").' '.dol_print_date($this->date_commande, 'day'); + else $text=$text=$langs->trans("DeliveryDate").' '.dol_print_date($this->date_delivery, 'day'); + $text.=' '.($conf->commande->fournisseur->warning_delay>0?'+':'-').' '.round(abs($conf->commande->fournisseur->warning_delay)/3600/24,1).' '.$langs->trans("days").' < '.$langs->trans("Today"); + + return $text; + } + + + /** + * Calc status regarding to dispatched stock + * + * @param User $user User action + * @param int $closeopenorder Close if received + * @param string $comment Comment + * @return int <0 if KO, 0 if not applicable, >0 if OK + */ + public function calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='') + { + global $conf, $langs; + + if (! empty($conf->fournisseur->enabled)) + { + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php'; + + $qtydelivered=array(); + $qtywished=array(); + + $supplierorderdispatch = new CommandeFournisseurDispatch($this->db); + $filter=array('t.fk_commande'=>$this->id); + if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) { + $filter['t.status']=1; // Restrict to lines with status validated + } + + $ret=$supplierorderdispatch->fetchAll('','',0,0,$filter); + if ($ret<0) + { + $this->error=$supplierorderdispatch->error; $this->errors=$supplierorderdispatch->errors; + return $ret; + } + else + { + if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines)>0) + { + $date_liv = dol_now(); + + // Build array with quantity deliverd by product + foreach($supplierorderdispatch->lines as $line) { + $qtydelivered[$line->fk_product]+=$line->qty; + } + foreach($this->lines as $line) { + $qtywished[$line->fk_product]+=$line->qty; + } + //Compare array + $diff_array=array_diff_assoc($qtydelivered,$qtywished); // Warning: $diff_array is done only on common keys. + $keysinwishednotindelivered=array_diff(array_keys($qtywished),array_keys($qtydelivered)); // To check we also have same number of keys + $keysindeliverednotinwished=array_diff(array_keys($qtydelivered),array_keys($qtywished)); // To check we also have same number of keys + /*var_dump(array_keys($qtydelivered)); var_dump(array_keys($qtywished)); var_dump($diff_array); var_dump($keysinwishednotindelivered); var_dump($keysindeliverednotinwished); exit;*/ - if (count($diff_array)==0 && count($keysinwishednotindelivered)==0 && count($keysindeliverednotinwished)==0) //No diff => mean everythings is received - { - if ($closeopenorder) - { - //$ret=$this->setStatus($user,5); - $ret = $this->Livraison($user, $date_liv, 'tot', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' - if ($ret<0) { - return -1; - } - return 5; - } - else - { - //Diff => received partially - //$ret=$this->setStatus($user,4); - $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' - if ($ret<0) { - return -1; - } - return 4; - } - } - else - { - //Diff => received partially - $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' - if ($ret<0) { - return -1; - } - return 4; - } - } - return 1; - } - } - return 0; - } + if (count($diff_array)==0 && count($keysinwishednotindelivered)==0 && count($keysindeliverednotinwished)==0) //No diff => mean everythings is received + { + if ($closeopenorder) + { + //$ret=$this->setStatus($user,5); + $ret = $this->Livraison($user, $date_liv, 'tot', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' + if ($ret<0) { + return -1; + } + return 5; + } + else + { + //Diff => received partially + //$ret=$this->setStatus($user,4); + $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' + if ($ret<0) { + return -1; + } + return 4; + } + } + else + { + //Diff => received partially + $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' + if ($ret<0) { + return -1; + } + return 4; + } + } + return 1; + } + } + return 0; + } } @@ -2933,22 +2933,22 @@ class CommandeFournisseur extends CommonOrder */ class CommandeFournisseurLigne extends CommonOrderLine { - public $element='commande_fournisseurdet'; + public $element='commande_fournisseurdet'; public $table_element='commande_fournisseurdet'; - public $oldline; + public $oldline; - /** - * Id of parent order - * @var int - */ - public $fk_commande; + /** + * Id of parent order + * @var int + */ + public $fk_commande; - // From llx_commande_fournisseurdet - public $fk_parent_line; - public $fk_facture; - public $label; - public $rang = 0; + // From llx_commande_fournisseurdet + public $fk_parent_line; + public $fk_facture; + public $label; + public $rang = 0; /** * Unit price without taxes @@ -2956,401 +2956,401 @@ class CommandeFournisseurLigne extends CommonOrderLine */ public $pu_ht; - public $date_start; - public $date_end; + public $date_start; + public $date_end; - // From llx_product_fournisseur_price + // From llx_product_fournisseur_price /** * Supplier reference of price when we added the line. May have been changed after line was added. * @var string */ - public $ref_supplier; - public $remise; - public $product_libelle; - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - $this->db= $db; - } - - /** - * Load line order - * - * @param int $rowid Id line order - * @return int <0 if KO, >0 if OK - */ - public function fetch($rowid) - { - $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx,'; - $sql.= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref,'; - $sql.= ' cd.remise, cd.remise_percent, cd.subprice,'; - $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_ttc,'; - $sql.= ' cd.total_localtax1, cd.total_localtax2,'; - $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,'; - $sql.= ' cd.date_start, cd.date_end, cd.fk_unit,'; + public $ref_supplier; + public $remise; + public $product_libelle; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + $this->db= $db; + } + + /** + * Load line order + * + * @param int $rowid Id line order + * @return int <0 if KO, >0 if OK + */ + public function fetch($rowid) + { + $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx,'; + $sql.= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref,'; + $sql.= ' cd.remise, cd.remise_percent, cd.subprice,'; + $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_ttc,'; + $sql.= ' cd.total_localtax1, cd.total_localtax2,'; + $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,'; + $sql.= ' cd.date_start, cd.date_end, cd.fk_unit,'; $sql.= ' cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; - $sql.= ' WHERE cd.rowid = '.$rowid; - $result = $this->db->query($sql); - if ($result) - { - $objp = $this->db->fetch_object($result); - - $this->rowid = $objp->rowid; - $this->id = $objp->rowid; - $this->fk_commande = $objp->fk_commande; - $this->desc = $objp->description; - $this->qty = $objp->qty; - $this->ref_fourn = $objp->ref; - $this->ref_supplier = $objp->ref; - $this->subprice = $objp->subprice; - $this->tva_tx = $objp->tva_tx; - $this->localtax1_tx = $objp->localtax1_tx; - $this->localtax2_tx = $objp->localtax2_tx; - $this->localtax1_type = $objp->localtax1_type; - $this->localtax2_type = $objp->localtax2_type; - $this->remise = $objp->remise; - $this->remise_percent = $objp->remise_percent; - $this->fk_product = $objp->fk_product; - $this->info_bits = $objp->info_bits; - $this->total_ht = $objp->total_ht; - $this->total_tva = $objp->total_tva; - $this->total_localtax1 = $objp->total_localtax1; - $this->total_localtax2 = $objp->total_localtax2; - $this->total_ttc = $objp->total_ttc; - $this->product_type = $objp->product_type; - - $this->ref = $objp->product_ref; - $this->product_ref = $objp->product_ref; - $this->product_libelle = $objp->product_libelle; - $this->product_desc = $objp->product_desc; - - $this->date_start = $this->db->jdate($objp->date_start); - $this->date_end = $this->db->jdate($objp->date_end); - $this->fk_unit = $objp->fk_unit; + $sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; + $sql.= ' WHERE cd.rowid = '.$rowid; + $result = $this->db->query($sql); + if ($result) + { + $objp = $this->db->fetch_object($result); + + $this->rowid = $objp->rowid; + $this->id = $objp->rowid; + $this->fk_commande = $objp->fk_commande; + $this->desc = $objp->description; + $this->qty = $objp->qty; + $this->ref_fourn = $objp->ref; + $this->ref_supplier = $objp->ref; + $this->subprice = $objp->subprice; + $this->tva_tx = $objp->tva_tx; + $this->localtax1_tx = $objp->localtax1_tx; + $this->localtax2_tx = $objp->localtax2_tx; + $this->localtax1_type = $objp->localtax1_type; + $this->localtax2_type = $objp->localtax2_type; + $this->remise = $objp->remise; + $this->remise_percent = $objp->remise_percent; + $this->fk_product = $objp->fk_product; + $this->info_bits = $objp->info_bits; + $this->total_ht = $objp->total_ht; + $this->total_tva = $objp->total_tva; + $this->total_localtax1 = $objp->total_localtax1; + $this->total_localtax2 = $objp->total_localtax2; + $this->total_ttc = $objp->total_ttc; + $this->product_type = $objp->product_type; + + $this->ref = $objp->product_ref; + $this->product_ref = $objp->product_ref; + $this->product_libelle = $objp->product_libelle; + $this->product_desc = $objp->product_desc; + + $this->date_start = $this->db->jdate($objp->date_start); + $this->date_end = $this->db->jdate($objp->date_end); + $this->fk_unit = $objp->fk_unit; $this->multicurrency_subprice = $objp->multicurrency_subprice; $this->multicurrency_total_ht = $objp->multicurrency_total_ht; $this->multicurrency_total_tva = $objp->multicurrency_total_tva; $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; - $this->db->free($result); - return 1; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Mise a jour de l'objet ligne de commande en base - * - * @return int <0 si ko, >0 si ok - */ - public function updateTotal() - { - $this->db->begin(); - - // Mise a jour ligne en base - $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseurdet SET"; - $sql.= " total_ht='".price2num($this->total_ht)."'"; - $sql.= ",total_tva='".price2num($this->total_tva)."'"; - $sql.= ",total_localtax1='".price2num($this->total_localtax1)."'"; - $sql.= ",total_localtax2='".price2num($this->total_localtax2)."'"; - $sql.= ",total_ttc='".price2num($this->total_ttc)."'"; - $sql.= " WHERE rowid = ".$this->rowid; - - dol_syslog(get_class($this)."::updateTotal", LOG_DEBUG); - - $resql=$this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -2; - } - } - - /** - * Insert line into database - * - * @param int $notrigger 1 = disable triggers - * @return int <0 if KO, >0 if OK - */ - public function insert($notrigger=0) - { - global $conf, $user; - - $error=0; - - dol_syslog(get_class($this)."::insert rang=".$this->rang); - - // Clean parameters - if (empty($this->tva_tx)) $this->tva_tx=0; - if (empty($this->localtax1_tx)) $this->localtax1_tx=0; - if (empty($this->localtax2_tx)) $this->localtax2_tx=0; - if (empty($this->localtax1_type)) $this->localtax1_type='0'; - if (empty($this->localtax2_type)) $this->localtax2_type='0'; - if (empty($this->total_localtax1)) $this->total_localtax1=0; - if (empty($this->total_localtax2)) $this->total_localtax2=0; - if (empty($this->rang)) $this->rang=0; - if (empty($this->remise)) $this->remise=0; - if (empty($this->remise_percent)) $this->remise_percent=0; - if (empty($this->info_bits)) $this->info_bits=0; - if (empty($this->special_code)) $this->special_code=0; - if (empty($this->fk_parent_line)) $this->fk_parent_line=0; - if (empty($this->pa_ht)) $this->pa_ht=0; - - // Multicurrency - if (!empty($this->multicurrency_code)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); - if (empty($this->fk_multicurrency)) - { - $this->multicurrency_code = $conf->currency; - $this->fk_multicurrency = 0; - $this->multicurrency_tx = 1; - } - - // Check parameters - if ($this->product_type < 0) return -1; - - $this->db->begin(); - - // Insertion dans base de la ligne - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " (fk_commande, label, description, date_start, date_end,"; - $sql.= " fk_product, product_type,"; - $sql.= " qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice, ref,"; - $sql.= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_unit,"; - $sql.= " fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc"; - $sql.= ")"; - $sql.= " VALUES (".$this->fk_commande.", '" . $this->db->escape($this->label) . "','" . $this->db->escape($this->desc) . "',"; - $sql.= " ".($this->date_start?"'".$this->db->idate($this->date_start)."'":"null").","; - $sql.= " ".($this->date_end?"'".$this->db->idate($this->date_end)."'":"null").","; - if ($this->fk_product) { $sql.= $this->fk_product.","; } - else { $sql.= "null,"; } - $sql.= "'".$this->db->escape($this->product_type)."',"; - $sql.= "'".$this->db->escape($this->qty)."', "; - - $sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->db->escape($this->vat_src_code)."'").","; - $sql.= " ".$this->tva_tx.", "; - $sql.= " ".$this->localtax1_tx.","; - $sql.= " ".$this->localtax2_tx.","; - $sql.= " '".$this->db->escape($this->localtax1_type)."',"; - $sql.= " '".$this->db->escape($this->localtax2_type)."',"; - $sql.= " ".$this->remise_percent.", ".price2num($this->subprice,'MU').", '".$this->db->escape($this->ref_supplier)."',"; - $sql.= " ".price2num($this->total_ht).","; - $sql.= " ".price2num($this->total_tva).","; - $sql.= " ".price2num($this->total_localtax1).","; - $sql.= " ".price2num($this->total_localtax2).","; - $sql.= " ".price2num($this->total_ttc).","; - $sql.= ($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'":"null"); - $sql.= ", ".($this->fk_multicurrency ? $this->fk_multicurrency : "null"); - $sql.= ", '".$this->db->escape($this->multicurrency_code)."'"; - $sql.= ", ".price2num($this->multicurrency_subprice); - $sql.= ", ".price2num($this->multicurrency_total_ht); - $sql.= ", ".price2num($this->multicurrency_total_tva); - $sql.= ", ".price2num($this->multicurrency_total_ttc); - $sql.= ")"; - - dol_syslog(get_class($this)."::insert", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); - $this->rowid =$this->id; - - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('LINEORDER_SUPPLIER_CREATE',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (!$error) { - $this->db->commit(); - return 1; - } - - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); - $this->errors[]=($this->errors?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->errors[]=$this->db->error(); - $this->db->rollback(); - return -2; - } - } - /** - * Update the line object into db - * - * @param int $notrigger 1 = disable triggers - * @return int <0 si ko, >0 si ok - */ - public function update($notrigger=0) - { - global $conf,$user; - - $error=0; - - // Mise a jour ligne en base - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; - $sql.= " description='".$this->db->escape($this->desc)."'"; - $sql.= ", subprice='".price2num($this->subprice)."'"; - //$sql.= ",remise='".price2num($remise)."'"; - $sql.= ", remise_percent='".price2num($this->remise_percent)."'"; + $this->db->free($result); + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Mise a jour de l'objet ligne de commande en base + * + * @return int <0 si ko, >0 si ok + */ + public function updateTotal() + { + $this->db->begin(); + + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseurdet SET"; + $sql.= " total_ht='".price2num($this->total_ht)."'"; + $sql.= ",total_tva='".price2num($this->total_tva)."'"; + $sql.= ",total_localtax1='".price2num($this->total_localtax1)."'"; + $sql.= ",total_localtax2='".price2num($this->total_localtax2)."'"; + $sql.= ",total_ttc='".price2num($this->total_ttc)."'"; + $sql.= " WHERE rowid = ".$this->rowid; + + dol_syslog(get_class($this)."::updateTotal", LOG_DEBUG); + + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -2; + } + } + + /** + * Insert line into database + * + * @param int $notrigger 1 = disable triggers + * @return int <0 if KO, >0 if OK + */ + public function insert($notrigger=0) + { + global $conf, $user; + + $error=0; + + dol_syslog(get_class($this)."::insert rang=".$this->rang); + + // Clean parameters + if (empty($this->tva_tx)) $this->tva_tx=0; + if (empty($this->localtax1_tx)) $this->localtax1_tx=0; + if (empty($this->localtax2_tx)) $this->localtax2_tx=0; + if (empty($this->localtax1_type)) $this->localtax1_type='0'; + if (empty($this->localtax2_type)) $this->localtax2_type='0'; + if (empty($this->total_localtax1)) $this->total_localtax1=0; + if (empty($this->total_localtax2)) $this->total_localtax2=0; + if (empty($this->rang)) $this->rang=0; + if (empty($this->remise)) $this->remise=0; + if (empty($this->remise_percent)) $this->remise_percent=0; + if (empty($this->info_bits)) $this->info_bits=0; + if (empty($this->special_code)) $this->special_code=0; + if (empty($this->fk_parent_line)) $this->fk_parent_line=0; + if (empty($this->pa_ht)) $this->pa_ht=0; + + // Multicurrency + if (!empty($this->multicurrency_code)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); + if (empty($this->fk_multicurrency)) + { + $this->multicurrency_code = $conf->currency; + $this->fk_multicurrency = 0; + $this->multicurrency_tx = 1; + } + + // Check parameters + if ($this->product_type < 0) return -1; + + $this->db->begin(); + + // Insertion dans base de la ligne + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " (fk_commande, label, description, date_start, date_end,"; + $sql.= " fk_product, product_type,"; + $sql.= " qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice, ref,"; + $sql.= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_unit,"; + $sql.= " fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc"; + $sql.= ")"; + $sql.= " VALUES (".$this->fk_commande.", '" . $this->db->escape($this->label) . "','" . $this->db->escape($this->desc) . "',"; + $sql.= " ".($this->date_start?"'".$this->db->idate($this->date_start)."'":"null").","; + $sql.= " ".($this->date_end?"'".$this->db->idate($this->date_end)."'":"null").","; + if ($this->fk_product) { $sql.= $this->fk_product.","; } + else { $sql.= "null,"; } + $sql.= "'".$this->db->escape($this->product_type)."',"; + $sql.= "'".$this->db->escape($this->qty)."', "; + + $sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->db->escape($this->vat_src_code)."'").","; + $sql.= " ".$this->tva_tx.", "; + $sql.= " ".$this->localtax1_tx.","; + $sql.= " ".$this->localtax2_tx.","; + $sql.= " '".$this->db->escape($this->localtax1_type)."',"; + $sql.= " '".$this->db->escape($this->localtax2_type)."',"; + $sql.= " ".$this->remise_percent.", ".price2num($this->subprice,'MU').", '".$this->db->escape($this->ref_supplier)."',"; + $sql.= " ".price2num($this->total_ht).","; + $sql.= " ".price2num($this->total_tva).","; + $sql.= " ".price2num($this->total_localtax1).","; + $sql.= " ".price2num($this->total_localtax2).","; + $sql.= " ".price2num($this->total_ttc).","; + $sql.= ($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'":"null"); + $sql.= ", ".($this->fk_multicurrency ? $this->fk_multicurrency : "null"); + $sql.= ", '".$this->db->escape($this->multicurrency_code)."'"; + $sql.= ", ".price2num($this->multicurrency_subprice); + $sql.= ", ".price2num($this->multicurrency_total_ht); + $sql.= ", ".price2num($this->multicurrency_total_tva); + $sql.= ", ".price2num($this->multicurrency_total_ttc); + $sql.= ")"; + + dol_syslog(get_class($this)."::insert", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); + $this->rowid =$this->id; + + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINEORDER_SUPPLIER_CREATE',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (!$error) { + $this->db->commit(); + return 1; + } + + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->errors[]=($this->errors?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->errors[]=$this->db->error(); + $this->db->rollback(); + return -2; + } + } + /** + * Update the line object into db + * + * @param int $notrigger 1 = disable triggers + * @return int <0 si ko, >0 si ok + */ + public function update($notrigger=0) + { + global $conf,$user; + + $error=0; + + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql.= " description='".$this->db->escape($this->desc)."'"; + $sql.= ", subprice='".price2num($this->subprice)."'"; + //$sql.= ",remise='".price2num($remise)."'"; + $sql.= ", remise_percent='".price2num($this->remise_percent)."'"; $sql.= ", vat_src_code = '".(empty($this->vat_src_code)?'':$this->vat_src_code)."'"; - $sql.= ", tva_tx='".price2num($this->tva_tx)."'"; - $sql.= ", localtax1_tx='".price2num($this->total_localtax1)."'"; - $sql.= ", localtax2_tx='".price2num($this->total_localtax2)."'"; - $sql.= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'"; - $sql.= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'"; - $sql.= ", qty='".price2num($this->qty)."'"; - $sql.= ", date_start=".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null"); - $sql.= ", date_end=".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); - $sql.= ", info_bits='".$this->db->escape($this->info_bits)."'"; - $sql.= ", total_ht='".price2num($this->total_ht)."'"; - $sql.= ", total_tva='".price2num($this->total_tva)."'"; - $sql.= ", total_localtax1='".price2num($this->total_localtax1)."'"; - $sql.= ", total_localtax2='".price2num($this->total_localtax2)."'"; - $sql.= ", total_ttc='".price2num($this->total_ttc)."'"; - $sql.= ", product_type=".$this->product_type; - $sql.= ($this->fk_unit ? ", fk_unit='".$this->db->escape($this->fk_unit)."'":", fk_unit=null"); - - // Multicurrency - $sql.= ", multicurrency_subprice=".price2num($this->multicurrency_subprice).""; - $sql.= ", multicurrency_total_ht=".price2num($this->multicurrency_total_ht).""; - $sql.= ", multicurrency_total_tva=".price2num($this->multicurrency_total_tva).""; - $sql.= ", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc).""; - - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::updateline", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result > 0) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - - if (! $error && ! $notrigger) - { - global $user; - // Call trigger - $result=$this->call_trigger('LINEORDER_SUPPLIER_UPDATE',$user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - // End call triggers - } - - if (! $error) - { - $this->db->commit(); - return $result; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Delete line in database - * - * @param int $notrigger 1=Disable call to triggers - * @return int <0 if KO, >0 if OK - */ - function delete($notrigger) - { - global $user; - - $error=0; - - $this->db->begin(); - - $sql = 'DELETE FROM '.MAIN_DB_PREFIX."commande_fournisseurdet WHERE rowid=".$this->rowid; - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - - if (!$notrigger) - { - // Call trigger - $result=$this->call_trigger('LINEORDER_SUPPLIER_DELETE',$user); - if ($result < 0) $error++; - // End call triggers - } - - if (!$error) - { - $this->db->commit(); - return 1; - } - - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } + $sql.= ", tva_tx='".price2num($this->tva_tx)."'"; + $sql.= ", localtax1_tx='".price2num($this->total_localtax1)."'"; + $sql.= ", localtax2_tx='".price2num($this->total_localtax2)."'"; + $sql.= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'"; + $sql.= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'"; + $sql.= ", qty='".price2num($this->qty)."'"; + $sql.= ", date_start=".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null"); + $sql.= ", date_end=".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); + $sql.= ", info_bits='".$this->db->escape($this->info_bits)."'"; + $sql.= ", total_ht='".price2num($this->total_ht)."'"; + $sql.= ", total_tva='".price2num($this->total_tva)."'"; + $sql.= ", total_localtax1='".price2num($this->total_localtax1)."'"; + $sql.= ", total_localtax2='".price2num($this->total_localtax2)."'"; + $sql.= ", total_ttc='".price2num($this->total_ttc)."'"; + $sql.= ", product_type=".$this->product_type; + $sql.= ($this->fk_unit ? ", fk_unit='".$this->db->escape($this->fk_unit)."'":", fk_unit=null"); + + // Multicurrency + $sql.= ", multicurrency_subprice=".price2num($this->multicurrency_subprice).""; + $sql.= ", multicurrency_total_ht=".price2num($this->multicurrency_total_ht).""; + $sql.= ", multicurrency_total_tva=".price2num($this->multicurrency_total_tva).""; + $sql.= ", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc).""; + + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::updateline", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result > 0) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $error && ! $notrigger) + { + global $user; + // Call trigger + $result=$this->call_trigger('LINEORDER_SUPPLIER_UPDATE',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // End call triggers + } + + if (! $error) + { + $this->db->commit(); + return $result; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + /** + * Delete line in database + * + * @param int $notrigger 1=Disable call to triggers + * @return int <0 if KO, >0 if OK + */ + function delete($notrigger) + { + global $user; + + $error=0; + + $this->db->begin(); + + $sql = 'DELETE FROM '.MAIN_DB_PREFIX."commande_fournisseurdet WHERE rowid=".$this->rowid; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + + if (!$notrigger) + { + // Call trigger + $result=$this->call_trigger('LINEORDER_SUPPLIER_DELETE',$user); + if ($result < 0) $error++; + // End call triggers + } + + if (!$error) + { + $this->db->commit(); + return 1; + } + + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } } diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index 92b6a3e40ec0bd104ba2979ee84040d4bd8a6583..43f39ce228734034eb52ffb43e688019846cd7b0 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -34,11 +34,11 @@ require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; */ class PaiementFourn extends Paiement { - public $element='payment_supplier'; - public $table_element='paiementfourn'; - public $picto = 'payment'; + public $element='payment_supplier'; + public $table_element='paiementfourn'; + public $picto = 'payment'; - var $statut; //Status of payment. 0 = unvalidated; 1 = validated + var $statut; //Status of payment. 0 = unvalidated; 1 = validated // fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...) // fk_paiement dans llx_paiement_facture est le rowid du paiement @@ -74,7 +74,7 @@ class PaiementFourn extends Paiement */ function fetch($id, $ref='', $fk_bank='') { - $error=0; + $error=0; $sql = 'SELECT p.rowid, p.ref, p.entity, p.datep as dp, p.amount, p.statut, p.fk_bank,'; $sql.= ' c.code as paiement_code, c.libelle as paiement_type,'; @@ -210,22 +210,22 @@ class PaiementFourn extends Paiement if ($resql) { // If we want to closed payed invoices - if ($closepaidinvoices) - { - $invoice=new FactureFournisseur($this->db); - $invoice->fetch($facid); - $paiement = $invoice->getSommePaiement(); - //$creditnotes=$invoice->getSumCreditNotesUsed(); - $creditnotes=0; - //$deposits=$invoice->getSumDepositsUsed(); - $deposits=0; - $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT'); - $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT'); - if ($remaintopay == 0) - { - $result=$invoice->set_paid($user, '', ''); - } - else dol_syslog("Remain to pay for invoice ".$facid." not null. We do nothing."); + if ($closepaidinvoices) + { + $invoice=new FactureFournisseur($this->db); + $invoice->fetch($facid); + $paiement = $invoice->getSommePaiement(); + //$creditnotes=$invoice->getSumCreditNotesUsed(); + $creditnotes=0; + //$deposits=$invoice->getSumDepositsUsed(); + $deposits=0; + $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT'); + $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT'); + if ($remaintopay == 0) + { + $result=$invoice->set_paid($user, '', ''); + } + else dol_syslog("Remain to pay for invoice ".$facid." not null. We do nothing."); } } else @@ -243,10 +243,10 @@ class PaiementFourn extends Paiement if (! $error) { - // Call trigger - $result=$this->call_trigger('PAYMENT_SUPPLIER_CREATE',$user); - if ($result < 0) $error++; - // End call triggers + // Call trigger + $result=$this->call_trigger('PAYMENT_SUPPLIER_CREATE',$user); + if ($result < 0) $error++; + // End call triggers } } else @@ -265,7 +265,7 @@ class PaiementFourn extends Paiement if ($totalamount <> 0 && $error == 0) // On accepte les montants negatifs { $this->amount=$total; - $this->total=$total; + $this->total=$total; $this->multicurrency_amount=$mtotal; $this->db->commit(); dol_syslog('PaiementFourn::Create Ok Total = '.$this->total); @@ -289,7 +289,7 @@ class PaiementFourn extends Paiement */ function delete($notrigger=0) { - global $conf, $user, $langs; + global $conf, $user, $langs; $bank_line_id = $this->bank_line; @@ -346,30 +346,30 @@ class PaiementFourn extends Paiement // Supprimer l'ecriture bancaire si paiement lie a ecriture if ($bank_line_id) { - $accline = new AccountLine($this->db); - $result=$accline->fetch($bank_line_id); - if ($result > 0) // If result = 0, record not found, we don't try to delete - { - $result=$accline->delete($user); - } - if ($result < 0) - { - $this->error=$accline->error; - $this->db->rollback(); - return -4; - } + $accline = new AccountLine($this->db); + $result=$accline->fetch($bank_line_id); + if ($result > 0) // If result = 0, record not found, we don't try to delete + { + $result=$accline->delete($user); + } + if ($result < 0) + { + $this->error=$accline->error; + $this->db->rollback(); + return -4; + } } if (! $notrigger) { - // Appel des triggers - $result=$this->call_trigger('PAYMENT_SUPPLIER_DELETE', $user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - // Fin appel triggers + // Appel des triggers + $result=$this->call_trigger('PAYMENT_SUPPLIER_DELETE', $user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // Fin appel triggers } $this->db->commit(); @@ -466,23 +466,23 @@ class PaiementFourn extends Paiement } /** - * Retourne le libelle du statut d'une facture (brouillon, validee, abandonnee, payee) - * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Libelle - */ + * Retourne le libelle du statut d'une facture (brouillon, validee, abandonnee, payee) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Libelle + */ function getLibStatut($mode=0) { return $this->LibStatut($this->statut,$mode); } /** - * Renvoi le libelle d'un statut donne - * - * @param int $status Statut - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Libelle du statut - */ + * Renvoi le libelle d'un statut donne + * + * @param int $status Statut + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Libelle du statut + */ function LibStatut($status,$mode=0) { global $langs; @@ -540,19 +540,19 @@ class PaiementFourn extends Paiement global $langs; $result=''; - $text=$this->ref; // Sometimes ref contains label - if (preg_match('/^\((.*)\)$/i',$text,$reg)) { - // Label generique car entre parentheses. On l'affiche en le traduisant - if ($reg[1]=='paiement') $reg[1]='Payment'; - $text=$langs->trans($reg[1]); - } - $label = $langs->trans("ShowPayment").': '.$text; + $text=$this->ref; // Sometimes ref contains label + if (preg_match('/^\((.*)\)$/i',$text,$reg)) { + // Label generique car entre parentheses. On l'affiche en le traduisant + if ($reg[1]=='paiement') $reg[1]='Payment'; + $text=$langs->trans($reg[1]); + } + $label = $langs->trans("ShowPayment").': '.$text; - $link = '<a href="'.DOL_URL_ROOT.'/fourn/paiement/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; - $linkend='</a>'; + $link = '<a href="'.DOL_URL_ROOT.'/fourn/paiement/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + $linkend='</a>'; - if ($withpicto) $result.=($link.img_object($langs->trans("ShowPayment"), 'payment', 'class="classfortooltip"').$linkend); + if ($withpicto) $result.=($link.img_object($langs->trans("ShowPayment"), 'payment', 'class="classfortooltip"').$linkend); if ($withpicto && $withpicto != 2) $result.=' '; if ($withpicto != 2) $result.=$link.$text.$linkend; return $result; @@ -699,13 +699,13 @@ class PaiementFourn extends Paiement if (empty($modele)) { - return 0; + return 0; } else { - $modelpath = "core/modules/supplier_payment/doc/"; + $modelpath = "core/modules/supplier_payment/doc/"; - return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); } } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index bb5ebc86babdbc85b08c2b8d01ccd48570cc12a2..ce95cfc7ebf1254ccbf94cbc0fc31ecfcf845039 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -123,43 +123,43 @@ $search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search // List of fields to search into when doing a "search in all" $fieldstosearchall = array( - 'cf.ref'=>'Ref', - 'cf.ref_supplier'=>'RefSupplierOrder', - 'pd.description'=>'Description', - 's.nom'=>"ThirdParty", - 'cf.note_public'=>'NotePublic', + 'cf.ref'=>'Ref', + 'cf.ref_supplier'=>'RefSupplierOrder', + 'pd.description'=>'Description', + 's.nom'=>"ThirdParty", + 'cf.note_public'=>'NotePublic', ); if (empty($user->socid)) $fieldstosearchall["cf.note_private"]="NotePrivate"; $checkedtypetiers=0; $arrayfields=array( - 'cf.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), - 'cf.ref_supplier'=>array('label'=>$langs->trans("RefOrderSupplierShort"), 'checked'=>1, 'enabled'=>1), - 'p.project_ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>0, 'enabled'=>1), - 'u.login'=>array('label'=>$langs->trans("AuthorRequest"), 'checked'=>1), - 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), - 's.town'=>array('label'=>$langs->trans("Town"), 'checked'=>1), - 's.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>1), - 'state.nom'=>array('label'=>$langs->trans("StateShort"), 'checked'=>0), - 'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0), - 'typent.code'=>array('label'=>$langs->trans("ThirdPartyType"), 'checked'=>$checkedtypetiers), - 'cf.date_commande'=>array('label'=>$langs->trans("OrderDateShort"), 'checked'=>1), - 'cf.date_delivery'=>array('label'=>$langs->trans("DateDeliveryPlanned"), 'checked'=>1, 'enabled'=>empty($conf->global->ORDER_DISABLE_DELIVERY_DATE)), - 'cf.total_ht'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1), - 'cf.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0), - 'cf.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0), - 'cf.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), - 'cf.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - 'cf.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), - 'cf.billed'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>1) + 'cf.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), + 'cf.ref_supplier'=>array('label'=>$langs->trans("RefOrderSupplierShort"), 'checked'=>1, 'enabled'=>1), + 'p.project_ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>0, 'enabled'=>1), + 'u.login'=>array('label'=>$langs->trans("AuthorRequest"), 'checked'=>1), + 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), + 's.town'=>array('label'=>$langs->trans("Town"), 'checked'=>1), + 's.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>1), + 'state.nom'=>array('label'=>$langs->trans("StateShort"), 'checked'=>0), + 'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0), + 'typent.code'=>array('label'=>$langs->trans("ThirdPartyType"), 'checked'=>$checkedtypetiers), + 'cf.date_commande'=>array('label'=>$langs->trans("OrderDateShort"), 'checked'=>1), + 'cf.date_delivery'=>array('label'=>$langs->trans("DateDeliveryPlanned"), 'checked'=>1, 'enabled'=>empty($conf->global->ORDER_DISABLE_DELIVERY_DATE)), + 'cf.total_ht'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1), + 'cf.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0), + 'cf.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0), + 'cf.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'cf.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), + 'cf.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), + 'cf.billed'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>1) ); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); - } + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } } @@ -177,277 +177,277 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - // Selection of new fields - include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - - // Purge search criteria - if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers - { - $ordermonth=''; - $orderyear=''; - $orderday=''; - $search_categ=''; - $search_user=''; - $search_sale=''; - $search_product_category=''; - $search_ref=''; - $search_refsupp=''; - $search_company=''; - $search_town=''; - $search_zip=""; - $search_state=""; - $search_type=''; - $search_country=''; - $search_type_thirdparty=''; - $search_request_author=''; - $search_total_ht=''; - $search_total_vat=''; - $search_total_ttc=''; - $search_project_ref=''; - $search_status=-1; - $orderyear=''; - $ordermonth=''; - $orderday=''; - $deliveryday=''; - $deliverymonth=''; - $deliveryyear=''; - $billed=''; - $toselect=''; - $search_array_options=array(); - } - if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha') - || GETPOST('button_search_x','alpha') || GETPOST('button_search.x','alpha') || GETPOST('button_search','alpha')) - { - $massaction=''; // Protection to avoid mass action if we force a new search during a mass action confirmation - } - - // Mass actions - $objectclass='CommandeFournisseur'; - $objectlabel='SupplierOrders'; - $permtoread = $user->rights->fournisseur->commande->lire; - $permtodelete = $user->rights->fournisseur->commande->supprimer; - $uploaddir = $conf->fournisseur->commande->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; - - // TODO Move this into mass action include - if ($massaction == 'confirm_createbills') - { - $orders = GETPOST('toselect','array'); - $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); - $validate_invoices = GETPOST('valdate_invoices', 'int'); - - $TFact = array(); - $TFactThird = array(); - - $nb_bills_created = 0; - - $db->begin(); - - foreach($orders as $id_order) { - - $cmd = new Commande($db); - if($cmd->fetch($id_order) <= 0) continue; - - $object = new Facture($db); - if(!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) $object = $TFactThird[$cmd->socid]; // If option "one bill per third" is set, we use already created order. - else { - - $object->socid = $cmd->socid; - $object->type = Facture::TYPE_STANDARD; - $object->cond_reglement_id = $cmd->cond_reglement_id; - $object->mode_reglement_id = $cmd->mode_reglement_id; - $object->fk_project = $cmd->fk_project; - - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $datefacture = dol_mktime(date("h"), date("M"), 0, date("m"), date("d"), date("Y")); - } - - $object->date = $datefacture; - $object->origin = 'commande'; - $object->origin_id = $id_order; - - $res = $object->create($user); - - if($res > 0) $nb_bills_created++; - - } - - if ($object->id > 0) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; - $sql.= "fk_source"; - $sql.= ", sourcetype"; - $sql.= ", fk_target"; - $sql.= ", targettype"; - $sql.= ") VALUES ("; - $sql.= $id_order; - $sql.= ", '".$object->origin."'"; - $sql.= ", ".$object->id; - $sql.= ", '".$object->element."'"; - $sql.= ")"; - - if (! $db->query($sql)) - { - $erorr++; - } - - if (! $error) - { - $lines = $cmd->lines; - if (empty($lines) && method_exists($cmd, 'fetch_lines')) - { - $cmd->fetch_lines(); - $lines = $cmd->lines; - } - - $fk_parent_line=0; - $num=count($lines); - - for ($i=0;$i<$num;$i++) - { - $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle); - if ($lines[$i]->subprice < 0) - { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc=$object->socid; - $discount->amount_ht=abs($lines[$i]->total_ht); - $discount->amount_tva=abs($lines[$i]->total_tva); - $discount->amount_ttc=abs($lines[$i]->total_ttc); - $discount->tva_tx=$lines[$i]->tva_tx; - $discount->fk_user=$user->id; - $discount->description=$desc; - $discountid=$discount->create($user); - if ($discountid > 0) - { - $result=$object->insert_discount($discountid); - //$result=$discount->link_to_invoice($lineid,$id); - } - else - { - setEventMessages($discount->error, $discount->errors, 'errors'); - $error++; - break; - } - } - else - { - // Positive line - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - // Date start - $date_start=false; - if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; - //Date end - $date_end=false; - if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) - { - $fk_parent_line = 0; - } - $result = $object->addline( - $desc, - $lines[$i]->subprice, - $lines[$i]->qty, - $lines[$i]->tva_tx, - $lines[$i]->localtax1_tx, - $lines[$i]->localtax2_tx, - $lines[$i]->fk_product, - $lines[$i]->remise_percent, - $date_start, - $date_end, - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_remise_except, - 'HT', - 0, - $product_type, - $ii, - $lines[$i]->special_code, - $object->origin, - $lines[$i]->rowid, - $fk_parent_line, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - $lines[$i]->label - ); - if ($result > 0) - { - $lineid=$result; - } - else - { - $lineid=0; - $error++; - break; - } - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) - { - $fk_parent_line = $result; - } - } - } - } - } - - $cmd->classifyBilled($user); // TODO Move this in workflow like done for customer orders - - if(!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) $TFactThird[$cmd->socid] = $object; - else $TFact[$object->id] = $object; - } - - // Build doc with all invoices - $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; - $toselect = array(); - - if (! $error && $validate_invoices) { - - $massaction = $action = 'builddoc'; - - foreach($TAllFact as &$object) - { - $object->validate($user); - if ($result <= 0) - { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); - break; - } - - $id = $object->id; // For builddoc action - - // Fac builddoc - $donotredirect = 1; - $upload_dir = $conf->facture->dir_output; - $permissioncreate=$user->rights->facture->creer; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - } - - $massaction = $action = 'confirm_createbills'; - } - - if (! $error) - { - $db->commit(); - setEventMessage($langs->trans('BillCreated', $nb_bills_created)); - } - else - { - $db->rollback(); - $action='create'; - $_GET["origin"]=$_POST["origin"]; - $_GET["originid"]=$_POST["originid"]; - setEventMessages($object->error, $object->errors, 'errors'); - $error++; - } - } + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // Purge search criteria + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $ordermonth=''; + $orderyear=''; + $orderday=''; + $search_categ=''; + $search_user=''; + $search_sale=''; + $search_product_category=''; + $search_ref=''; + $search_refsupp=''; + $search_company=''; + $search_town=''; + $search_zip=""; + $search_state=""; + $search_type=''; + $search_country=''; + $search_type_thirdparty=''; + $search_request_author=''; + $search_total_ht=''; + $search_total_vat=''; + $search_total_ttc=''; + $search_project_ref=''; + $search_status=-1; + $orderyear=''; + $ordermonth=''; + $orderday=''; + $deliveryday=''; + $deliverymonth=''; + $deliveryyear=''; + $billed=''; + $toselect=''; + $search_array_options=array(); + } + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha') + || GETPOST('button_search_x','alpha') || GETPOST('button_search.x','alpha') || GETPOST('button_search','alpha')) + { + $massaction=''; // Protection to avoid mass action if we force a new search during a mass action confirmation + } + + // Mass actions + $objectclass='CommandeFournisseur'; + $objectlabel='SupplierOrders'; + $permtoread = $user->rights->fournisseur->commande->lire; + $permtodelete = $user->rights->fournisseur->commande->supprimer; + $uploaddir = $conf->fournisseur->commande->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + + // TODO Move this into mass action include + if ($massaction == 'confirm_createbills') + { + $orders = GETPOST('toselect','array'); + $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); + $validate_invoices = GETPOST('valdate_invoices', 'int'); + + $TFact = array(); + $TFactThird = array(); + + $nb_bills_created = 0; + + $db->begin(); + + foreach($orders as $id_order) { + + $cmd = new Commande($db); + if($cmd->fetch($id_order) <= 0) continue; + + $object = new Facture($db); + if(!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) $object = $TFactThird[$cmd->socid]; // If option "one bill per third" is set, we use already created order. + else { + + $object->socid = $cmd->socid; + $object->type = Facture::TYPE_STANDARD; + $object->cond_reglement_id = $cmd->cond_reglement_id; + $object->mode_reglement_id = $cmd->mode_reglement_id; + $object->fk_project = $cmd->fk_project; + + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $datefacture = dol_mktime(date("h"), date("M"), 0, date("m"), date("d"), date("Y")); + } + + $object->date = $datefacture; + $object->origin = 'commande'; + $object->origin_id = $id_order; + + $res = $object->create($user); + + if($res > 0) $nb_bills_created++; + + } + + if ($object->id > 0) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; + $sql.= "fk_source"; + $sql.= ", sourcetype"; + $sql.= ", fk_target"; + $sql.= ", targettype"; + $sql.= ") VALUES ("; + $sql.= $id_order; + $sql.= ", '".$object->origin."'"; + $sql.= ", ".$object->id; + $sql.= ", '".$object->element."'"; + $sql.= ")"; + + if (! $db->query($sql)) + { + $erorr++; + } + + if (! $error) + { + $lines = $cmd->lines; + if (empty($lines) && method_exists($cmd, 'fetch_lines')) + { + $cmd->fetch_lines(); + $lines = $cmd->lines; + } + + $fk_parent_line=0; + $num=count($lines); + + for ($i=0;$i<$num;$i++) + { + $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle); + if ($lines[$i]->subprice < 0) + { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc=$object->socid; + $discount->amount_ht=abs($lines[$i]->total_ht); + $discount->amount_tva=abs($lines[$i]->total_tva); + $discount->amount_ttc=abs($lines[$i]->total_ttc); + $discount->tva_tx=$lines[$i]->tva_tx; + $discount->fk_user=$user->id; + $discount->description=$desc; + $discountid=$discount->create($user); + if ($discountid > 0) + { + $result=$object->insert_discount($discountid); + //$result=$discount->link_to_invoice($lineid,$id); + } + else + { + setEventMessages($discount->error, $discount->errors, 'errors'); + $error++; + break; + } + } + else + { + // Positive line + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + // Date start + $date_start=false; + if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; + //Date end + $date_end=false; + if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) + { + $fk_parent_line = 0; + } + $result = $object->addline( + $desc, + $lines[$i]->subprice, + $lines[$i]->qty, + $lines[$i]->tva_tx, + $lines[$i]->localtax1_tx, + $lines[$i]->localtax2_tx, + $lines[$i]->fk_product, + $lines[$i]->remise_percent, + $date_start, + $date_end, + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_remise_except, + 'HT', + 0, + $product_type, + $ii, + $lines[$i]->special_code, + $object->origin, + $lines[$i]->rowid, + $fk_parent_line, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + $lines[$i]->label + ); + if ($result > 0) + { + $lineid=$result; + } + else + { + $lineid=0; + $error++; + break; + } + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) + { + $fk_parent_line = $result; + } + } + } + } + } + + $cmd->classifyBilled($user); // TODO Move this in workflow like done for customer orders + + if(!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) $TFactThird[$cmd->socid] = $object; + else $TFact[$object->id] = $object; + } + + // Build doc with all invoices + $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; + $toselect = array(); + + if (! $error && $validate_invoices) { + + $massaction = $action = 'builddoc'; + + foreach($TAllFact as &$object) + { + $object->validate($user); + if ($result <= 0) + { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + break; + } + + $id = $object->id; // For builddoc action + + // Fac builddoc + $donotredirect = 1; + $upload_dir = $conf->facture->dir_output; + $permissioncreate=$user->rights->facture->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + } + + $massaction = $action = 'confirm_createbills'; + } + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans('BillCreated', $nb_bills_created)); + } + else + { + $db->rollback(); + $action='create'; + $_GET["origin"]=$_POST["origin"]; + $_GET["originid"]=$_POST["originid"]; + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } } @@ -474,9 +474,9 @@ if ($socid > 0) } if ($status) { - if ($status == '1,2,3') $title.=' - '.$langs->trans("StatusOrderToProcessShort"); - if ($status == '6,7') $title.=' - '.$langs->trans("StatusOrderCanceled"); - else $title.=' - '.$langs->trans($commandestatic->statuts[$status]); + if ($status == '1,2,3') $title.=' - '.$langs->trans("StatusOrderToProcessShort"); + if ($status == '6,7') $title.=' - '.$langs->trans("StatusOrderCanceled"); + else $title.=' - '.$langs->trans($commandestatic->statuts[$status]); } if ($billed > 0) $title.=' - '.$langs->trans("Billed"); @@ -513,8 +513,8 @@ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = cf.fk_projet"; if ($search_sale > 0 || (!$user->rights->societe->client->voir && ! $socid)) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; if ($search_user > 0) { - $sql.=", ".MAIN_DB_PREFIX."element_contact as ec"; - $sql.=", ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql.=", ".MAIN_DB_PREFIX."element_contact as ec"; + $sql.=", ".MAIN_DB_PREFIX."c_type_contact as tc"; } $sql.= ' WHERE cf.fk_soc = s.rowid'; $sql.= ' AND cf.entity IN ('.getEntity('supplier_order').')'; @@ -538,29 +538,29 @@ if ($search_status != '' && $search_status >= 0) } if ($ordermonth > 0) { - if ($orderyear > 0 && empty($orderday)) - $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_get_first_day($orderyear,$ordermonth,false))."' AND '".$db->idate(dol_get_last_day($orderyear,$ordermonth,false))."'"; - else if ($orderyear > 0 && ! empty($orderday)) - $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $ordermonth, $orderday, $orderyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $ordermonth, $orderday, $orderyear))."'"; - else - $sql.= " AND date_format(cf.date_commande, '%m') = '".$ordermonth."'"; + if ($orderyear > 0 && empty($orderday)) + $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_get_first_day($orderyear,$ordermonth,false))."' AND '".$db->idate(dol_get_last_day($orderyear,$ordermonth,false))."'"; + else if ($orderyear > 0 && ! empty($orderday)) + $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $ordermonth, $orderday, $orderyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $ordermonth, $orderday, $orderyear))."'"; + else + $sql.= " AND date_format(cf.date_commande, '%m') = '".$ordermonth."'"; } else if ($orderyear > 0) { - $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_get_first_day($orderyear,1,false))."' AND '".$db->idate(dol_get_last_day($orderyear,12,false))."'"; + $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_get_first_day($orderyear,1,false))."' AND '".$db->idate(dol_get_last_day($orderyear,12,false))."'"; } if ($deliverymonth > 0) { - if ($deliveryyear > 0 && empty($deliveryday)) - $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_get_first_day($deliveryyear,$deliverymonth,false))."' AND '".$db->idate(dol_get_last_day($deliveryyear,$deliverymonth,false))."'"; - else if ($deliveryyear > 0 && ! empty($deliveryday)) - $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $deliverymonth, $deliveryday, $deliveryyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $deliverymonth, $deliveryday, $deliveryyear))."'"; - else - $sql.= " AND date_format(cf.date_livraison, '%m') = '".$deliverymonth."'"; + if ($deliveryyear > 0 && empty($deliveryday)) + $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_get_first_day($deliveryyear,$deliverymonth,false))."' AND '".$db->idate(dol_get_last_day($deliveryyear,$deliverymonth,false))."'"; + else if ($deliveryyear > 0 && ! empty($deliveryday)) + $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $deliverymonth, $deliveryday, $deliveryyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $deliverymonth, $deliveryday, $deliveryyear))."'"; + else + $sql.= " AND date_format(cf.date_livraison, '%m') = '".$deliverymonth."'"; } else if ($deliveryyear > 0) { - $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_get_first_day($deliveryyear,1,false))."' AND '".$db->idate(dol_get_last_day($deliveryyear,12,false))."'"; + $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_get_first_day($deliveryyear,1,false))."' AND '".$db->idate(dol_get_last_day($deliveryyear,12,false))."'"; } if ($search_town) $sql.= natural_search('s.town', $search_town); if ($search_zip) $sql.= natural_search("s.zip",$search_zip); @@ -577,16 +577,16 @@ if ($search_project_ref != '') $sql.= natural_search("p.ref",$search_project_ref // Add where from extra fields foreach ($search_array_options as $key => $val) { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode=0; - if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric - if (in_array($typ, array('sellist')) && $crit != '0' && $crit != '-1') $mode=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); - } + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode=0; + if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric + if (in_array($typ, array('sellist')) && $crit != '0' && $crit != '-1') $mode=2; // Search on a foreign key int + if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0')) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); + } } // Add where from hooks $parameters=array(); @@ -624,7 +624,7 @@ if ($resql) $param=''; if ($socid > 0) $param.='&socid='.$socid; - if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($sall) $param.="&search_all=".$sall; if ($orderday) $param.='&orderday='.$orderday; @@ -644,20 +644,20 @@ if ($resql) if ($search_status >= 0) $param.="&search_status=".$search_status; if ($search_project_ref >= 0) $param.="&search_project_ref=".$search_project_ref; if ($billed != '') $param.="&billed=".$billed; - if ($show_files) $param.='&show_files=' .$show_files; - if ($optioncss != '') $param.='&optioncss='.$optioncss; + if ($show_files) $param.='&show_files=' .$show_files; + if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields foreach ($search_array_options as $key => $val) { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); } // List of mass actions available $arrayofmassactions = array( - 'presend'=>$langs->trans("SendByMail"), - 'builddoc'=>$langs->trans("PDFMerge"), + 'presend'=>$langs->trans("SendByMail"), + 'builddoc'=>$langs->trans("PDFMerge"), ); //if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); if ($user->rights->fournisseur->commande->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); @@ -666,13 +666,13 @@ if ($resql) // Lignes des champs de filtre print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; - if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">'; + if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">'; print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">'; print '<input type="hidden" name="action" value="list">'; - print '<input type="hidden" name="page" value="'.$page.'">'; + print '<input type="hidden" name="page" value="'.$page.'">'; print '<input type="hidden" name="contextpage" value="'.$contextpage.'">'; - print '<input type="hidden" name="sortfield" value="'.$sortfield.'">'; + print '<input type="hidden" name="sortfield" value="'.$sortfield.'">'; print '<input type="hidden" name="sortorder" value="'.$sortorder.'">'; print '<input type="hidden" name="viewstatut" value="'.$viewstatut.'">'; @@ -690,97 +690,97 @@ if ($resql) if ($massaction == 'createbills') { - //var_dump($_REQUEST); - print '<input type="hidden" name="massaction" value="confirm_createbills">'; - - print '<table class="border" width="100%" >'; - print '<tr>'; - print '<td class="titlefieldmiddle">'; - print $langs->trans('DateInvoice'); - print '</td>'; - print '<td>'; - print $form->select_date('', '', '', '', '', '', 1, 1); - print '</td>'; - print '</tr>'; - print '<tr>'; - print '<td>'; - print $langs->trans('CreateOneBillByThird'); - print '</td>'; - print '<td>'; - print $form->selectyesno('createbills_onebythird', '', 1); - print '</td>'; - print '</tr>'; - print '<tr>'; - print '<td>'; - print $langs->trans('ValidateInvoices'); - print '</td>'; - print '<td>'; - print $form->selectyesno('valdate_invoices', 1, 1); - print '</td>'; - print '</tr>'; - print '</table>'; - - print '<br>'; - print '<div class="center">'; - print '<input type="submit" class="button" id="createbills" name="createbills" value="'.$langs->trans('CreateInvoiceForThisCustomer').'"> '; - print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">'; - print '</div>'; - print '<br>'; + //var_dump($_REQUEST); + print '<input type="hidden" name="massaction" value="confirm_createbills">'; + + print '<table class="border" width="100%" >'; + print '<tr>'; + print '<td class="titlefieldmiddle">'; + print $langs->trans('DateInvoice'); + print '</td>'; + print '<td>'; + print $form->select_date('', '', '', '', '', '', 1, 1); + print '</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'; + print $langs->trans('CreateOneBillByThird'); + print '</td>'; + print '<td>'; + print $form->selectyesno('createbills_onebythird', '', 1); + print '</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'; + print $langs->trans('ValidateInvoices'); + print '</td>'; + print '<td>'; + print $form->selectyesno('valdate_invoices', 1, 1); + print '</td>'; + print '</tr>'; + print '</table>'; + + print '<br>'; + print '<div class="center">'; + print '<input type="submit" class="button" id="createbills" name="createbills" value="'.$langs->trans('CreateInvoiceForThisCustomer').'"> '; + print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">'; + print '</div>'; + print '<br>'; } if ($sall) - { - foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); - print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall); - } - - $moreforfilter=''; - - // If the user can view prospects other than his' - if ($user->rights->societe->client->voir || $socid) - { - $langs->load("commercial"); - $moreforfilter.='<div class="divsearchfield">'; - $moreforfilter.=$langs->trans('ThirdPartiesOfSaleRepresentative'). ': '; - $moreforfilter.=$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, 1, 'maxwidth200'); - $moreforfilter.='</div>'; - } - // If the user can view other users - if ($user->rights->user->user->lire) - { - $moreforfilter.='<div class="divsearchfield">'; - $moreforfilter.=$langs->trans('LinkedToSpecificUsers'). ': '; - $moreforfilter.=$form->select_dolusers($search_user, 'search_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200'); - $moreforfilter.='</div>'; - } - // If the user can view prospects other than his' - if ($conf->categorie->enabled && ($user->rights->produit->lire || $user->rights->service->lire)) - { - include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - $moreforfilter.='<div class="divsearchfield">'; - $moreforfilter.=$langs->trans('IncludingProductWithTag'). ': '; - $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1); - $moreforfilter.=$form->selectarray('search_product_category', $cate_arbo, $search_product_category, 1, 0, 0, '', 0, 0, 0, 0, 'maxwidth300', 1); - $moreforfilter.='</div>'; - } - $parameters=array(); - $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook - if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; - else $moreforfilter = $hookmanager->resPrint; - - if (! empty($moreforfilter)) - { - print '<div class="liste_titre liste_titre_bydiv centpercent">'; - print $moreforfilter; - print '</div>'; - } - - $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; - $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); - - print '<div class="div-table-responsive">'; - print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n"; + { + foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); + print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall); + } + + $moreforfilter=''; + + // If the user can view prospects other than his' + if ($user->rights->societe->client->voir || $socid) + { + $langs->load("commercial"); + $moreforfilter.='<div class="divsearchfield">'; + $moreforfilter.=$langs->trans('ThirdPartiesOfSaleRepresentative'). ': '; + $moreforfilter.=$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, 1, 'maxwidth200'); + $moreforfilter.='</div>'; + } + // If the user can view other users + if ($user->rights->user->user->lire) + { + $moreforfilter.='<div class="divsearchfield">'; + $moreforfilter.=$langs->trans('LinkedToSpecificUsers'). ': '; + $moreforfilter.=$form->select_dolusers($search_user, 'search_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200'); + $moreforfilter.='</div>'; + } + // If the user can view prospects other than his' + if ($conf->categorie->enabled && ($user->rights->produit->lire || $user->rights->service->lire)) + { + include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + $moreforfilter.='<div class="divsearchfield">'; + $moreforfilter.=$langs->trans('IncludingProductWithTag'). ': '; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1); + $moreforfilter.=$form->selectarray('search_product_category', $cate_arbo, $search_product_category, 1, 0, 0, '', 0, 0, 0, 0, 'maxwidth300', 1); + $moreforfilter.='</div>'; + } + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint; + else $moreforfilter = $hookmanager->resPrint; + + if (! empty($moreforfilter)) + { + print '<div class="liste_titre liste_titre_bydiv centpercent">'; + print $moreforfilter; + print '</div>'; + } + + $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); + + print '<div class="div-table-responsive">'; + print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n"; print '<tr class="liste_titre_filter">'; // Ref @@ -817,23 +817,23 @@ if ($resql) // State if (! empty($arrayfields['state.nom']['checked'])) { - print '<td class="liste_titre">'; - print '<input class="flat" size="4" type="text" name="search_state" value="'.dol_escape_htmltag($search_state).'">'; - print '</td>'; + print '<td class="liste_titre">'; + print '<input class="flat" size="4" type="text" name="search_state" value="'.dol_escape_htmltag($search_state).'">'; + print '</td>'; } // Country if (! empty($arrayfields['country.code_iso']['checked'])) { - print '<td class="liste_titre" align="center">'; - print $form->select_country($search_country,'search_country','',0,'maxwidth100'); - print '</td>'; + print '<td class="liste_titre" align="center">'; + print $form->select_country($search_country,'search_country','',0,'maxwidth100'); + print '</td>'; } // Company type if (! empty($arrayfields['typent.code']['checked'])) { - print '<td class="liste_titre maxwidthonsmartphone" align="center">'; - print $form->selectarray("search_type_thirdparty", $formcompany->typent_array(0), $search_type_thirdparty, 0, 0, 0, '', 0, 0, 0, (empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT)); - print '</td>'; + print '<td class="liste_titre maxwidthonsmartphone" align="center">'; + print $form->selectarray("search_type_thirdparty", $formcompany->typent_array(0), $search_type_thirdparty, 0, 0, 0, '', 0, 0, 0, (empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT)); + print '</td>'; } // Date order if (! empty($arrayfields['cf.date_commande']['checked'])) @@ -847,55 +847,55 @@ if ($resql) // Date delivery if (! empty($arrayfields['cf.date_delivery']['checked'])) { - print '<td class="liste_titre" align="center">'; - if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="deliveryday" value="'.$deliveryday.'">'; - print '<input class="flat" type="text" size="1" maxlength="2" name="deliverymonth" value="'.$deliverymonth.'">'; - $formother->select_year($deliveryyear?$deliveryyear:-1,'deliveryyear',1, 20, 5); - print '</td>'; + print '<td class="liste_titre" align="center">'; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="deliveryday" value="'.$deliveryday.'">'; + print '<input class="flat" type="text" size="1" maxlength="2" name="deliverymonth" value="'.$deliverymonth.'">'; + $formother->select_year($deliveryyear?$deliveryyear:-1,'deliveryyear',1, 20, 5); + print '</td>'; } if (! empty($arrayfields['cf.total_ht']['checked'])) { - // Amount - print '<td class="liste_titre" align="right">'; - print '<input class="flat" type="text" size="5" name="search_total_ht" value="'.$search_total_ht.'">'; - print '</td>'; + // Amount + print '<td class="liste_titre" align="right">'; + print '<input class="flat" type="text" size="5" name="search_total_ht" value="'.$search_total_ht.'">'; + print '</td>'; } if (! empty($arrayfields['cf.total_vat']['checked'])) { - // Amount - print '<td class="liste_titre" align="right">'; - print '<input class="flat" type="text" size="5" name="search_total_vat" value="'.$search_total_vat.'">'; - print '</td>'; + // Amount + print '<td class="liste_titre" align="right">'; + print '<input class="flat" type="text" size="5" name="search_total_vat" value="'.$search_total_vat.'">'; + print '</td>'; } if (! empty($arrayfields['cf.total_ttc']['checked'])) { - // Amount - print '<td class="liste_titre" align="right">'; - print '<input class="flat" type="text" size="5" name="search_total_ttc" value="'.$search_total_ttc.'">'; - print '</td>'; + // Amount + print '<td class="liste_titre" align="right">'; + print '<input class="flat" type="text" size="5" name="search_total_ttc" value="'.$search_total_ttc.'">'; + print '</td>'; } // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print '<td class="liste_titre'.($align?' '.$align:'').'">'; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print '<input class="flat'.($searchclass?' '.$searchclass:'').'" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">'; - } - print '</td>'; - } - } + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print '<td class="liste_titre'.($align?' '.$align:'').'">'; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print '<input class="flat'.($searchclass?' '.$searchclass:'').'" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">'; + } + print '</td>'; + } + } } // Fields from hook $parameters=array('arrayfields'=>$arrayfields); @@ -904,14 +904,14 @@ if ($resql) // Date creation if (! empty($arrayfields['cf.datec']['checked'])) { - print '<td class="liste_titre">'; - print '</td>'; + print '<td class="liste_titre">'; + print '</td>'; } // Date modification if (! empty($arrayfields['cf.tms']['checked'])) { - print '<td class="liste_titre">'; - print '</td>'; + print '<td class="liste_titre">'; + print '</td>'; } // Status if (! empty($arrayfields['cf.fk_statut']['checked'])) @@ -955,16 +955,16 @@ if ($resql) // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $sortonfield = "ef.".$key; + if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } } // Hook fields $parameters=array('arrayfields'=>$arrayfields); @@ -980,9 +980,9 @@ if ($resql) $total=0; $subtotal=0; - $productstat_cache=array(); + $productstat_cache=array(); - $userstatic = new User($db); + $userstatic = new User($db); $objectstatic=new CommandeFournisseur($db); $projectstatic=new Project($db); @@ -994,56 +994,56 @@ if ($resql) $obj = $db->fetch_object($resql); - $objectstatic->id=$obj->rowid; - $objectstatic->ref=$obj->ref; - $objectstatic->ref_supplier = $obj->ref_supplier; - $objectstatic->total_ht = $obj->total_ht; - $objectstatic->total_tva = $obj->total_tva; - $objectstatic->total_ttc = $obj->total_ttc; - $objectstatic->date_delivery = $db->jdate($obj->date_delivery); - $objectstatic->statut = $obj->fk_statut; + $objectstatic->id=$obj->rowid; + $objectstatic->ref=$obj->ref; + $objectstatic->ref_supplier = $obj->ref_supplier; + $objectstatic->total_ht = $obj->total_ht; + $objectstatic->total_tva = $obj->total_tva; + $objectstatic->total_ttc = $obj->total_ttc; + $objectstatic->date_delivery = $db->jdate($obj->date_delivery); + $objectstatic->statut = $obj->fk_statut; print '<tr class="oddeven">'; // Ref - if (! empty($arrayfields['cf.ref']['checked'])) - { - print '<td class="nowrap">'; - - print '<table class="nobordernopadding"><tr class="nocellnopadd">'; - // Picto + Ref - print '<td class="nobordernopadding nowrap">'; - print $objectstatic->getNomUrl(1); - print '</td>'; - // Warning - //print '<td style="min-width: 20px" class="nobordernopadding nowrap">'; - //print '</td>'; - // Other picto tool - print '<td width="16" align="right" class="nobordernopadding hideonsmartphone">'; + if (! empty($arrayfields['cf.ref']['checked'])) + { + print '<td class="nowrap">'; + + print '<table class="nobordernopadding"><tr class="nocellnopadd">'; + // Picto + Ref + print '<td class="nobordernopadding nowrap">'; + print $objectstatic->getNomUrl(1); + print '</td>'; + // Warning + //print '<td style="min-width: 20px" class="nobordernopadding nowrap">'; + //print '</td>'; + // Other picto tool + print '<td width="16" align="right" class="nobordernopadding hideonsmartphone">'; $filename=dol_sanitizeFileName($obj->ref); $filedir=$conf->fournisseur->commande->dir_output.'/' . dol_sanitizeFileName($obj->ref); print $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); print '</td></tr></table>'; print '</td>'."\n"; - if (! $i) $totalarray['nbfield']++; - } + if (! $i) $totalarray['nbfield']++; + } // Ref Supplier - if (! empty($arrayfields['cf.ref_supplier']['checked'])) - { - print '<td>'.$obj->ref_supplier.'</td>'."\n"; - if (! $i) $totalarray['nbfield']++; - } + if (! empty($arrayfields['cf.ref_supplier']['checked'])) + { + print '<td>'.$obj->ref_supplier.'</td>'."\n"; + if (! $i) $totalarray['nbfield']++; + } // Project - if (! empty($arrayfields['p.project_ref']['checked'])) - { + if (! empty($arrayfields['p.project_ref']['checked'])) + { $projectstatic->id=$obj->project_id; $projectstatic->ref=$obj->project_ref; print '<td>'; if ($obj->project_id > 0) print $projectstatic->getNomUrl(1); print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + if (! $i) $totalarray['nbfield']++; + } // Author $userstatic->id = $obj->fk_user_author; $userstatic->lastname = $obj->lastname; @@ -1052,169 +1052,169 @@ if ($resql) $userstatic->photo = $obj->photo; if (! empty($arrayfields['u.login']['checked'])) { - print "<td>"; - if ($userstatic->id) print $userstatic->getNomUrl(1); - else print " "; - print "</td>"; - if (! $i) $totalarray['nbfield']++; + print "<td>"; + if ($userstatic->id) print $userstatic->getNomUrl(1); + else print " "; + print "</td>"; + if (! $i) $totalarray['nbfield']++; } - // Thirdparty - if (! empty($arrayfields['s.nom']['checked'])) - { - print '<td>'; + // Thirdparty + if (! empty($arrayfields['s.nom']['checked'])) + { + print '<td>'; $thirdpartytmp->id = $obj->socid; $thirdpartytmp->name = $obj->name; print $thirdpartytmp->getNomUrl(1,'supplier'); print '</td>'."\n"; - if (! $i) $totalarray['nbfield']++; - } - // Town - if (! empty($arrayfields['s.town']['checked'])) - { - print '<td class="nocellnopadd">'; - print $obj->town; - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // Zip - if (! empty($arrayfields['s.zip']['checked'])) - { - print '<td class="nocellnopadd">'; - print $obj->zip; - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // State - if (! empty($arrayfields['state.nom']['checked'])) - { - print "<td>".$obj->state_name."</td>\n"; - if (! $i) $totalarray['nbfield']++; - } - // Country - if (! empty($arrayfields['country.code_iso']['checked'])) - { - print '<td align="center">'; - $tmparray=getCountry($obj->fk_pays,'all'); - print $tmparray['label']; - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // Type ent - if (! empty($arrayfields['typent.code']['checked'])) - { - print '<td align="center">'; - if (count($typenArray)==0) $typenArray = $formcompany->typent_array(1); - print $typenArray[$obj->typent_code]; - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + if (! $i) $totalarray['nbfield']++; + } + // Town + if (! empty($arrayfields['s.town']['checked'])) + { + print '<td class="nocellnopadd">'; + print $obj->town; + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + // Zip + if (! empty($arrayfields['s.zip']['checked'])) + { + print '<td class="nocellnopadd">'; + print $obj->zip; + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + // State + if (! empty($arrayfields['state.nom']['checked'])) + { + print "<td>".$obj->state_name."</td>\n"; + if (! $i) $totalarray['nbfield']++; + } + // Country + if (! empty($arrayfields['country.code_iso']['checked'])) + { + print '<td align="center">'; + $tmparray=getCountry($obj->fk_pays,'all'); + print $tmparray['label']; + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + // Type ent + if (! empty($arrayfields['typent.code']['checked'])) + { + print '<td align="center">'; + if (count($typenArray)==0) $typenArray = $formcompany->typent_array(1); + print $typenArray[$obj->typent_code]; + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } // Order date if (! empty($arrayfields['cf.date_commande']['checked'])) { - print '<td align="center">'; - if ($obj->date_commande) print dol_print_date($db->jdate($obj->date_commande), 'day'); - else print ''; - print '</td>'; - if (! $i) $totalarray['nbfield']++; + print '<td align="center">'; + if ($obj->date_commande) print dol_print_date($db->jdate($obj->date_commande), 'day'); + else print ''; + print '</td>'; + if (! $i) $totalarray['nbfield']++; } // Plannned date of delivery if (! empty($arrayfields['cf.date_delivery']['checked'])) { - print '<td align="center">'; - print dol_print_date($db->jdate($obj->date_delivery), 'day'); - if ($objectstatic->hasDelay() && ! empty($objectstatic->date_delivery)) { - print ' '.img_picto($langs->trans("Late").' : '.$objectstatic->showDelay(), "warning"); - } - print '</td>'; - if (! $i) $totalarray['nbfield']++; + print '<td align="center">'; + print dol_print_date($db->jdate($obj->date_delivery), 'day'); + if ($objectstatic->hasDelay() && ! empty($objectstatic->date_delivery)) { + print ' '.img_picto($langs->trans("Late").' : '.$objectstatic->showDelay(), "warning"); + } + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + // Amount HT + if (! empty($arrayfields['cf.total_ht']['checked'])) + { + print '<td align="right">'.price($obj->total_ht)."</td>\n"; + if (! $i) $totalarray['nbfield']++; + if (! $i) $totalarray['totalhtfield']=$totalarray['nbfield']; + $totalarray['totalht'] += $obj->total_ht; + } + // Amount VAT + if (! empty($arrayfields['cf.total_vat']['checked'])) + { + print '<td align="right">'.price($obj->total_tva)."</td>\n"; + if (! $i) $totalarray['nbfield']++; + if (! $i) $totalarray['totalvatfield']=$totalarray['nbfield']; + $totalarray['totalvat'] += $obj->total_tva; + } + // Amount TTC + if (! empty($arrayfields['cf.total_ttc']['checked'])) + { + print '<td align="right">'.price($obj->total_ttc)."</td>\n"; + if (! $i) $totalarray['nbfield']++; + if (! $i) $totalarray['totalttcfield']=$totalarray['nbfield']; + $totalarray['totalttc'] += $obj->total_ttc; + } + + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print '<td'; + $align=$extrafields->getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Date creation + if (! empty($arrayfields['cf.datec']['checked'])) + { + print '<td align="center" class="nowrap">'; + print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + // Date modification + if (! empty($arrayfields['cf.tms']['checked'])) + { + print '<td align="center" class="nowrap">'; + print dol_print_date($db->jdate($obj->date_update), 'dayhour'); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + // Status + if (! empty($arrayfields['cf.fk_statut']['checked'])) + { + print '<td align="right" class="nowrap">'.$objectstatic->LibStatut($obj->fk_statut, 5, $obj->billed, 1).'</td>'; + if (! $i) $totalarray['nbfield']++; } - // Amount HT - if (! empty($arrayfields['cf.total_ht']['checked'])) - { - print '<td align="right">'.price($obj->total_ht)."</td>\n"; - if (! $i) $totalarray['nbfield']++; - if (! $i) $totalarray['totalhtfield']=$totalarray['nbfield']; - $totalarray['totalht'] += $obj->total_ht; - } - // Amount VAT - if (! empty($arrayfields['cf.total_vat']['checked'])) - { - print '<td align="right">'.price($obj->total_tva)."</td>\n"; - if (! $i) $totalarray['nbfield']++; - if (! $i) $totalarray['totalvatfield']=$totalarray['nbfield']; - $totalarray['totalvat'] += $obj->total_tva; - } - // Amount TTC - if (! empty($arrayfields['cf.total_ttc']['checked'])) - { - print '<td align="right">'.price($obj->total_ttc)."</td>\n"; - if (! $i) $totalarray['nbfield']++; - if (! $i) $totalarray['totalttcfield']=$totalarray['nbfield']; - $totalarray['totalttc'] += $obj->total_ttc; - } - - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print '<td'; - $align=$extrafields->getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - } - } - // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); - $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Date creation - if (! empty($arrayfields['cf.datec']['checked'])) - { - print '<td align="center" class="nowrap">'; - print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // Date modification - if (! empty($arrayfields['cf.tms']['checked'])) - { - print '<td align="center" class="nowrap">'; - print dol_print_date($db->jdate($obj->date_update), 'dayhour'); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // Status - if (! empty($arrayfields['cf.fk_statut']['checked'])) - { - print '<td align="right" class="nowrap">'.$objectstatic->LibStatut($obj->fk_statut, 5, $obj->billed, 1).'</td>'; - if (! $i) $totalarray['nbfield']++; - } // Billed - if (! empty($arrayfields['cf.billed']['checked'])) - { - print '<td align="center">'.yn($obj->billed).'</td>'; - if (! $i) $totalarray['nbfield']++; - } - - // Action column - print '<td class="nowrap" align="center">'; - if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - { - $selected=0; - if (in_array($obj->rowid, $arrayofselected)) $selected=1; - print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected?' checked="checked"':'').'>'; - } - print '</td>'; - if (! $i) $totalarray['nbfield']++; + if (! empty($arrayfields['cf.billed']['checked'])) + { + print '<td align="center">'.yn($obj->billed).'</td>'; + if (! $i) $totalarray['nbfield']++; + } + + // Action column + print '<td class="nowrap" align="center">'; + if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected=0; + if (in_array($obj->rowid, $arrayofselected)) $selected=1; + print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected?' checked="checked"':'').'>'; + } + print '</td>'; + if (! $i) $totalarray['nbfield']++; print "</tr>\n"; $i++; @@ -1225,21 +1225,21 @@ if ($resql) if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) { - /* + /* * Show list of available documents */ - $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; - $urlsource.=str_replace('&','&',$param); + $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; + $urlsource.=str_replace('&','&',$param); - $filedir=$diroutputmassaction; - $genallowed=$user->rights->fournisseur->commande->lire; - $delallowed=$user->rights->fournisseur->commande->lire; + $filedir=$diroutputmassaction; + $genallowed=$user->rights->fournisseur->commande->lire; + $delallowed=$user->rights->fournisseur->commande->lire; - print $formfile->showdocuments('massfilesarea_supplier_order','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,''); + print $formfile->showdocuments('massfilesarea_supplier_order','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,''); } else { - print '<br><a name="show_files"></a><a href="'.$_SERVER["PHP_SELF"].'?show_files=1'.$param.'#show_files">'.$langs->trans("ShowTempMassFilesArea").'</a>'; + print '<br><a name="show_files"></a><a href="'.$_SERVER["PHP_SELF"].'?show_files=1'.$param.'#show_files">'.$langs->trans("ShowTempMassFilesArea").'</a>'; } $db->free($resql); diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index c3030574ce1ea7278623478ec9cacb243e5988dd..4126ef8c1344fc61b729746b18f7b6fc0ee13a7d 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -54,20 +54,20 @@ $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (! empty($co if ($action == 'setnote' && $user->rights->fournisseur->facture->creer) { - $db->begin(); - - $object->fetch($id); - $result = $object->update_note(GETPOST('note','none')); - if ($result > 0) - { - $db->commit(); - $action=''; - } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - $db->rollback(); - } + $db->begin(); + + $object->fetch($id); + $result = $object->update_note(GETPOST('note','none')); + if ($result > 0) + { + $db->commit(); + $action=''; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + $db->rollback(); + } } if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->fournisseur->facture->supprimer) @@ -90,8 +90,8 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->fournisse } if ($action == 'confirm_valide' && $confirm == 'yes' && - ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->facture->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_invoice_advance->validate))) + ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->facture->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_invoice_advance->validate))) ) { $db->begin(); @@ -113,7 +113,7 @@ if ($action == 'confirm_valide' && $confirm == 'yes' && if ($action == 'setnum_paiement' && ! empty($_POST['num_paiement'])) { $object->fetch($id); - $res = $object->update_num($_POST['num_paiement']); + $res = $object->update_num($_POST['num_paiement']); if ($res === 0) { setEventMessages($langs->trans('PaymentNumberUpdateSucceeded'), null, 'mesgs'); @@ -127,7 +127,7 @@ if ($action == 'setnum_paiement' && ! empty($_POST['num_paiement'])) if ($action == 'setdatep' && ! empty($_POST['datepday'])) { $object->fetch($id); - $datepaye = dol_mktime(12, 0, 0, $_POST['datepmonth'], $_POST['datepday'], $_POST['datepyear']); + $datepaye = dol_mktime(12, 0, 0, $_POST['datepmonth'], $_POST['datepday'], $_POST['datepyear']); $res = $object->update_date($datepaye); if ($res === 0) { @@ -197,18 +197,18 @@ if ($result > 0) print '</td></tr>';*/ // Date payment - print '<tr><td class="titlefield" colspan="2">'.$form->editfieldkey("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).'</td><td colspan="3">'; - print $form->editfieldval("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'datepicker','',null,$langs->trans('PaymentDateUpdateSucceeded')); - print '</td></tr>'; + print '<tr><td class="titlefield" colspan="2">'.$form->editfieldkey("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).'</td><td colspan="3">'; + print $form->editfieldval("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'datepicker','',null,$langs->trans('PaymentDateUpdateSucceeded')); + print '</td></tr>'; // Payment mode $labeltype=$langs->trans("PaymentType".$object->type_code)!=("PaymentType".$object->type_code)?$langs->trans("PaymentType".$object->type_code):$object->type_libelle; print '<tr><td colspan="2">'.$langs->trans('PaymentMode').'</td><td colspan="3">'.$labeltype.'</td></tr>'; // Payment numero - print '<tr><td colspan="2">'.$form->editfieldkey("Numero",'num_paiement',$object->numero,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).'</td><td colspan="3">'; - print $form->editfieldval("Numero",'num_paiement',$object->numero,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'string','',null,$langs->trans('PaymentNumberUpdateSucceeded')); - print '</td></tr>'; + print '<tr><td colspan="2">'.$form->editfieldkey("Numero",'num_paiement',$object->numero,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).'</td><td colspan="3">'; + print $form->editfieldval("Numero",'num_paiement',$object->numero,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'string','',null,$langs->trans('PaymentNumberUpdateSucceeded')); + print '</td></tr>'; // Amount print '<tr><td colspan="2">'.$langs->trans('Amount').'</td><td colspan="3">'.price($object->montant,'',$langs,0,0,-1,$conf->currency).'</td></tr>'; @@ -219,41 +219,41 @@ if ($result > 0) } // Note - print '<tr><td colspan="2">'.$form->editfieldkey("Note",'note',$object->note,$object,$user->rights->fournisseur->facture->creer).'</td><td colspan="3">'; - print $form->editfieldval("Note",'note',$object->note,$object,$user->rights->fournisseur->facture->creer,'textarea'); - print '</td></tr>'; + print '<tr><td colspan="2">'.$form->editfieldkey("Note",'note',$object->note,$object,$user->rights->fournisseur->facture->creer).'</td><td colspan="3">'; + print $form->editfieldval("Note",'note',$object->note,$object,$user->rights->fournisseur->facture->creer,'textarea'); + print '</td></tr>'; $allow_delete = 1 ; - // Bank account + // Bank account if (! empty($conf->banque->enabled)) { if ($object->bank_account) { - $bankline=new AccountLine($db); - $bankline->fetch($object->bank_line); - if ($bankline->rappro) - { - $allow_delete=0; - $title_button = dol_escape_htmltag($langs->transnoentitiesnoconv("CantRemoveConciliatedPayment")); - } - - print '<tr>'; - print '<td colspan="2">'.$langs->trans('BankTransactionLine').'</td>'; - print '<td colspan="3">'; - print $bankline->getNomUrl(1,0,'showconciliated'); - print '</td>'; - print '</tr>'; - - print '<tr>'; - print '<td colspan="2">'.$langs->trans('BankAccount').'</td>'; + $bankline=new AccountLine($db); + $bankline->fetch($object->bank_line); + if ($bankline->rappro) + { + $allow_delete=0; + $title_button = dol_escape_htmltag($langs->transnoentitiesnoconv("CantRemoveConciliatedPayment")); + } + + print '<tr>'; + print '<td colspan="2">'.$langs->trans('BankTransactionLine').'</td>'; + print '<td colspan="3">'; + print $bankline->getNomUrl(1,0,'showconciliated'); + print '</td>'; + print '</tr>'; + + print '<tr>'; + print '<td colspan="2">'.$langs->trans('BankAccount').'</td>'; print '<td colspan="3">'; $accountstatic=new Account($db); $accountstatic->fetch($bankline->fk_account); - print $accountstatic->getNomUrl(1); - print '</td>'; - print '</tr>'; - } - } + print $accountstatic->getNomUrl(1); + print '</td>'; + print '</tr>'; + } + } print '</table>'; @@ -315,7 +315,7 @@ if ($result > 0) if ($objp->paye == 1) { $allow_delete = 0; - $title_button = dol_escape_htmltag($langs->transnoentitiesnoconv("CantRemovePaymentWithOneInvoicePaid")); + $title_button = dol_escape_htmltag($langs->transnoentitiesnoconv("CantRemovePaymentWithOneInvoicePaid")); } $total = $total + $objp->amount; $i++; @@ -343,8 +343,8 @@ if ($result > 0) { if ($user->societe_id == 0 && $object->statut == 0 && $action == '') { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->facture->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_invoice_advance->validate))) + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->facture->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_invoice_advance->validate))) { print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=valide">'.$langs->trans('Valid').'</a>'; @@ -355,14 +355,14 @@ if ($result > 0) { if ($user->rights->fournisseur->facture->supprimer) { - if ($allow_delete) - { + if ($allow_delete) + { print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete">'.$langs->trans('Delete').'</a>'; - } - else - { - print '<a class="butActionRefused" href="#" title="'.$title_button.'">'.$langs->trans('Delete').'</a>'; - } + } + else + { + print '<a class="butActionRefused" href="#" title="'.$title_button.'">'.$langs->trans('Delete').'</a>'; + } } } print '</div>'; @@ -372,27 +372,27 @@ if ($result > 0) /* * Documents generes */ - $ref=dol_sanitizeFileName($object->ref); - $filedir = $conf->fournisseur->payment->dir_output.'/'.dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER['PHP_SELF'].'?id='.$object->id; - $genallowed=$user->rights->fournisseur->facture->creer; - $delallowed=$user->rights->fournisseur->facture->supprimer; - $modelpdf=(! empty($object->modelpdf)?$object->modelpdf:(empty($conf->global->SUPPLIER_PAYMENT_ADDON_PDF)?'':$conf->global->SUPPLIER_PAYMENT_ADDON_PDF)); + $ref=dol_sanitizeFileName($object->ref); + $filedir = $conf->fournisseur->payment->dir_output.'/'.dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$object->id; + $genallowed=$user->rights->fournisseur->facture->creer; + $delallowed=$user->rights->fournisseur->facture->supprimer; + $modelpdf=(! empty($object->modelpdf)?$object->modelpdf:(empty($conf->global->SUPPLIER_PAYMENT_ADDON_PDF)?'':$conf->global->SUPPLIER_PAYMENT_ADDON_PDF)); - print $formfile->showdocuments('supplier_payment',$ref,$filedir,$urlsource,$genallowed,$delallowed,$modelpdf,1,0,0,40,0,'','','',$societe->default_lang); - $somethingshown=$formfile->numoffiles; + print $formfile->showdocuments('supplier_payment',$ref,$filedir,$urlsource,$genallowed,$delallowed,$modelpdf,1,0,0,40,0,'','','',$societe->default_lang); + $somethingshown=$formfile->numoffiles; print '</div><div class="fichehalfright"><div class="ficheaddleft">'; - //print '</td><td valign="top" width="50%">'; - //print '<br>'; + //print '</td><td valign="top" width="50%">'; + //print '<br>'; - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - $somethingshown = $formactions->showactions($object,'supplier_payment',$socid,1,'listaction'.($genallowed?'largetitle':'')); + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + $somethingshown = $formactions->showactions($object,'supplier_payment',$socid,1,'listaction'.($genallowed?'largetitle':'')); print '</div></div></div>'; - //print '</td></tr></table>'; + //print '</td></tr></table>'; } else diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 382530225fdbf81ee4715432ad82ca51026e936a..ba976c2ee4875629b3fa5b714c764463c27569b0 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -36,277 +36,403 @@ class Holiday extends CommonObject public $table_element='holiday'; protected $isnolinkedbythird = 1; // No field fk_soc protected $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - public $picto = 'holiday'; + public $picto = 'holiday'; /** * @deprecated * @see id */ - var $rowid; - - var $fk_user; - var $date_create=''; - var $description; - var $date_debut=''; // Date start in PHP server TZ - var $date_fin=''; // Date end in PHP server TZ - var $date_debut_gmt=''; // Date start in GMT - var $date_fin_gmt=''; // Date end in GMT - var $halfday=''; - var $statut=''; // 1=draft, 2=validated, 3=approved - var $fk_validator; - var $date_valid=''; - var $fk_user_valid; - var $date_refuse=''; - var $fk_user_refuse; - var $date_cancel=''; - var $fk_user_cancel; - var $detail_refuse=''; - var $fk_type; - - var $holiday = array(); - var $events = array(); - var $logs = array(); - - var $optName = ''; - var $optValue = ''; - var $optRowid = ''; - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - } - - - /** - * Update balance of vacations and check table of users for holidays is complete. If not complete. - * - * @return int <0 if KO, >0 if OK - */ - function updateBalance() - { - $this->db->begin(); - - // Update sold of vocations - $result = $this->updateSoldeCP(); - - // Check nb of users into table llx_holiday_users and update with empty lines - //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser')); - - if ($result >= 0) - { - $this->db->commit(); - return 1; - } - else + var $rowid; + + var $fk_user; + var $date_create=''; + var $description; + var $date_debut=''; // Date start in PHP server TZ + var $date_fin=''; // Date end in PHP server TZ + var $date_debut_gmt=''; // Date start in GMT + var $date_fin_gmt=''; // Date end in GMT + var $halfday=''; + var $statut=''; // 1=draft, 2=validated, 3=approved + var $fk_validator; + var $date_valid=''; + var $fk_user_valid; + var $date_refuse=''; + var $fk_user_refuse; + var $date_cancel=''; + var $fk_user_cancel; + var $detail_refuse=''; + var $fk_type; + + var $holiday = array(); + var $events = array(); + var $logs = array(); + + var $optName = ''; + var $optValue = ''; + var $optRowid = ''; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + + /** + * Update balance of vacations and check table of users for holidays is complete. If not complete. + * + * @return int <0 if KO, >0 if OK + */ + function updateBalance() + { + $this->db->begin(); + + // Update sold of vocations + $result = $this->updateSoldeCP(); + + // Check nb of users into table llx_holiday_users and update with empty lines + //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser')); + + if ($result >= 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Créer un congés payés dans la base de données + * + * @param User $user User that create + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + function create($user, $notrigger=0) + { + global $conf; + $error=0; + + $now=dol_now(); + + // Check parameters + if (empty($this->fk_user) || ! is_numeric($this->fk_user) || $this->fk_user < 0) { $this->error="ErrorBadParameterFkUser"; return -1; } + if (empty($this->fk_validator) || ! is_numeric($this->fk_validator) || $this->fk_validator < 0) { $this->error="ErrorBadParameterFkValidator"; return -1; } + if (empty($this->fk_type) || ! is_numeric($this->fk_type) || $this->fk_type < 0) { $this->error="ErrorBadParameterFkType"; return -1; } + + // Insert request + $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday("; + $sql.= "fk_user,"; + $sql.= "date_create,"; + $sql.= "description,"; + $sql.= "date_debut,"; + $sql.= "date_fin,"; + $sql.= "halfday,"; + $sql.= "statut,"; + $sql.= "fk_validator,"; + $sql.= "fk_type,"; + $sql.= "fk_user_create,"; + $sql.= "entity"; + $sql.= ") VALUES ("; + $sql.= "'".$this->db->escape($this->fk_user)."',"; + $sql.= " '".$this->db->idate($now)."',"; + $sql.= " '".$this->db->escape($this->description)."',"; + $sql.= " '".$this->db->idate($this->date_debut)."',"; + $sql.= " '".$this->db->idate($this->date_fin)."',"; + $sql.= " ".$this->halfday.","; + $sql.= " '1',"; + $sql.= " '".$this->db->escape($this->fk_validator)."',"; + $sql.= " ".$this->fk_type.","; + $sql.= " ".$user->id.","; + $sql.= " ".$conf->entity; + $sql.= ")"; + + $this->db->begin(); + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + + if (! $error) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday"); + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('HOLIDAY_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return $this->id; + } + } + + + /** + * Load object in memory from database + * + * @param int $id Id object + * @return int <0 if KO, >0 if OK + */ + function fetch($id) + { + global $langs; + + $sql = "SELECT"; + $sql.= " cp.rowid,"; + $sql.= " cp.fk_user,"; + $sql.= " cp.date_create,"; + $sql.= " cp.description,"; + $sql.= " cp.date_debut,"; + $sql.= " cp.date_fin,"; + $sql.= " cp.halfday,"; + $sql.= " cp.statut,"; + $sql.= " cp.fk_validator,"; + $sql.= " cp.date_valid,"; + $sql.= " cp.fk_user_valid,"; + $sql.= " cp.date_refuse,"; + $sql.= " cp.fk_user_refuse,"; + $sql.= " cp.date_cancel,"; + $sql.= " cp.fk_user_cancel,"; + $sql.= " cp.detail_refuse,"; + $sql.= " cp.note_private,"; + $sql.= " cp.note_public,"; + $sql.= " cp.fk_user_create,"; + $sql.= " cp.fk_type,"; + $sql.= " cp.entity"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; + $sql.= " WHERE cp.rowid = ".$id; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + $this->rowid = $obj->rowid; // deprecated + $this->ref = $obj->rowid; + $this->fk_user = $obj->fk_user; + $this->date_create = $this->db->jdate($obj->date_create); + $this->description = $obj->description; + $this->date_debut = $this->db->jdate($obj->date_debut); + $this->date_fin = $this->db->jdate($obj->date_fin); + $this->date_debut_gmt = $this->db->jdate($obj->date_debut,1); + $this->date_fin_gmt = $this->db->jdate($obj->date_fin,1); + $this->halfday = $obj->halfday; + $this->statut = $obj->statut; + $this->fk_validator = $obj->fk_validator; + $this->date_valid = $this->db->jdate($obj->date_valid); + $this->fk_user_valid = $obj->fk_user_valid; + $this->date_refuse = $this->db->jdate($obj->date_refuse); + $this->fk_user_refuse = $obj->fk_user_refuse; + $this->date_cancel = $this->db->jdate($obj->date_cancel); + $this->fk_user_cancel = $obj->fk_user_cancel; + $this->detail_refuse = $obj->detail_refuse; + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->fk_user_create = $obj->fk_user_create; + $this->fk_type = $obj->fk_type; + $this->entity = $obj->entity; + } + $this->db->free($resql); + + return 1; + } + else + { + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + /** + * List holidays for a particular user + * + * @param int $user_id ID of user to list + * @param string $order Sort order + * @param string $filter SQL Filter + * @return int -1 if KO, 1 if OK, 2 if no result + */ + function fetchByUser($user_id, $order='', $filter='') + { + global $langs, $conf; + + $sql = "SELECT"; + $sql.= " cp.rowid,"; + + $sql.= " cp.fk_user,"; + $sql.= " cp.fk_type,"; + $sql.= " cp.date_create,"; + $sql.= " cp.description,"; + $sql.= " cp.date_debut,"; + $sql.= " cp.date_fin,"; + $sql.= " cp.halfday,"; + $sql.= " cp.statut,"; + $sql.= " cp.fk_validator,"; + $sql.= " cp.date_valid,"; + $sql.= " cp.fk_user_valid,"; + $sql.= " cp.date_refuse,"; + $sql.= " cp.fk_user_refuse,"; + $sql.= " cp.date_cancel,"; + $sql.= " cp.fk_user_cancel,"; + $sql.= " cp.detail_refuse,"; + + $sql.= " uu.lastname as user_lastname,"; + $sql.= " uu.firstname as user_firstname,"; + $sql.= " uu.login as user_login,"; + $sql.= " uu.statut as user_statut,"; + $sql.= " uu.photo as user_photo,"; + + $sql.= " ua.lastname as validator_lastname,"; + $sql.= " ua.firstname as validator_firstname,"; + $sql.= " ua.login as validator_login,"; + $sql.= " ua.statut as validator_statut,"; + $sql.= " ua.photo as validator_photo"; + + $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua"; + $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; + $sql.= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau + $sql.= " AND cp.fk_user = ".$user_id; + + // Filtre de séléction + if(!empty($filter)) { + $sql.= $filter; + } + + // Ordre d'affichage du résultat + if(!empty($order)) { + $sql.= $order; + } + + dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG); + $resql=$this->db->query($sql); + + // Si pas d'erreur SQL + if ($resql) { + + $i = 0; + $tab_result = $this->holiday; + $num = $this->db->num_rows($resql); + + // Si pas d'enregistrement + if(!$num) { + return 2; + } + + // Liste les enregistrements et les ajoutent au tableau + while($i < $num) { + + $obj = $this->db->fetch_object($resql); + + $tab_result[$i]['rowid'] = $obj->rowid; + $tab_result[$i]['ref'] = $obj->rowid; + $tab_result[$i]['fk_user'] = $obj->fk_user; + $tab_result[$i]['fk_type'] = $obj->fk_type; + $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create); + $tab_result[$i]['description'] = $obj->description; + $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut); + $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin); + $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut,1); + $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin,1); + $tab_result[$i]['halfday'] = $obj->halfday; + $tab_result[$i]['statut'] = $obj->statut; + $tab_result[$i]['fk_validator'] = $obj->fk_validator; + $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid); + $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid; + $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse); + $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse; + $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel); + $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel; + $tab_result[$i]['detail_refuse'] = $obj->detail_refuse; + + $tab_result[$i]['user_firstname'] = $obj->user_firstname; + $tab_result[$i]['user_lastname'] = $obj->user_lastname; + $tab_result[$i]['user_login'] = $obj->user_login; + $tab_result[$i]['user_statut'] = $obj->user_statut; + $tab_result[$i]['user_photo'] = $obj->user_photo; + + $tab_result[$i]['validator_firstname'] = $obj->validator_firstname; + $tab_result[$i]['validator_lastname'] = $obj->validator_lastname; + $tab_result[$i]['validator_login'] = $obj->validator_login; + $tab_result[$i]['validator_statut'] = $obj->validator_statut; + $tab_result[$i]['validator_photo'] = $obj->validator_photo; + + $i++; + } + + // Retourne 1 avec le tableau rempli + $this->holiday = $tab_result; + return 1; + } + else { - $this->db->rollback(); - return -1; + // Erreur SQL + $this->error="Error ".$this->db->lasterror(); + return -1; } - } - - /** - * Créer un congés payés dans la base de données - * - * @param User $user User that create - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, Id of created object if OK - */ - function create($user, $notrigger=0) - { - global $conf; - $error=0; - - $now=dol_now(); - - // Check parameters - if (empty($this->fk_user) || ! is_numeric($this->fk_user) || $this->fk_user < 0) { $this->error="ErrorBadParameterFkUser"; return -1; } - if (empty($this->fk_validator) || ! is_numeric($this->fk_validator) || $this->fk_validator < 0) { $this->error="ErrorBadParameterFkValidator"; return -1; } - if (empty($this->fk_type) || ! is_numeric($this->fk_type) || $this->fk_type < 0) { $this->error="ErrorBadParameterFkType"; return -1; } - - // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday("; - $sql.= "fk_user,"; - $sql.= "date_create,"; - $sql.= "description,"; - $sql.= "date_debut,"; - $sql.= "date_fin,"; - $sql.= "halfday,"; - $sql.= "statut,"; - $sql.= "fk_validator,"; - $sql.= "fk_type,"; - $sql.= "fk_user_create,"; - $sql.= "entity"; - $sql.= ") VALUES ("; - $sql.= "'".$this->db->escape($this->fk_user)."',"; - $sql.= " '".$this->db->idate($now)."',"; - $sql.= " '".$this->db->escape($this->description)."',"; - $sql.= " '".$this->db->idate($this->date_debut)."',"; - $sql.= " '".$this->db->idate($this->date_fin)."',"; - $sql.= " ".$this->halfday.","; - $sql.= " '1',"; - $sql.= " '".$this->db->escape($this->fk_validator)."',"; - $sql.= " ".$this->fk_type.","; - $sql.= " ".$user->id.","; - $sql.= " ".$conf->entity; - $sql.= ")"; - - $this->db->begin(); - - dol_syslog(get_class($this)."::create", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) { - $error++; $this->errors[]="Error ".$this->db->lasterror(); - } - - if (! $error) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday"); - - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('HOLIDAY_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return $this->id; - } - } - - - /** - * Load object in memory from database - * - * @param int $id Id object - * @return int <0 if KO, >0 if OK - */ - function fetch($id) - { - global $langs; - - $sql = "SELECT"; - $sql.= " cp.rowid,"; - $sql.= " cp.fk_user,"; - $sql.= " cp.date_create,"; - $sql.= " cp.description,"; - $sql.= " cp.date_debut,"; - $sql.= " cp.date_fin,"; - $sql.= " cp.halfday,"; - $sql.= " cp.statut,"; - $sql.= " cp.fk_validator,"; - $sql.= " cp.date_valid,"; - $sql.= " cp.fk_user_valid,"; - $sql.= " cp.date_refuse,"; - $sql.= " cp.fk_user_refuse,"; - $sql.= " cp.date_cancel,"; - $sql.= " cp.fk_user_cancel,"; - $sql.= " cp.detail_refuse,"; - $sql.= " cp.note_private,"; - $sql.= " cp.note_public,"; - $sql.= " cp.fk_user_create,"; - $sql.= " cp.fk_type,"; - $sql.= " cp.entity"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; - $sql.= " WHERE cp.rowid = ".$id; - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; - $this->rowid = $obj->rowid; // deprecated - $this->ref = $obj->rowid; - $this->fk_user = $obj->fk_user; - $this->date_create = $this->db->jdate($obj->date_create); - $this->description = $obj->description; - $this->date_debut = $this->db->jdate($obj->date_debut); - $this->date_fin = $this->db->jdate($obj->date_fin); - $this->date_debut_gmt = $this->db->jdate($obj->date_debut,1); - $this->date_fin_gmt = $this->db->jdate($obj->date_fin,1); - $this->halfday = $obj->halfday; - $this->statut = $obj->statut; - $this->fk_validator = $obj->fk_validator; - $this->date_valid = $this->db->jdate($obj->date_valid); - $this->fk_user_valid = $obj->fk_user_valid; - $this->date_refuse = $this->db->jdate($obj->date_refuse); - $this->fk_user_refuse = $obj->fk_user_refuse; - $this->date_cancel = $this->db->jdate($obj->date_cancel); - $this->fk_user_cancel = $obj->fk_user_cancel; - $this->detail_refuse = $obj->detail_refuse; - $this->note_private = $obj->note_private; - $this->note_public = $obj->note_public; - $this->fk_user_create = $obj->fk_user_create; - $this->fk_type = $obj->fk_type; - $this->entity = $obj->entity; - } - $this->db->free($resql); - - return 1; - } - else - { - $this->error="Error ".$this->db->lasterror(); - return -1; - } - } - - /** - * List holidays for a particular user - * - * @param int $user_id ID of user to list - * @param string $order Sort order - * @param string $filter SQL Filter - * @return int -1 if KO, 1 if OK, 2 if no result - */ - function fetchByUser($user_id, $order='', $filter='') - { - global $langs, $conf; - - $sql = "SELECT"; - $sql.= " cp.rowid,"; - - $sql.= " cp.fk_user,"; + } + + /** + * List all holidays of all users + * + * @param string $order Sort order + * @param string $filter SQL Filter + * @return int -1 if KO, 1 if OK, 2 if no result + */ + function fetchAll($order,$filter) + { + global $langs; + + $sql = "SELECT"; + $sql.= " cp.rowid,"; + + $sql.= " cp.fk_user,"; $sql.= " cp.fk_type,"; $sql.= " cp.date_create,"; - $sql.= " cp.description,"; - $sql.= " cp.date_debut,"; - $sql.= " cp.date_fin,"; - $sql.= " cp.halfday,"; - $sql.= " cp.statut,"; - $sql.= " cp.fk_validator,"; - $sql.= " cp.date_valid,"; - $sql.= " cp.fk_user_valid,"; - $sql.= " cp.date_refuse,"; - $sql.= " cp.fk_user_refuse,"; - $sql.= " cp.date_cancel,"; - $sql.= " cp.fk_user_cancel,"; - $sql.= " cp.detail_refuse,"; + $sql.= " cp.description,"; + $sql.= " cp.date_debut,"; + $sql.= " cp.date_fin,"; + $sql.= " cp.halfday,"; + $sql.= " cp.statut,"; + $sql.= " cp.fk_validator,"; + $sql.= " cp.date_valid,"; + $sql.= " cp.fk_user_valid,"; + $sql.= " cp.date_refuse,"; + $sql.= " cp.fk_user_refuse,"; + $sql.= " cp.date_cancel,"; + $sql.= " cp.fk_user_cancel,"; + $sql.= " cp.detail_refuse,"; $sql.= " uu.lastname as user_lastname,"; $sql.= " uu.firstname as user_firstname,"; @@ -314,554 +440,428 @@ class Holiday extends CommonObject $sql.= " uu.statut as user_statut,"; $sql.= " uu.photo as user_photo,"; - $sql.= " ua.lastname as validator_lastname,"; - $sql.= " ua.firstname as validator_firstname,"; - $sql.= " ua.login as validator_login,"; - $sql.= " ua.statut as validator_statut,"; - $sql.= " ua.photo as validator_photo"; + $sql.= " ua.lastname as validator_lastname,"; + $sql.= " ua.firstname as validator_firstname,"; + $sql.= " ua.login as validator_login,"; + $sql.= " ua.statut as validator_statut,"; + $sql.= " ua.photo as validator_photo"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua"; - $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua"; + $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; $sql.= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau - $sql.= " AND cp.fk_user = ".$user_id; - - // Filtre de séléction - if(!empty($filter)) { - $sql.= $filter; - } - - // Ordre d'affichage du résultat - if(!empty($order)) { - $sql.= $order; - } - - dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG); - $resql=$this->db->query($sql); - - // Si pas d'erreur SQL - if ($resql) { - - $i = 0; - $tab_result = $this->holiday; - $num = $this->db->num_rows($resql); - - // Si pas d'enregistrement - if(!$num) { - return 2; - } - - // Liste les enregistrements et les ajoutent au tableau - while($i < $num) { - - $obj = $this->db->fetch_object($resql); - - $tab_result[$i]['rowid'] = $obj->rowid; - $tab_result[$i]['ref'] = $obj->rowid; - $tab_result[$i]['fk_user'] = $obj->fk_user; - $tab_result[$i]['fk_type'] = $obj->fk_type; - $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create); - $tab_result[$i]['description'] = $obj->description; - $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut); - $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin); - $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut,1); - $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin,1); - $tab_result[$i]['halfday'] = $obj->halfday; - $tab_result[$i]['statut'] = $obj->statut; - $tab_result[$i]['fk_validator'] = $obj->fk_validator; - $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid); - $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid; - $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse); - $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse; - $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel); - $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel; - $tab_result[$i]['detail_refuse'] = $obj->detail_refuse; - - $tab_result[$i]['user_firstname'] = $obj->user_firstname; - $tab_result[$i]['user_lastname'] = $obj->user_lastname; - $tab_result[$i]['user_login'] = $obj->user_login; - $tab_result[$i]['user_statut'] = $obj->user_statut; - $tab_result[$i]['user_photo'] = $obj->user_photo; - - $tab_result[$i]['validator_firstname'] = $obj->validator_firstname; - $tab_result[$i]['validator_lastname'] = $obj->validator_lastname; - $tab_result[$i]['validator_login'] = $obj->validator_login; - $tab_result[$i]['validator_statut'] = $obj->validator_statut; - $tab_result[$i]['validator_photo'] = $obj->validator_photo; - - $i++; - } - - // Retourne 1 avec le tableau rempli - $this->holiday = $tab_result; - return 1; - } - else - { - // Erreur SQL - $this->error="Error ".$this->db->lasterror(); - return -1; - } - } - - /** - * List all holidays of all users - * - * @param string $order Sort order - * @param string $filter SQL Filter - * @return int -1 if KO, 1 if OK, 2 if no result - */ - function fetchAll($order,$filter) - { - global $langs; - - $sql = "SELECT"; - $sql.= " cp.rowid,"; - - $sql.= " cp.fk_user,"; - $sql.= " cp.fk_type,"; - $sql.= " cp.date_create,"; - $sql.= " cp.description,"; - $sql.= " cp.date_debut,"; - $sql.= " cp.date_fin,"; - $sql.= " cp.halfday,"; - $sql.= " cp.statut,"; - $sql.= " cp.fk_validator,"; - $sql.= " cp.date_valid,"; - $sql.= " cp.fk_user_valid,"; - $sql.= " cp.date_refuse,"; - $sql.= " cp.fk_user_refuse,"; - $sql.= " cp.date_cancel,"; - $sql.= " cp.fk_user_cancel,"; - $sql.= " cp.detail_refuse,"; - - $sql.= " uu.lastname as user_lastname,"; - $sql.= " uu.firstname as user_firstname,"; - $sql.= " uu.login as user_login,"; - $sql.= " uu.statut as user_statut,"; - $sql.= " uu.photo as user_photo,"; - - $sql.= " ua.lastname as validator_lastname,"; - $sql.= " ua.firstname as validator_firstname,"; - $sql.= " ua.login as validator_login,"; - $sql.= " ua.statut as validator_statut,"; - $sql.= " ua.photo as validator_photo"; - - $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua"; - $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; - $sql.= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau - - // Filtrage de séléction - if(!empty($filter)) { - $sql.= $filter; - } - - // Ordre d'affichage - if(!empty($order)) { - $sql.= $order; - } - - dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG); - $resql=$this->db->query($sql); - - // Si pas d'erreur SQL - if ($resql) { - - $i = 0; - $tab_result = $this->holiday; - $num = $this->db->num_rows($resql); - - // Si pas d'enregistrement - if(!$num) { - return 2; - } - - // On liste les résultats et on les ajoutent dans le tableau - while($i < $num) { - - $obj = $this->db->fetch_object($resql); - - $tab_result[$i]['rowid'] = $obj->rowid; - $tab_result[$i]['ref'] = $obj->rowid; - $tab_result[$i]['fk_user'] = $obj->fk_user; - $tab_result[$i]['fk_type'] = $obj->fk_type; - $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create); - $tab_result[$i]['description'] = $obj->description; - $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut); - $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin); - $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut,1); - $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin,1); - $tab_result[$i]['halfday'] = $obj->halfday; - $tab_result[$i]['statut'] = $obj->statut; - $tab_result[$i]['fk_validator'] = $obj->fk_validator; - $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid); - $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid; - $tab_result[$i]['date_refuse'] = $obj->date_refuse; - $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse; - $tab_result[$i]['date_cancel'] = $obj->date_cancel; - $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel; - $tab_result[$i]['detail_refuse'] = $obj->detail_refuse; - - $tab_result[$i]['user_firstname'] = $obj->user_firstname; - $tab_result[$i]['user_lastname'] = $obj->user_lastname; - $tab_result[$i]['user_login'] = $obj->user_login; - $tab_result[$i]['user_statut'] = $obj->user_statut; - $tab_result[$i]['user_photo'] = $obj->user_photo; - - $tab_result[$i]['validator_firstname'] = $obj->validator_firstname; - $tab_result[$i]['validator_lastname'] = $obj->validator_lastname; - $tab_result[$i]['validator_login'] = $obj->validator_login; - $tab_result[$i]['validator_statut'] = $obj->validator_statut; - $tab_result[$i]['validator_photo'] = $obj->validator_photo; - - $i++; - } - // Retourne 1 et ajoute le tableau à la variable - $this->holiday = $tab_result; - return 1; - } - else - { - // Erreur SQL - $this->error="Error ".$this->db->lasterror(); - return -1; - } - } - - /** - * Update database - * - * @param User $user User that modify - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function update($user=null, $notrigger=0) - { - global $conf, $langs; - $error=0; - - // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET"; - - $sql.= " description= '".$this->db->escape($this->description)."',"; - - if(!empty($this->date_debut)) { - $sql.= " date_debut = '".$this->db->idate($this->date_debut)."',"; - } else { - $error++; - } - if(!empty($this->date_fin)) { - $sql.= " date_fin = '".$this->db->idate($this->date_fin)."',"; - } else { - $error++; - } - $sql.= " halfday = ".$this->halfday.","; - if(!empty($this->statut) && is_numeric($this->statut)) { - $sql.= " statut = ".$this->statut.","; - } else { - $error++; - } - if(!empty($this->fk_validator)) { - $sql.= " fk_validator = '".$this->db->escape($this->fk_validator)."',"; - } else { - $error++; - } - if(!empty($this->date_valid)) { - $sql.= " date_valid = '".$this->db->idate($this->date_valid)."',"; - } else { - $sql.= " date_valid = NULL,"; - } - if(!empty($this->fk_user_valid)) { - $sql.= " fk_user_valid = '".$this->db->escape($this->fk_user_valid)."',"; - } else { - $sql.= " fk_user_valid = NULL,"; - } - if(!empty($this->date_refuse)) { - $sql.= " date_refuse = '".$this->db->idate($this->date_refuse)."',"; - } else { - $sql.= " date_refuse = NULL,"; - } - if(!empty($this->fk_user_refuse)) { - $sql.= " fk_user_refuse = '".$this->db->escape($this->fk_user_refuse)."',"; - } else { - $sql.= " fk_user_refuse = NULL,"; - } - if(!empty($this->date_cancel)) { - $sql.= " date_cancel = '".$this->db->idate($this->date_cancel)."',"; - } else { - $sql.= " date_cancel = NULL,"; - } - if(!empty($this->fk_user_cancel)) { - $sql.= " fk_user_cancel = '".$this->db->escape($this->fk_user_cancel)."',"; - } else { - $sql.= " fk_user_cancel = NULL,"; - } - if(!empty($this->detail_refuse)) { - $sql.= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'"; - } else { - $sql.= " detail_refuse = NULL"; - } - - $sql.= " WHERE rowid= ".$this->id; - - $this->db->begin(); - - dol_syslog(get_class($this)."::update", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { - $error++; $this->errors[]="Error ".$this->db->lasterror(); - } - - if (! $error) - { - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('HOLIDAY_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return 1; - } - } - - - /** - * Delete object in database - * - * @param User $user User that delete - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function delete($user, $notrigger=0) - { - global $conf, $langs; - $error=0; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday"; - $sql.= " WHERE rowid=".$this->id; - - $this->db->begin(); - - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { - $error++; $this->errors[]="Error ".$this->db->lasterror(); - } - - if (! $error) - { - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('HOLIDAY_DELETE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return 1; - } - } - - /** - * Check if a user is on holiday (partially or completely) into a period. - * This function can be used to avoid to have 2 leave requests on same period for example. - * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. - * - * @param int $fk_user Id user - * @param date $dateDebut Start date of period to check - * @param date $dateFin End date of period to check - * @param int $halfday Tag to define how start and end the period to check: - * 0:Full days, 2:Sart afternoon end monring, -1:Start afternoon, 1:End morning - * @return boolean False is on holiday at least partially into the period, True is never on holiday during chcked period. - * @see verifDateHolidayForTimestamp - */ - function verifDateHolidayCP($fk_user, $dateDebut, $dateFin, $halfday=0) - { - $this->fetchByUser($fk_user,'',''); - - foreach($this->holiday as $infos_CP) - { - if ($infos_CP['statut'] == 4) continue; // ignore not validated holidays - if ($infos_CP['statut'] == 5) continue; // ignore not validated holidays - - // TODO Also use halfday for the check - if ($halfday == 0) - { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) - { - return false; - } - } - elseif ($halfday == -1) - { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) - { - return false; - } - } - elseif ($halfday == 1) - { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) - { - return false; - } - } - elseif ($halfday == 2) - { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) - { - return false; - } - } - else - { - dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP'); - } - } - - return true; - } - - - /** - * Check a user is not on holiday for a particular timestamp - * - * @param int $fk_user Id user - * @param timestamp $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) - * @return array array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. - * @see verifDateHolidayCP - */ - function verifDateHolidayForTimestamp($fk_user, $timestamp) - { - global $langs, $conf; - - $isavailablemorning=true; - $isavailableafternoon=true; - - $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; - $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; - $sql.= " AND cp.fk_user = ".(int) $fk_user; + + // Filtrage de séléction + if(!empty($filter)) { + $sql.= $filter; + } + + // Ordre d'affichage + if(!empty($order)) { + $sql.= $order; + } + + dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG); + $resql=$this->db->query($sql); + + // Si pas d'erreur SQL + if ($resql) { + + $i = 0; + $tab_result = $this->holiday; + $num = $this->db->num_rows($resql); + + // Si pas d'enregistrement + if(!$num) { + return 2; + } + + // On liste les résultats et on les ajoutent dans le tableau + while($i < $num) { + + $obj = $this->db->fetch_object($resql); + + $tab_result[$i]['rowid'] = $obj->rowid; + $tab_result[$i]['ref'] = $obj->rowid; + $tab_result[$i]['fk_user'] = $obj->fk_user; + $tab_result[$i]['fk_type'] = $obj->fk_type; + $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create); + $tab_result[$i]['description'] = $obj->description; + $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut); + $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin); + $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut,1); + $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin,1); + $tab_result[$i]['halfday'] = $obj->halfday; + $tab_result[$i]['statut'] = $obj->statut; + $tab_result[$i]['fk_validator'] = $obj->fk_validator; + $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid); + $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid; + $tab_result[$i]['date_refuse'] = $obj->date_refuse; + $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse; + $tab_result[$i]['date_cancel'] = $obj->date_cancel; + $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel; + $tab_result[$i]['detail_refuse'] = $obj->detail_refuse; + + $tab_result[$i]['user_firstname'] = $obj->user_firstname; + $tab_result[$i]['user_lastname'] = $obj->user_lastname; + $tab_result[$i]['user_login'] = $obj->user_login; + $tab_result[$i]['user_statut'] = $obj->user_statut; + $tab_result[$i]['user_photo'] = $obj->user_photo; + + $tab_result[$i]['validator_firstname'] = $obj->validator_firstname; + $tab_result[$i]['validator_lastname'] = $obj->validator_lastname; + $tab_result[$i]['validator_login'] = $obj->validator_login; + $tab_result[$i]['validator_statut'] = $obj->validator_statut; + $tab_result[$i]['validator_photo'] = $obj->validator_photo; + + $i++; + } + // Retourne 1 et ajoute le tableau à la variable + $this->holiday = $tab_result; + return 1; + } + else + { + // Erreur SQL + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=null, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET"; + + $sql.= " description= '".$this->db->escape($this->description)."',"; + + if(!empty($this->date_debut)) { + $sql.= " date_debut = '".$this->db->idate($this->date_debut)."',"; + } else { + $error++; + } + if(!empty($this->date_fin)) { + $sql.= " date_fin = '".$this->db->idate($this->date_fin)."',"; + } else { + $error++; + } + $sql.= " halfday = ".$this->halfday.","; + if(!empty($this->statut) && is_numeric($this->statut)) { + $sql.= " statut = ".$this->statut.","; + } else { + $error++; + } + if(!empty($this->fk_validator)) { + $sql.= " fk_validator = '".$this->db->escape($this->fk_validator)."',"; + } else { + $error++; + } + if(!empty($this->date_valid)) { + $sql.= " date_valid = '".$this->db->idate($this->date_valid)."',"; + } else { + $sql.= " date_valid = NULL,"; + } + if(!empty($this->fk_user_valid)) { + $sql.= " fk_user_valid = '".$this->db->escape($this->fk_user_valid)."',"; + } else { + $sql.= " fk_user_valid = NULL,"; + } + if(!empty($this->date_refuse)) { + $sql.= " date_refuse = '".$this->db->idate($this->date_refuse)."',"; + } else { + $sql.= " date_refuse = NULL,"; + } + if(!empty($this->fk_user_refuse)) { + $sql.= " fk_user_refuse = '".$this->db->escape($this->fk_user_refuse)."',"; + } else { + $sql.= " fk_user_refuse = NULL,"; + } + if(!empty($this->date_cancel)) { + $sql.= " date_cancel = '".$this->db->idate($this->date_cancel)."',"; + } else { + $sql.= " date_cancel = NULL,"; + } + if(!empty($this->fk_user_cancel)) { + $sql.= " fk_user_cancel = '".$this->db->escape($this->fk_user_cancel)."',"; + } else { + $sql.= " fk_user_cancel = NULL,"; + } + if(!empty($this->detail_refuse)) { + $sql.= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'"; + } else { + $sql.= " detail_refuse = NULL"; + } + + $sql.= " WHERE rowid= ".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('HOLIDAY_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Delete object in database + * + * @param User $user User that delete + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function delete($user, $notrigger=0) + { + global $conf, $langs; + $error=0; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday"; + $sql.= " WHERE rowid=".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('HOLIDAY_DELETE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + /** + * Check if a user is on holiday (partially or completely) into a period. + * This function can be used to avoid to have 2 leave requests on same period for example. + * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. + * + * @param int $fk_user Id user + * @param date $dateDebut Start date of period to check + * @param date $dateFin End date of period to check + * @param int $halfday Tag to define how start and end the period to check: + * 0:Full days, 2:Sart afternoon end monring, -1:Start afternoon, 1:End morning + * @return boolean False is on holiday at least partially into the period, True is never on holiday during chcked period. + * @see verifDateHolidayForTimestamp + */ + function verifDateHolidayCP($fk_user, $dateDebut, $dateFin, $halfday=0) + { + $this->fetchByUser($fk_user,'',''); + + foreach($this->holiday as $infos_CP) + { + if ($infos_CP['statut'] == 4) continue; // ignore not validated holidays + if ($infos_CP['statut'] == 5) continue; // ignore not validated holidays + + // TODO Also use halfday for the check + if ($halfday == 0) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == -1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 2) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + else + { + dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP'); + } + } + + return true; + } + + + /** + * Check a user is not on holiday for a particular timestamp + * + * @param int $fk_user Id user + * @param timestamp $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) + * @return array array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. + * @see verifDateHolidayCP + */ + function verifDateHolidayForTimestamp($fk_user, $timestamp) + { + global $langs, $conf; + + $isavailablemorning=true; + $isavailableafternoon=true; + + $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; + $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; + $sql.= " AND cp.fk_user = ".(int) $fk_user; $sql.= " AND date_debut <= '".$this->db->idate($timestamp)."' AND date_fin >= '".$this->db->idate($timestamp)."'"; - $resql = $this->db->query($sql); - if ($resql) - { - $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon - if ($num_rows > 0) - { - $arrayofrecord=array(); - $i=0; - while ($i < $num_rows) - { - $obj = $this->db->fetch_object($resql); - - // Note: $obj->halfday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning - $arrayofrecord[$obj->rowid]=array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday); - $i++; - } - - // We found a record, user is on holiday by default, so is not available is true. - $isavailablemorning = true; - foreach($arrayofrecord as $record) - { + $resql = $this->db->query($sql); + if ($resql) + { + $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon + if ($num_rows > 0) + { + $arrayofrecord=array(); + $i=0; + while ($i < $num_rows) + { + $obj = $this->db->fetch_object($resql); + + // Note: $obj->halfday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning + $arrayofrecord[$obj->rowid]=array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday); + $i++; + } + + // We found a record, user is on holiday by default, so is not available is true. + $isavailablemorning = true; + foreach($arrayofrecord as $record) + { if ($timestamp == $record['date_start'] && $record['halfday'] == 2) continue; if ($timestamp == $record['date_start'] && $record['halfday'] == -1) continue; - $isavailablemorning = false; - break; - } - $isavailableafternoon = true; - foreach($arrayofrecord as $record) - { + $isavailablemorning = false; + break; + } + $isavailableafternoon = true; + foreach($arrayofrecord as $record) + { if ($timestamp == $record['date_end'] && $record['halfday'] == 2) continue; if ($timestamp == $record['date_end'] && $record['halfday'] == 1) continue; - $isavailableafternoon = false; - break; - } - } - } - else dol_print_error($this->db); + $isavailableafternoon = false; + break; + } + } + } + else dol_print_error($this->db); return array('morning'=>$isavailablemorning, 'afternoon'=>$isavailableafternoon); - } - - - /** - * Return clicable name (with picto eventually) - * - * @param int $withpicto 0=_No picto, 1=Includes the picto in the linkn, 2=Picto only - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string String with URL - */ - function getNomUrl($withpicto=0, $save_lastsearch_value=-1) - { - global $langs; - - $result=''; - $picto='holiday'; - $label=$langs->trans("Show").': '.$this->ref; - - $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id; - - //if ($option != 'nolink') - //{ - // Add param to save lastsearch_values or not - $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; - if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; - //} - - $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; - $linkend='</a>'; - - if ($withpicto) $result.=($linkstart.img_object($label, $picto, 'class="classfortooltip"').$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$linkstart.$this->ref.$linkend; - return $result; - } - - - /** - * Returns the label status - * - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto - * @return string Label - */ - function getLibStatut($mode=0) - { - return $this->LibStatut($this->statut, $mode, $this->date_debut); - } + } + + + /** + * Return clicable name (with picto eventually) + * + * @param int $withpicto 0=_No picto, 1=Includes the picto in the linkn, 2=Picto only + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + function getNomUrl($withpicto=0, $save_lastsearch_value=-1) + { + global $langs; + + $result=''; + $picto='holiday'; + $label=$langs->trans("Show").': '.$this->ref; + + $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id; + + //if ($option != 'nolink') + //{ + // Add param to save lastsearch_values or not + $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; + if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; + //} + + $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + $linkend='</a>'; + + if ($withpicto) $result.=($linkstart.img_object($label, $picto, 'class="classfortooltip"').$linkend); + if ($withpicto && $withpicto != 2) $result.=' '; + if ($withpicto != 2) $result.=$linkstart.$this->ref.$linkend; + return $result; + } + + + /** + * Returns the label status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut, $mode, $this->date_debut); + } /** * Returns the label of a statut @@ -877,11 +877,11 @@ class Holiday extends CommonObject if ($mode == 0) { - if ($statut == 1) return $langs->trans('DraftCP'); - if ($statut == 2) return $langs->trans('ToReviewCP'); - if ($statut == 3) return $langs->trans('ApprovedCP'); - if ($statut == 4) return $langs->trans('CancelCP'); - if ($statut == 5) return $langs->trans('RefuseCP'); + if ($statut == 1) return $langs->trans('DraftCP'); + if ($statut == 2) return $langs->trans('ToReviewCP'); + if ($statut == 3) return $langs->trans('ApprovedCP'); + if ($statut == 4) return $langs->trans('CancelCP'); + if ($statut == 5) return $langs->trans('RefuseCP'); } if ($mode == 2) { @@ -915,865 +915,865 @@ class Holiday extends CommonObject } if ($mode == 6) { - $pictoapproved='statut6'; - if (! empty($startdate) && $startdate > dol_now()) $pictoapproved='statut4'; - if ($statut == 1) return $langs->trans('DraftCP').' '.img_picto($langs->trans('DraftCP'),'statut0'); // Draft - if ($statut == 2) return $langs->trans('ToReviewCP').' '.img_picto($langs->trans('ToReviewCP'),'statut1'); // Waiting approval - if ($statut == 3) return $langs->trans('ApprovedCP').' '.img_picto($langs->trans('ApprovedCP'),$pictoapproved); - if ($statut == 4) return $langs->trans('CancelCP').' '.img_picto($langs->trans('CancelCP'),'statut5'); - if ($statut == 5) return $langs->trans('RefuseCP').' '.img_picto($langs->trans('RefuseCP'),'statut5'); + $pictoapproved='statut6'; + if (! empty($startdate) && $startdate > dol_now()) $pictoapproved='statut4'; + if ($statut == 1) return $langs->trans('DraftCP').' '.img_picto($langs->trans('DraftCP'),'statut0'); // Draft + if ($statut == 2) return $langs->trans('ToReviewCP').' '.img_picto($langs->trans('ToReviewCP'),'statut1'); // Waiting approval + if ($statut == 3) return $langs->trans('ApprovedCP').' '.img_picto($langs->trans('ApprovedCP'),$pictoapproved); + if ($statut == 4) return $langs->trans('CancelCP').' '.img_picto($langs->trans('CancelCP'),'statut5'); + if ($statut == 5) return $langs->trans('RefuseCP').' '.img_picto($langs->trans('RefuseCP'),'statut5'); } return $statut; - } - - - /** - * Affiche un select HTML des statuts de congés payés - * - * @param int $selected int du statut séléctionné par défaut - * @return string affiche le select des statuts - */ - function selectStatutCP($selected='') { - - global $langs; - - // Liste des statuts - $name = array('DraftCP','ToReviewCP','ApprovedCP','CancelCP','RefuseCP'); - $nb = count($name)+1; - - // Select HTML - $statut = '<select name="select_statut" class="flat">'."\n"; - $statut.= '<option value="-1"> </option>'."\n"; - - // Boucle des statuts - for($i=1; $i < $nb; $i++) { - if($i==$selected) { - $statut.= '<option value="'.$i.'" selected>'.$langs->trans($name[$i-1]).'</option>'."\n"; - } - else { - $statut.= '<option value="'.$i.'">'.$langs->trans($name[$i-1]).'</option>'."\n"; - } - } - - $statut.= '</select>'."\n"; - print $statut; - - } - - /** - * Met à jour une option du module Holiday Payés - * - * @param string $name name du paramètre de configuration - * @param string $value vrai si mise à jour OK sinon faux - * @return boolean ok or ko - */ - function updateConfCP($name,$value) { - - $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET"; - $sql.= " value = '".$value."'"; - $sql.= " WHERE name = '".$name."'"; - - dol_syslog(get_class($this).'::updateConfCP name='.$name.'', LOG_DEBUG); - $result = $this->db->query($sql); - if($result) { - return true; - } - - return false; - } - - /** - * Return value of a conf parameterfor leave module - * TODO Move this into llx_const table - * - * @param string $name Name of parameter - * @param string $createifnotfound 'stringvalue'=Create entry with string value if not found. For example 'YYYYMMDDHHMMSS'. - * @return string Value of parameter. Example: 'YYYYMMDDHHMMSS' or < 0 if error - */ - function getConfCP($name, $createifnotfound='') - { - $sql = "SELECT value"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday_config"; - $sql.= " WHERE name = '".$this->db->escape($name)."'"; - - dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG); - $result = $this->db->query($sql); - - if($result) { - - $obj = $this->db->fetch_object($result); - // Return value - if (empty($obj)) - { - if ($createifnotfound) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)"; - $sql.= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')"; - $result = $this->db->query($sql); - if ($result) - { - return $createifnotfound; - } - else - { - $this->error=$this->db->lasterror(); - return -2; - } - } - else - { - return ''; - } - } - else - { - return $obj->value; - } - } else { - - // Erreur SQL - $this->error=$this->db->lasterror(); - return -1; - } - } - - /** - * Met à jour le timestamp de la dernière mise à jour du solde des CP - * - * @param int $userID Id of user - * @param int $nbHoliday Nb of days - * @param int $fk_type Type of vacation - * @return int 0=Nothing done, 1=OK, -1=KO - */ - function updateSoldeCP($userID='',$nbHoliday='', $fk_type='') - { - global $user, $langs; - - $error = 0; - - if (empty($userID) && empty($nbHoliday) && empty($fk_type)) - { - $langs->load("holiday"); - - // Si mise à jour pour tout le monde en début de mois + } + + + /** + * Affiche un select HTML des statuts de congés payés + * + * @param int $selected int du statut séléctionné par défaut + * @return string affiche le select des statuts + */ + function selectStatutCP($selected='') { + + global $langs; + + // Liste des statuts + $name = array('DraftCP','ToReviewCP','ApprovedCP','CancelCP','RefuseCP'); + $nb = count($name)+1; + + // Select HTML + $statut = '<select name="select_statut" class="flat">'."\n"; + $statut.= '<option value="-1"> </option>'."\n"; + + // Boucle des statuts + for($i=1; $i < $nb; $i++) { + if($i==$selected) { + $statut.= '<option value="'.$i.'" selected>'.$langs->trans($name[$i-1]).'</option>'."\n"; + } + else { + $statut.= '<option value="'.$i.'">'.$langs->trans($name[$i-1]).'</option>'."\n"; + } + } + + $statut.= '</select>'."\n"; + print $statut; + + } + + /** + * Met à jour une option du module Holiday Payés + * + * @param string $name name du paramètre de configuration + * @param string $value vrai si mise à jour OK sinon faux + * @return boolean ok or ko + */ + function updateConfCP($name,$value) { + + $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET"; + $sql.= " value = '".$value."'"; + $sql.= " WHERE name = '".$name."'"; + + dol_syslog(get_class($this).'::updateConfCP name='.$name.'', LOG_DEBUG); + $result = $this->db->query($sql); + if($result) { + return true; + } + + return false; + } + + /** + * Return value of a conf parameterfor leave module + * TODO Move this into llx_const table + * + * @param string $name Name of parameter + * @param string $createifnotfound 'stringvalue'=Create entry with string value if not found. For example 'YYYYMMDDHHMMSS'. + * @return string Value of parameter. Example: 'YYYYMMDDHHMMSS' or < 0 if error + */ + function getConfCP($name, $createifnotfound='') + { + $sql = "SELECT value"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday_config"; + $sql.= " WHERE name = '".$this->db->escape($name)."'"; + + dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG); + $result = $this->db->query($sql); + + if($result) { + + $obj = $this->db->fetch_object($result); + // Return value + if (empty($obj)) + { + if ($createifnotfound) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)"; + $sql.= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')"; + $result = $this->db->query($sql); + if ($result) + { + return $createifnotfound; + } + else + { + $this->error=$this->db->lasterror(); + return -2; + } + } + else + { + return ''; + } + } + else + { + return $obj->value; + } + } else { + + // Erreur SQL + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Met à jour le timestamp de la dernière mise à jour du solde des CP + * + * @param int $userID Id of user + * @param int $nbHoliday Nb of days + * @param int $fk_type Type of vacation + * @return int 0=Nothing done, 1=OK, -1=KO + */ + function updateSoldeCP($userID='',$nbHoliday='', $fk_type='') + { + global $user, $langs; + + $error = 0; + + if (empty($userID) && empty($nbHoliday) && empty($fk_type)) + { + $langs->load("holiday"); + + // Si mise à jour pour tout le monde en début de mois $now=dol_now(); - $month = date('m',$now); - $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S'); + $month = date('m',$now); + $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S'); - // Get month of last update - $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate); - $monthLastUpdate = $lastUpdate[4].$lastUpdate[5]; + // Get month of last update + $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate); + $monthLastUpdate = $lastUpdate[4].$lastUpdate[5]; //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit; - // Si la date du mois n'est pas la même que celle sauvegardée, on met à jour le timestamp - if ($month != $monthLastUpdate) - { - $this->db->begin(); + // Si la date du mois n'est pas la même que celle sauvegardée, on met à jour le timestamp + if ($month != $monthLastUpdate) + { + $this->db->begin(); - $users = $this->fetchUsers(false,false); - $nbUser = count($users); + $users = $this->fetchUsers(false,false); + $nbUser = count($users); - $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET"; - $sql.= " value = '".$this->db->escape($newdateforlastupdate)."'"; - $sql.= " WHERE name = 'lastUpdate'"; - $result = $this->db->query($sql); + $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET"; + $sql.= " value = '".$this->db->escape($newdateforlastupdate)."'"; + $sql.= " WHERE name = 'lastUpdate'"; + $result = $this->db->query($sql); $typeleaves=$this->getTypes(1,1); - foreach($typeleaves as $key => $val) - { - // On ajoute x jours à chaque utilisateurs - $nb_holiday = $val['newByMonth']; + foreach($typeleaves as $key => $val) + { + // On ajoute x jours à chaque utilisateurs + $nb_holiday = $val['newByMonth']; if (empty($nb_holiday)) $nb_holiday=0; if ($nb_holiday > 0) { dol_syslog("We update leavefor everybody for type ".$key, LOG_DEBUG); - $i = 0; - while ($i < $nbUser) - { - $now_holiday = $this->getCPforUser($users[$i]['rowid'], $val['rowid']); - $new_solde = $now_holiday + $this->getConfCP('nbHolidayEveryMonth'); + $i = 0; + while ($i < $nbUser) + { + $now_holiday = $this->getCPforUser($users[$i]['rowid'], $val['rowid']); + $new_solde = $now_holiday + $this->getConfCP('nbHolidayEveryMonth'); - // We add a log for each user - $this->addLogCP($user->id, $users[$i]['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $new_solde, $val['rowid']); + // We add a log for each user + $this->addLogCP($user->id, $users[$i]['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $new_solde, $val['rowid']); - $i++; - } + $i++; + } - // Now we update counter for all users at once - $sql2 = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET"; - $sql2.= " nb_holiday = nb_holiday + ".$nb_holiday; + // Now we update counter for all users at once + $sql2 = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET"; + $sql2.= " nb_holiday = nb_holiday + ".$nb_holiday; $sql2.= " WHERE fk_type = ".$val['rowid']; - $result= $this->db->query($sql2); + $result= $this->db->query($sql2); - if (! $result) - { - dol_print_error($this->db); - break; - } + if (! $result) + { + dol_print_error($this->db); + break; + } } else dol_syslog("No change for leave of type ".$key, LOG_DEBUG); - } + } if ($result) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - - return 0; - } - else + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + return 0; + } + else { - // Mise à jour pour un utilisateur - $nbHoliday = price2num($nbHoliday,5); - - $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users"; - $sql.= " WHERE fk_user = '".$userID."' AND fk_type = ".$fk_type; - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - - if ($num > 0) - { - // Update for user - $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET"; - $sql.= " nb_holiday = ".$nbHoliday; - $sql.= " WHERE fk_user = '".$userID."' AND fk_type = ".$fk_type; - $result = $this->db->query($sql); - if (! $result) - { - $error++; - $this->errors[]=$this->db->lasterror(); - } - } - else - { - // Insert for user - $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES ("; - $sql.= $nbHoliday; - $sql.= ", '".$userID."', ".$fk_type.")"; - $result = $this->db->query($sql); - if (! $result) - { - $error++; - $this->errors[]=$this->db->lasterror(); - } - } - } - else + // Mise à jour pour un utilisateur + $nbHoliday = price2num($nbHoliday,5); + + $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users"; + $sql.= " WHERE fk_user = '".$userID."' AND fk_type = ".$fk_type; + $resql = $this->db->query($sql); + if ($resql) { - $this->errors[]=$this->db->lasterror(); - $error++; + $num = $this->db->num_rows($resql); + + if ($num > 0) + { + // Update for user + $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET"; + $sql.= " nb_holiday = ".$nbHoliday; + $sql.= " WHERE fk_user = '".$userID."' AND fk_type = ".$fk_type; + $result = $this->db->query($sql); + if (! $result) + { + $error++; + $this->errors[]=$this->db->lasterror(); + } + } + else + { + // Insert for user + $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES ("; + $sql.= $nbHoliday; + $sql.= ", '".$userID."', ".$fk_type.")"; + $result = $this->db->query($sql); + if (! $result) + { + $error++; + $this->errors[]=$this->db->lasterror(); + } + } + } + else + { + $this->errors[]=$this->db->lasterror(); + $error++; + } + + if (! $error) + { + return 1; + } + else + { + return -1; + } + } + + } + + /** + * Retourne un checked si vrai + * + * @param string $name name du paramètre de configuration + * @return string retourne checked si > 0 + */ + function getCheckOption($name) { + + $sql = "SELECT value"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday_config"; + $sql.= " WHERE name = '".$name."'"; + + $result = $this->db->query($sql); + + if($result) { + $obj = $this->db->fetch_object($result); + + // Si la valeur est 1 on retourne checked + if($obj->value) { + return 'checked'; } + } + } - if (! $error) - { - return 1; - } - else - { - return -1; - } - } - - } - - /** - * Retourne un checked si vrai - * - * @param string $name name du paramètre de configuration - * @return string retourne checked si > 0 - */ - function getCheckOption($name) { - - $sql = "SELECT value"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday_config"; - $sql.= " WHERE name = '".$name."'"; - - $result = $this->db->query($sql); - - if($result) { - $obj = $this->db->fetch_object($result); - - // Si la valeur est 1 on retourne checked - if($obj->value) { - return 'checked'; - } - } - } - - - /** - * Créer les entrées pour chaque utilisateur au moment de la configuration - * - * @param boolean $single Single - * @param int $userid Id user - * @return void - */ - function createCPusers($single=false,$userid='') - { - // Si c'est l'ensemble des utilisateurs à ajouter - if (! $single) - { - dol_syslog(get_class($this).'::createCPusers'); - $arrayofusers = $this->fetchUsers(false,true); - - foreach($arrayofusers as $users) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users"; - $sql.= " (fk_user, nb_holiday)"; - $sql.= " VALUES ('".$users['rowid']."','0')"; - - $resql=$this->db->query($sql); - if (! $resql) dol_print_error($this->db); - } - } - else + + /** + * Créer les entrées pour chaque utilisateur au moment de la configuration + * + * @param boolean $single Single + * @param int $userid Id user + * @return void + */ + function createCPusers($single=false,$userid='') + { + // Si c'est l'ensemble des utilisateurs à ajouter + if (! $single) { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users"; - $sql.= " (fk_user, nb_holiday)"; - $sql.= " VALUES ('".$userid."','0')"; - - $resql=$this->db->query($sql); - if (! $resql) dol_print_error($this->db); - } - } - - /** - * Supprime un utilisateur du module Congés Payés - * - * @param int $user_id ID de l'utilisateur à supprimer - * @return boolean Vrai si pas d'erreur, faut si Erreur - */ - function deleteCPuser($user_id) { - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday_users"; - $sql.= " WHERE fk_user = '".$user_id."'"; - - $this->db->query($sql); - - } - - - /** - * Retourne le solde de congés payés pour un utilisateur - * - * @param int $user_id ID de l'utilisateur - * @param int $fk_type Filter on type - * @return float Retourne le solde de congés payés de l'utilisateur - */ - function getCPforUser($user_id, $fk_type=0) - { - $sql = "SELECT nb_holiday"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday_users"; - $sql.= " WHERE fk_user = '".$user_id."'"; - if ($fk_type > 0) $sql.=" AND fk_type = ".$fk_type; - - dol_syslog(get_class($this).'::getCPforUser', LOG_DEBUG); - $result = $this->db->query($sql); - if($result) - { - $obj = $this->db->fetch_object($result); - //return number_format($obj->nb_holiday,2); - if ($obj) return $obj->nb_holiday; - else return null; - } - else + dol_syslog(get_class($this).'::createCPusers'); + $arrayofusers = $this->fetchUsers(false,true); + + foreach($arrayofusers as $users) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users"; + $sql.= " (fk_user, nb_holiday)"; + $sql.= " VALUES ('".$users['rowid']."','0')"; + + $resql=$this->db->query($sql); + if (! $resql) dol_print_error($this->db); + } + } + else { - return null; - } - } - - /** - * Get list of Users or list of vacation balance. - * - * @param boolean $stringlist If true return a string list of id. If false, return an array with detail. - * @param boolean $type If true, read Dolibarr user list, if false, return vacation balance list. - * @param string $filters Filters - * @return array|string|int Return an array - */ - function fetchUsers($stringlist=true, $type=true, $filters='') - { - global $conf; - - dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG); - - if ($stringlist) - { - if ($type) - { - // Si utilisateur de Dolibarr - - $sql = "SELECT u.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; - - if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) - { - $sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; - $sql.= " WHERE (ug.fk_user = u.rowid"; - $sql.= " AND ug.entity = ".$conf->entity.")"; - $sql.= " OR u.admin = 1"; - } - else - { - $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; - } - $sql.= " AND u.statut > 0"; - if ($filters) $sql.=$filters; - - $resql=$this->db->query($sql); - - // Si pas d'erreur SQL - if ($resql) { - - $i = 0; - $num = $this->db->num_rows($resql); - $stringlist = ''; - - // Boucles du listage des utilisateurs - while($i < $num) - { - $obj = $this->db->fetch_object($resql); - - if ($i == 0) { - $stringlist.= $obj->rowid; - } else { - $stringlist.= ', '.$obj->rowid; - } - - $i++; - } - // Retoune le tableau des utilisateurs - return $stringlist; - } - else - { - // Erreur SQL - $this->error="Error ".$this->db->lasterror(); - return -1; - } - - } - else - { - // We want only list of vacation balance for user ids - $sql = "SELECT DISTINCT cpu.fk_user"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u"; - $sql.= " WHERE cpu.fk_user = u.user"; - if ($filters) $sql.=$filters; - - $resql=$this->db->query($sql); - - // Si pas d'erreur SQL - if ($resql) { - - $i = 0; - $num = $this->db->num_rows($resql); - $stringlist = ''; - - // Boucles du listage des utilisateurs - while($i < $num) - { - $obj = $this->db->fetch_object($resql); - - if($i == 0) { - $stringlist.= $obj->fk_user; - } else { - $stringlist.= ', '.$obj->fk_user; - } - - $i++; - } - // Retoune le tableau des utilisateurs - return $stringlist; - } - else - { - // Erreur SQL - $this->error="Error ".$this->db->lasterror(); - return -1; - } - } - - } - else - { // Si faux donc return array - - // List for Dolibarr users - if ($type) - { - $sql = "SELECT u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user"; - $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; - - if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) - { - $sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; - $sql.= " WHERE (ug.fk_user = u.rowid"; - $sql.= " AND ug.entity = ".$conf->entity.")"; - $sql.= " OR u.admin = 1"; - } - else - $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; - - $sql.= " AND u.statut > 0"; - if ($filters) $sql.=$filters; - - $resql=$this->db->query($sql); - - // Si pas d'erreur SQL - if ($resql) - { - $i = 0; - $tab_result = $this->holiday; - $num = $this->db->num_rows($resql); - - // Boucles du listage des utilisateurs - while($i < $num) { - - $obj = $this->db->fetch_object($resql); - - $tab_result[$i]['rowid'] = $obj->rowid; - $tab_result[$i]['name'] = $obj->lastname; // deprecated - $tab_result[$i]['lastname'] = $obj->lastname; - $tab_result[$i]['firstname'] = $obj->firstname; - $tab_result[$i]['gender'] = $obj->gender; - $tab_result[$i]['status'] = $obj->statut; - $tab_result[$i]['employee'] = $obj->employee; - $tab_result[$i]['photo'] = $obj->photo; - $tab_result[$i]['fk_user'] = $obj->fk_user; - //$tab_result[$i]['type'] = $obj->type; - //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday; - - $i++; - } - // Retoune le tableau des utilisateurs - return $tab_result; - } - else + $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users"; + $sql.= " (fk_user, nb_holiday)"; + $sql.= " VALUES ('".$userid."','0')"; + + $resql=$this->db->query($sql); + if (! $resql) dol_print_error($this->db); + } + } + + /** + * Supprime un utilisateur du module Congés Payés + * + * @param int $user_id ID de l'utilisateur à supprimer + * @return boolean Vrai si pas d'erreur, faut si Erreur + */ + function deleteCPuser($user_id) { + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday_users"; + $sql.= " WHERE fk_user = '".$user_id."'"; + + $this->db->query($sql); + + } + + + /** + * Retourne le solde de congés payés pour un utilisateur + * + * @param int $user_id ID de l'utilisateur + * @param int $fk_type Filter on type + * @return float Retourne le solde de congés payés de l'utilisateur + */ + function getCPforUser($user_id, $fk_type=0) + { + $sql = "SELECT nb_holiday"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday_users"; + $sql.= " WHERE fk_user = '".$user_id."'"; + if ($fk_type > 0) $sql.=" AND fk_type = ".$fk_type; + + dol_syslog(get_class($this).'::getCPforUser', LOG_DEBUG); + $result = $this->db->query($sql); + if($result) + { + $obj = $this->db->fetch_object($result); + //return number_format($obj->nb_holiday,2); + if ($obj) return $obj->nb_holiday; + else return null; + } + else + { + return null; + } + } + + /** + * Get list of Users or list of vacation balance. + * + * @param boolean $stringlist If true return a string list of id. If false, return an array with detail. + * @param boolean $type If true, read Dolibarr user list, if false, return vacation balance list. + * @param string $filters Filters + * @return array|string|int Return an array + */ + function fetchUsers($stringlist=true, $type=true, $filters='') + { + global $conf; + + dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG); + + if ($stringlist) + { + if ($type) + { + // Si utilisateur de Dolibarr + + $sql = "SELECT u.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; + + if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + $sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql.= " WHERE (ug.fk_user = u.rowid"; + $sql.= " AND ug.entity = ".$conf->entity.")"; + $sql.= " OR u.admin = 1"; + } + else + { + $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; + } + $sql.= " AND u.statut > 0"; + if ($filters) $sql.=$filters; + + $resql=$this->db->query($sql); + + // Si pas d'erreur SQL + if ($resql) { + + $i = 0; + $num = $this->db->num_rows($resql); + $stringlist = ''; + + // Boucles du listage des utilisateurs + while($i < $num) + { + $obj = $this->db->fetch_object($resql); + + if ($i == 0) { + $stringlist.= $obj->rowid; + } else { + $stringlist.= ', '.$obj->rowid; + } + + $i++; + } + // Retoune le tableau des utilisateurs + return $stringlist; + } + else { - // Erreur SQL - $this->errors[]="Error ".$this->db->lasterror(); - return -1; - } - } - else - { + // Erreur SQL + $this->error="Error ".$this->db->lasterror(); + return -1; + } + + } + else + { + // We want only list of vacation balance for user ids + $sql = "SELECT DISTINCT cpu.fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u"; + $sql.= " WHERE cpu.fk_user = u.user"; + if ($filters) $sql.=$filters; + + $resql=$this->db->query($sql); + + // Si pas d'erreur SQL + if ($resql) { + + $i = 0; + $num = $this->db->num_rows($resql); + $stringlist = ''; + + // Boucles du listage des utilisateurs + while($i < $num) + { + $obj = $this->db->fetch_object($resql); + + if($i == 0) { + $stringlist.= $obj->fk_user; + } else { + $stringlist.= ', '.$obj->fk_user; + } + + $i++; + } + // Retoune le tableau des utilisateurs + return $stringlist; + } + else + { + // Erreur SQL + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + } + else + { // Si faux donc return array + + // List for Dolibarr users + if ($type) + { + $sql = "SELECT u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; + + if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + $sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql.= " WHERE (ug.fk_user = u.rowid"; + $sql.= " AND ug.entity = ".$conf->entity.")"; + $sql.= " OR u.admin = 1"; + } + else + $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; + + $sql.= " AND u.statut > 0"; + if ($filters) $sql.=$filters; + + $resql=$this->db->query($sql); + + // Si pas d'erreur SQL + if ($resql) + { + $i = 0; + $tab_result = $this->holiday; + $num = $this->db->num_rows($resql); + + // Boucles du listage des utilisateurs + while($i < $num) { + + $obj = $this->db->fetch_object($resql); + + $tab_result[$i]['rowid'] = $obj->rowid; + $tab_result[$i]['name'] = $obj->lastname; // deprecated + $tab_result[$i]['lastname'] = $obj->lastname; + $tab_result[$i]['firstname'] = $obj->firstname; + $tab_result[$i]['gender'] = $obj->gender; + $tab_result[$i]['status'] = $obj->statut; + $tab_result[$i]['employee'] = $obj->employee; + $tab_result[$i]['photo'] = $obj->photo; + $tab_result[$i]['fk_user'] = $obj->fk_user; + //$tab_result[$i]['type'] = $obj->type; + //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday; + + $i++; + } + // Retoune le tableau des utilisateurs + return $tab_result; + } + else + { + // Erreur SQL + $this->errors[]="Error ".$this->db->lasterror(); + return -1; + } + } + else + { // List of vacation balance users - $sql = "SELECT cpu.fk_user, cpu.fk_type, cpu.nb_holiday, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u"; - $sql.= " WHERE cpu.fk_user = u.rowid"; - if ($filters) $sql.=$filters; - - $resql=$this->db->query($sql); - - // Si pas d'erreur SQL - if ($resql) - { - $i = 0; - $tab_result = $this->holiday; - $num = $this->db->num_rows($resql); - - // Boucles du listage des utilisateurs - while($i < $num) - { - $obj = $this->db->fetch_object($resql); - - $tab_result[$i]['rowid'] = $obj->fk_user; - $tab_result[$i]['name'] = $obj->lastname; // deprecated - $tab_result[$i]['lastname'] = $obj->lastname; - $tab_result[$i]['firstname'] = $obj->firstname; - $tab_result[$i]['gender'] = $obj->gender; - $tab_result[$i]['status'] = $obj->statut; - $tab_result[$i]['employee'] = $obj->employee; - $tab_result[$i]['photo'] = $obj->photo; - $tab_result[$i]['fk_user'] = $obj->fk_user; - - $tab_result[$i]['type'] = $obj->type; - $tab_result[$i]['nb_holiday'] = $obj->nb_holiday; - - $i++; - } - // Retoune le tableau des utilisateurs - return $tab_result; - } - else + $sql = "SELECT cpu.fk_user, cpu.fk_type, cpu.nb_holiday, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u"; + $sql.= " WHERE cpu.fk_user = u.rowid"; + if ($filters) $sql.=$filters; + + $resql=$this->db->query($sql); + + // Si pas d'erreur SQL + if ($resql) { - // Erreur SQL - $this->error="Error ".$this->db->lasterror(); - return -1; - } - } - } - } - - /** - * Compte le nombre d'utilisateur actifs dans Dolibarr - * - * @return int retourne le nombre d'utilisateur - */ - function countActiveUsers() - { - $sql = "SELECT count(u.rowid) as compteur"; - $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; + $i = 0; + $tab_result = $this->holiday; + $num = $this->db->num_rows($resql); + + // Boucles du listage des utilisateurs + while($i < $num) + { + $obj = $this->db->fetch_object($resql); + + $tab_result[$i]['rowid'] = $obj->fk_user; + $tab_result[$i]['name'] = $obj->lastname; // deprecated + $tab_result[$i]['lastname'] = $obj->lastname; + $tab_result[$i]['firstname'] = $obj->firstname; + $tab_result[$i]['gender'] = $obj->gender; + $tab_result[$i]['status'] = $obj->statut; + $tab_result[$i]['employee'] = $obj->employee; + $tab_result[$i]['photo'] = $obj->photo; + $tab_result[$i]['fk_user'] = $obj->fk_user; + + $tab_result[$i]['type'] = $obj->type; + $tab_result[$i]['nb_holiday'] = $obj->nb_holiday; + + $i++; + } + // Retoune le tableau des utilisateurs + return $tab_result; + } + else + { + // Erreur SQL + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + } + } + + /** + * Compte le nombre d'utilisateur actifs dans Dolibarr + * + * @return int retourne le nombre d'utilisateur + */ + function countActiveUsers() + { + $sql = "SELECT count(u.rowid) as compteur"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; $sql.= " WHERE u.statut > 0"; - $result = $this->db->query($sql); - $objet = $this->db->fetch_object($result); + $result = $this->db->query($sql); + $objet = $this->db->fetch_object($result); - return $objet->compteur; - } - /** - * Compte le nombre d'utilisateur actifs dans Dolibarr sans CP - * - * @return int retourne le nombre d'utilisateur - */ - function countActiveUsersWithoutCP() { + return $objet->compteur; + } + /** + * Compte le nombre d'utilisateur actifs dans Dolibarr sans CP + * + * @return int retourne le nombre d'utilisateur + */ + function countActiveUsersWithoutCP() { - $sql = "SELECT count(u.rowid) as compteur"; - $sql.= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)"; + $sql = "SELECT count(u.rowid) as compteur"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)"; $sql.= " WHERE u.statut > 0 AND hu.fk_user IS NULL"; - $result = $this->db->query($sql); - $objet = $this->db->fetch_object($result); - - return $objet->compteur; - } - - /** - * Compare le nombre d'utilisateur actif de Dolibarr à celui des utilisateurs des congés payés - * - * @param int $userDolibarrWithoutCP Number of active users in Dolibarr without holidays - * @param int $userCP Number of active users into table of holidays - * @return int <0 if KO, >0 if OK - */ - function verifNbUsers($userDolibarrWithoutCP, $userCP) - { - if (empty($userCP)) $userCP=0; - dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP); - return 1; - } - - - /** - * addLogCP - * - * @param int $fk_user_action Id user creation - * @param int $fk_user_update Id user update - * @param string $label Label - * @param int $new_solde New value - * @param int $fk_type Type of vacation - * @return int Id of record added, 0 if nothing done, < 0 if KO - */ - function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type) - { - global $conf, $langs; - - $error=0; - - $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5); - $new_solde = price2num($new_solde, 5); + $result = $this->db->query($sql); + $objet = $this->db->fetch_object($result); + + return $objet->compteur; + } + + /** + * Compare le nombre d'utilisateur actif de Dolibarr à celui des utilisateurs des congés payés + * + * @param int $userDolibarrWithoutCP Number of active users in Dolibarr without holidays + * @param int $userCP Number of active users into table of holidays + * @return int <0 if KO, >0 if OK + */ + function verifNbUsers($userDolibarrWithoutCP, $userCP) + { + if (empty($userCP)) $userCP=0; + dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP); + return 1; + } + + + /** + * addLogCP + * + * @param int $fk_user_action Id user creation + * @param int $fk_user_update Id user update + * @param string $label Label + * @param int $new_solde New value + * @param int $fk_type Type of vacation + * @return int Id of record added, 0 if nothing done, < 0 if KO + */ + function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type) + { + global $conf, $langs; + + $error=0; + + $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5); + $new_solde = price2num($new_solde, 5); //print "$prev_solde == $new_solde"; - if ($prev_solde == $new_solde) return 0; + if ($prev_solde == $new_solde) return 0; $this->db->begin(); // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs ("; - $sql.= "date_action,"; - $sql.= "fk_user_action,"; - $sql.= "fk_user_update,"; - $sql.= "type_action,"; - $sql.= "prev_solde,"; - $sql.= "new_solde,"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs ("; + $sql.= "date_action,"; + $sql.= "fk_user_action,"; + $sql.= "fk_user_update,"; + $sql.= "type_action,"; + $sql.= "prev_solde,"; + $sql.= "new_solde,"; $sql.= "fk_type"; - $sql.= ") VALUES ("; - $sql.= " '".$this->db->idate(dol_now())."',"; - $sql.= " '".$fk_user_action."',"; - $sql.= " '".$fk_user_update."',"; - $sql.= " '".$this->db->escape($label)."',"; - $sql.= " '".$prev_solde."',"; - $sql.= " '".$new_solde."',"; - $sql.= " ".$fk_type; - $sql.= ")"; - - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; $this->errors[]="Error ".$this->db->lasterror(); - } - - if (! $error) - { - $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs"); - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return $this->optRowid; - } - } - - /** - * Liste le log des congés payés - * - * @param string $order Filtrage par ordre - * @param string $filter Filtre de séléction - * @return int -1 si erreur, 1 si OK et 2 si pas de résultat - */ - function fetchLog($order,$filter) - { - global $langs; - - $sql = "SELECT"; - $sql.= " cpl.rowid,"; - $sql.= " cpl.date_action,"; - $sql.= " cpl.fk_user_action,"; - $sql.= " cpl.fk_user_update,"; - $sql.= " cpl.type_action,"; - $sql.= " cpl.prev_solde,"; - $sql.= " cpl.new_solde,"; + $sql.= ") VALUES ("; + $sql.= " '".$this->db->idate(dol_now())."',"; + $sql.= " '".$fk_user_action."',"; + $sql.= " '".$fk_user_update."',"; + $sql.= " '".$this->db->escape($label)."',"; + $sql.= " '".$prev_solde."',"; + $sql.= " '".$new_solde."',"; + $sql.= " ".$fk_type; + $sql.= ")"; + + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + + if (! $error) + { + $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs"); + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return $this->optRowid; + } + } + + /** + * Liste le log des congés payés + * + * @param string $order Filtrage par ordre + * @param string $filter Filtre de séléction + * @return int -1 si erreur, 1 si OK et 2 si pas de résultat + */ + function fetchLog($order,$filter) + { + global $langs; + + $sql = "SELECT"; + $sql.= " cpl.rowid,"; + $sql.= " cpl.date_action,"; + $sql.= " cpl.fk_user_action,"; + $sql.= " cpl.fk_user_update,"; + $sql.= " cpl.type_action,"; + $sql.= " cpl.prev_solde,"; + $sql.= " cpl.new_solde,"; $sql.= " cpl.fk_type"; - $sql.= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl"; - $sql.= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria + $sql.= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl"; + $sql.= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria - // Filtrage de séléction - if(!empty($filter)) { - $sql.= " ".$filter; - } + // Filtrage de séléction + if(!empty($filter)) { + $sql.= " ".$filter; + } - // Ordre d'affichage - if(!empty($order)) { - $sql.= " ".$order; - } + // Ordre d'affichage + if(!empty($order)) { + $sql.= " ".$order; + } - dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG); - $resql=$this->db->query($sql); + dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG); + $resql=$this->db->query($sql); - // Si pas d'erreur SQL + // Si pas d'erreur SQL if ($resql) { - $i = 0; - $tab_result = $this->logs; - $num = $this->db->num_rows($resql); - - // Si pas d'enregistrement - if(!$num) { - return 2; - } - - // On liste les résultats et on les ajoutent dans le tableau - while($i < $num) { - - $obj = $this->db->fetch_object($resql); - - $tab_result[$i]['rowid'] = $obj->rowid; - $tab_result[$i]['date_action'] = $obj->date_action; - $tab_result[$i]['fk_user_action'] = $obj->fk_user_action; - $tab_result[$i]['fk_user_update'] = $obj->fk_user_update; - $tab_result[$i]['type_action'] = $obj->type_action; - $tab_result[$i]['prev_solde'] = $obj->prev_solde; - $tab_result[$i]['new_solde'] = $obj->new_solde; - $tab_result[$i]['fk_type'] = $obj->fk_type; - - $i++; - } - // Retourne 1 et ajoute le tableau à la variable - $this->logs = $tab_result; - return 1; + $i = 0; + $tab_result = $this->logs; + $num = $this->db->num_rows($resql); + + // Si pas d'enregistrement + if(!$num) { + return 2; + } + + // On liste les résultats et on les ajoutent dans le tableau + while($i < $num) { + + $obj = $this->db->fetch_object($resql); + + $tab_result[$i]['rowid'] = $obj->rowid; + $tab_result[$i]['date_action'] = $obj->date_action; + $tab_result[$i]['fk_user_action'] = $obj->fk_user_action; + $tab_result[$i]['fk_user_update'] = $obj->fk_user_update; + $tab_result[$i]['type_action'] = $obj->type_action; + $tab_result[$i]['prev_solde'] = $obj->prev_solde; + $tab_result[$i]['new_solde'] = $obj->new_solde; + $tab_result[$i]['fk_type'] = $obj->fk_type; + + $i++; + } + // Retourne 1 et ajoute le tableau à la variable + $this->logs = $tab_result; + return 1; } else { - // Erreur SQL - $this->error="Error ".$this->db->lasterror(); - return -1; + // Erreur SQL + $this->error="Error ".$this->db->lasterror(); + return -1; } - } - - - /** - * Return array with list of types - * - * @param int $active Status of type. -1 = Both - * @param int $affect Filter on affect (a request will change sold or not). -1 = Both - * @return array Return array with list of types - */ - function getTypes($active=-1, $affect=-1) - { - global $mysoc; - - $sql = "SELECT rowid, code, label, affect, delay, newByMonth"; - $sql.= " FROM " . MAIN_DB_PREFIX . "c_holiday_types"; - $sql.= " WHERE (fk_country IS NULL OR fk_country = ".$mysoc->country_id.')'; - if ($active >= 0) $sql.=" AND active = ".((int) $active); - if ($affect >= 0) $sql.=" AND affect = ".((int) $affect); - - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - if ($num) - { - while ($obj = $this->db->fetch_object($result)) - { - $types[$obj->rowid] = array('rowid'=> $obj->rowid, 'code'=> $obj->code, 'label'=>$obj->label, 'affect'=>$obj->affect, 'delay'=>$obj->delay, 'newByMonth'=>$obj->newByMonth); - } - - return $types; - } - } - else dol_print_error($this->db); - - return array(); - } - - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - function initAsSpecimen() - { - global $user,$langs; - - // Initialise parameters - $this->id=0; - $this->specimen=1; - - $this->fk_user=1; - $this->description='SPECIMEN description'; - $this->date_debut=dol_now(); - $this->date_fin=dol_now()+(24*3600); - $this->fk_validator=1; - $this->halfday=0; - $this->fk_type=1; - } + } + + + /** + * Return array with list of types + * + * @param int $active Status of type. -1 = Both + * @param int $affect Filter on affect (a request will change sold or not). -1 = Both + * @return array Return array with list of types + */ + function getTypes($active=-1, $affect=-1) + { + global $mysoc; + + $sql = "SELECT rowid, code, label, affect, delay, newByMonth"; + $sql.= " FROM " . MAIN_DB_PREFIX . "c_holiday_types"; + $sql.= " WHERE (fk_country IS NULL OR fk_country = ".$mysoc->country_id.')'; + if ($active >= 0) $sql.=" AND active = ".((int) $active); + if ($affect >= 0) $sql.=" AND affect = ".((int) $affect); + + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + if ($num) + { + while ($obj = $this->db->fetch_object($result)) + { + $types[$obj->rowid] = array('rowid'=> $obj->rowid, 'code'=> $obj->code, 'label'=>$obj->label, 'affect'=>$obj->affect, 'delay'=>$obj->delay, 'newByMonth'=>$obj->newByMonth); + } + + return $types; + } + } + else dol_print_error($this->db); + + return array(); + } + + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $user,$langs; + + // Initialise parameters + $this->id=0; + $this->specimen=1; + + $this->fk_user=1; + $this->description='SPECIMEN description'; + $this->date_debut=dol_now(); + $this->date_fin=dol_now()+(24*3600); + $this->fk_validator=1; + $this->halfday=0; + $this->fk_type=1; + } } diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index b4ed7aeab9feb2fde3f4c2bc8993d1a2cc798e49..4947e71f8c8e1446c0a2814e91e857d2eefcd76f 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -82,13 +82,13 @@ else if ($year && $month && $day) $daytoparse=dol_mktime(0, 0, 0, $month, $day, if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) { - $usertoprocess=$user; + $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } elseif ($search_usertoprocessid > 0) { - $usertoprocess=new User($db); - $usertoprocess->fetch($search_usertoprocessid); + $usertoprocess=new User($db); + $usertoprocess->fetch($search_usertoprocessid); $search_usertoprocessid=$usertoprocess->id; } else @@ -106,17 +106,17 @@ $object=new Task($db); // Purge criteria if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { - $action = ''; - $search_categ=''; - $search_usertoprocessid = $user->id; - $search_task_ref = ''; - $search_task_label = ''; - $search_project_ref = ''; - $search_thirdparty = ''; + $action = ''; + $search_categ=''; + $search_usertoprocessid = $user->id; + $search_task_ref = ''; + $search_task_label = ''; + $search_project_ref = ''; + $search_thirdparty = ''; } if (GETPOST("button_search_x",'alpha') || GETPOST("button_search.x",'alpha') || GETPOST("button_search",'alpha')) { - $action = ''; + $action = ''; } if (GETPOST('submitdateselect')) @@ -129,57 +129,57 @@ if (GETPOST('submitdateselect')) if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask')) { - $action = 'assigntask'; + $action = 'assigntask'; - if ($taskid > 0) - { + if ($taskid > 0) + { $result = $object->fetch($taskid, $ref); if ($result < 0) $error++; - } - else - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), '', 'errors'); - $error++; - } - if (! GETPOST('type')) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors'); - $error++; - } - if (! $error) - { - $idfortaskuser=$usertoprocess->id; + } + else + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), '', 'errors'); + $error++; + } + if (! GETPOST('type')) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors'); + $error++; + } + if (! $error) + { + $idfortaskuser=$usertoprocess->id; $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal'); - if ($result >= 0 || $result == -2) // Contact add ok or already contact of task - { + if ($result >= 0 || $result == -2) // Contact add ok or already contact of task + { // Test if we are already contact of the project (should be rare but sometimes we can add as task contact without being contact of project, like when admin user has been removed from contact of project) - $sql='SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact'; - $sql.=' AND ec.fk_socpeople = '.$idfortaskuser." AND ec.element_id = '.$object->fk_project.' AND tc.element = 'project' AND source = 'internal'"; - $resql=$db->query($sql); - if ($resql) - { - $obj=$db->fetch_object($resql); - if (! $obj) // User is not already linked to project, so we will create link to first type - { - $project = new Project($db); - $project->fetch($object->fk_project); - // Get type - $listofprojcontact=$project->liste_type_contact('internal'); - - if (count($listofprojcontact)) - { - $typeforprojectcontact=reset(array_keys($listofprojcontact)); - $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal'); - } - } - } - else - { - dol_print_error($db); - } - } - } + $sql='SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact'; + $sql.=' AND ec.fk_socpeople = '.$idfortaskuser." AND ec.element_id = '.$object->fk_project.' AND tc.element = 'project' AND source = 'internal'"; + $resql=$db->query($sql); + if ($resql) + { + $obj=$db->fetch_object($resql); + if (! $obj) // User is not already linked to project, so we will create link to first type + { + $project = new Project($db); + $project->fetch($object->fk_project); + // Get type + $listofprojcontact=$project->liste_type_contact('internal'); + + if (count($listofprojcontact)) + { + $typeforprojectcontact=reset(array_keys($listofprojcontact)); + $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal'); + } + } + } + else + { + dol_print_error($db); + } + } + } if ($result < 0) { @@ -206,48 +206,48 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') if ($action == 'addtime' && $user->rights->projet->lire) { - $timespent_duration=array(); - - if (is_array($_POST)) - { - foreach($_POST as $key => $time) - { - if (intval($time) > 0) - { - // Hours or minutes of duration - if (preg_match("/([0-9]+)duration(hour|min)/",$key,$matches)) - { - $id = $matches[1]; - if ($id > 0) - { - // We store HOURS in seconds - if($matches[2]=='hour') $timespent_duration[$id] += $time*60*60; - - // We store MINUTES in seconds - if($matches[2]=='min') $timespent_duration[$id] += $time*60; - } - } - } - } - } - - if (count($timespent_duration) > 0) - { - foreach($timespent_duration as $key => $val) - { - $object->fetch($key); - $object->progress = GETPOST($key.'progress', 'int'); - $object->timespent_duration = $val; - $object->timespent_fk_user = $user->id; - $object->timespent_note = GETPOST($key.'note'); - if (GETPOST($key."hour") != '' && GETPOST($key."hour") >= 0) // If hour was entered - { - $object->timespent_datehour = dol_mktime(GETPOST($key."hour"),GETPOST($key."min"),0,$monthofday,$dayofday,$yearofday); - $object->timespent_withhour = 1; - } - else + $timespent_duration=array(); + + if (is_array($_POST)) + { + foreach($_POST as $key => $time) + { + if (intval($time) > 0) { - $object->timespent_datehour = dol_mktime(12,0,0,$monthofday,$dayofday,$yearofday); + // Hours or minutes of duration + if (preg_match("/([0-9]+)duration(hour|min)/",$key,$matches)) + { + $id = $matches[1]; + if ($id > 0) + { + // We store HOURS in seconds + if($matches[2]=='hour') $timespent_duration[$id] += $time*60*60; + + // We store MINUTES in seconds + if($matches[2]=='min') $timespent_duration[$id] += $time*60; + } + } + } + } + } + + if (count($timespent_duration) > 0) + { + foreach($timespent_duration as $key => $val) + { + $object->fetch($key); + $object->progress = GETPOST($key.'progress', 'int'); + $object->timespent_duration = $val; + $object->timespent_fk_user = $user->id; + $object->timespent_note = GETPOST($key.'note'); + if (GETPOST($key."hour") != '' && GETPOST($key."hour") >= 0) // If hour was entered + { + $object->timespent_datehour = dol_mktime(GETPOST($key."hour"),GETPOST($key."min"),0,$monthofday,$dayofday,$yearofday); + $object->timespent_withhour = 1; + } + else + { + $object->timespent_datehour = dol_mktime(12,0,0,$monthofday,$dayofday,$yearofday); } $object->timespent_date = $object->timespent_datehour; @@ -268,21 +268,21 @@ if ($action == 'addtime' && $user->rights->projet->lire) $error++; break; } - } - - if (! $error) - { - setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); - - // Redirect to avoid submit twice on back - header('Location: '.$_SERVER["PHP_SELF"].'?'.($projectid?'id='.$projectid:'').($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:'').($mode?'&mode='.$mode:'').'&year='.$yearofday.'&month='.$monthofday.'&day='.$dayofday); - exit; - } - } - else - { - setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors'); - } + } + + if (! $error) + { + setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); + + // Redirect to avoid submit twice on back + header('Location: '.$_SERVER["PHP_SELF"].'?'.($projectid?'id='.$projectid:'').($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:'').($mode?'&mode='.$mode:'').'&year='.$yearofday.'&month='.$monthofday.'&day='.$dayofday); + exit; + } + } + else + { + setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors'); + } } @@ -318,8 +318,8 @@ $projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess,(e if ($id) { - $project->fetch($id); - $project->fetch_thirdparty(); + $project->fetch($id); + $project->fetch_thirdparty(); } $onlyopenedproject=1; // or -1 @@ -465,7 +465,7 @@ print '<tr class="liste_titre">'; print '<td>'.$langs->trans("ProjectRef").'</td>'; if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) { - print '<td>'.$langs->trans("ThirdParty").'</td>'; + print '<td>'.$langs->trans("ThirdParty").'</td>'; } print '<td>'.$langs->trans("RefTask").'</td>'; print '<td>'.$langs->trans("LabelTask").'</td>'; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 8ff05e459ed2abade208c695a3d161208649fdbc..873ebfdb442a32b7d6ffe7c5dd8eef8c0186b95e 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -95,13 +95,13 @@ $lastdaytoshow=dol_time_plus_duree($firstdaytoshow, 7, 'd'); if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) { - $usertoprocess=$user; + $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } elseif ($search_usertoprocessid > 0) { - $usertoprocess=new User($db); - $usertoprocess->fetch($search_usertoprocessid); + $usertoprocess=new User($db); + $usertoprocess->fetch($search_usertoprocessid); $search_usertoprocessid=$usertoprocess->id; } else @@ -119,17 +119,17 @@ $object=new Task($db); // Purge criteria if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { - $action = ''; - $search_categ=''; - $search_usertoprocessid = $user->id; - $search_task_ref = ''; - $search_task_label = ''; - $search_project_ref = ''; - $search_thirdparty = ''; + $action = ''; + $search_categ=''; + $search_usertoprocessid = $user->id; + $search_task_ref = ''; + $search_task_label = ''; + $search_project_ref = ''; + $search_thirdparty = ''; } if (GETPOST("button_search_x",'alpha') || GETPOST("button_search.x",'alpha') || GETPOST("button_search",'alpha')) { - $action = ''; + $action = ''; } if (GETPOST('submitdateselect')) @@ -141,58 +141,58 @@ if (GETPOST('submitdateselect')) if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask')) { - $action = 'assigntask'; + $action = 'assigntask'; - if ($taskid > 0) - { + if ($taskid > 0) + { $result = $object->fetch($taskid, $ref); if ($result < 0) $error++; - } - else - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), '', 'errors'); - $error++; - } - if (! GETPOST('type')) - { - setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors'); - $error++; - } - - if (! $error) - { - $idfortaskuser=$usertoprocess->id; - $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal'); - - if ($result >= 0 || $result == -2) // Contact add ok or already contact of task - { - // Test if we are already contact of the project (should be rare but sometimes we can add as task contact without being contact of project, like when admin user has been removed from contact of project) - $sql='SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact'; - $sql.=' AND ec.fk_socpeople = '.$idfortaskuser." AND ec.element_id = '.$object->fk_project.' AND tc.element = 'project' AND source = 'internal'"; - $resql=$db->query($sql); - if ($resql) - { - $obj=$db->fetch_object($resql); - if (! $obj) // User is not already linked to project, so we will create link to first type - { - $project = new Project($db); - $project->fetch($object->fk_project); - // Get type - $listofprojcontact=$project->liste_type_contact('internal'); - - if (count($listofprojcontact)) - { - $typeforprojectcontact=reset(array_keys($listofprojcontact)); - $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal'); - } - } - } - else - { - dol_print_error($db); - } - } - } + } + else + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), '', 'errors'); + $error++; + } + if (! GETPOST('type')) + { + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors'); + $error++; + } + + if (! $error) + { + $idfortaskuser=$usertoprocess->id; + $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal'); + + if ($result >= 0 || $result == -2) // Contact add ok or already contact of task + { + // Test if we are already contact of the project (should be rare but sometimes we can add as task contact without being contact of project, like when admin user has been removed from contact of project) + $sql='SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact'; + $sql.=' AND ec.fk_socpeople = '.$idfortaskuser." AND ec.element_id = '.$object->fk_project.' AND tc.element = 'project' AND source = 'internal'"; + $resql=$db->query($sql); + if ($resql) + { + $obj=$db->fetch_object($resql); + if (! $obj) // User is not already linked to project, so we will create link to first type + { + $project = new Project($db); + $project->fetch($object->fk_project); + // Get type + $listofprojcontact=$project->liste_type_contact('internal'); + + if (count($listofprojcontact)) + { + $typeforprojectcontact=reset(array_keys($listofprojcontact)); + $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal'); + } + } + } + else + { + dol_print_error($db); + } + } + } if ($result < 0) { @@ -219,35 +219,35 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') if ($action == 'addtime' && $user->rights->projet->lire) { - $timetoadd=$_POST['task']; + $timetoadd=$_POST['task']; if (empty($timetoadd)) { - setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors'); - } + setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors'); + } else { foreach($timetoadd as $taskid => $value) // Loop on each task - { - $updateoftaskdone=0; + { + $updateoftaskdone=0; foreach($value as $key => $val) // Loop on each day { $amountoadd=$timetoadd[$taskid][$key]; - if (! empty($amountoadd)) - { - $tmpduration=explode(':',$amountoadd); - $newduration=0; + if (! empty($amountoadd)) + { + $tmpduration=explode(':',$amountoadd); + $newduration=0; if (! empty($tmpduration[0])) $newduration+=($tmpduration[0] * 3600); if (! empty($tmpduration[1])) $newduration+=($tmpduration[1] * 60); if (! empty($tmpduration[2])) $newduration+=($tmpduration[2]); - if ($newduration > 0) - { - $object->fetch($taskid); - $object->progress = GETPOST($taskid . 'progress', 'int'); - $object->timespent_duration = $newduration; - $object->timespent_fk_user = $usertoprocess->id; - $object->timespent_date = dol_time_plus_duree($firstdaytoshow, $key, 'd'); - $object->timespent_datehour = $object->timespent_date; + if ($newduration > 0) + { + $object->fetch($taskid); + $object->progress = GETPOST($taskid . 'progress', 'int'); + $object->timespent_duration = $newduration; + $object->timespent_fk_user = $usertoprocess->id; + $object->timespent_date = dol_time_plus_duree($firstdaytoshow, $key, 'd'); + $object->timespent_datehour = $object->timespent_date; $result=$object->addTimeSpent($user); if ($result < 0) @@ -258,35 +258,35 @@ if ($action == 'addtime' && $user->rights->projet->lire) } $updateoftaskdone++; - } - } + } + } } if (! $updateoftaskdone) // Check to update progress if no update were done on task. { - $object->fetch($taskid); - //var_dump($object->progress);var_dump(GETPOST($taskid . 'progress', 'int')); exit; - if ($object->progress != GETPOST($taskid . 'progress', 'int')) - { - $object->progress = GETPOST($taskid . 'progress', 'int'); - $result=$object->update($user); - if ($result < 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $error++; - break; - } - } + $object->fetch($taskid); + //var_dump($object->progress);var_dump(GETPOST($taskid . 'progress', 'int')); exit; + if ($object->progress != GETPOST($taskid . 'progress', 'int')) + { + $object->progress = GETPOST($taskid . 'progress', 'int'); + $result=$object->update($user); + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + break; + } + } } - } + } if (! $error) { - setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); + setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); - // Redirect to avoid submit twice on back - header('Location: '.$_SERVER["PHP_SELF"].'?'.($projectid?'id='.$projectid:'').($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:'').($mode?'&mode='.$mode:'').($day?'&day='.$day:'').($month?'&month='.$month:'').($year?'&year='.$year:'')); - exit; + // Redirect to avoid submit twice on back + header('Location: '.$_SERVER["PHP_SELF"].'?'.($projectid?'id='.$projectid:'').($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:'').($mode?'&mode='.$mode:'').($day?'&day='.$day:'').($month?'&month='.$month:'').($year?'&year='.$year:'')); + exit; } } } @@ -313,8 +313,8 @@ $projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess,(e //var_dump($projectsListId); if ($id) { - $project->fetch($id); - $project->fetch_thirdparty(); + $project->fetch($id); + $project->fetch_thirdparty(); } $onlyopenedproject=1; // or -1 @@ -449,7 +449,7 @@ print '<td class="liste_titre"></td>'; print '<td class="liste_titre"></td>'; for($i=0;$i<7;$i++) { - print '<td class="liste_titre"></td>'; + print '<td class="liste_titre"></td>'; } // Action column print '<td class="liste_titre nowrap" align="right">'; @@ -462,7 +462,7 @@ print '<tr class="liste_titre">'; print '<td>'.$langs->trans("ProjectRef").'</td>'; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) { - print '<td>'.$langs->trans("ThirdParty").'</td>'; + print '<td>'.$langs->trans("ThirdParty").'</td>'; } print '<td>'.$langs->trans("RefTask").'</td>'; print '<td>'.$langs->trans("LabelTask").'</td>'; @@ -504,8 +504,8 @@ $restrictviewformytask=(empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED if (count($tasksarray) > 0) { - //var_dump($tasksarray); - //var_dump($tasksrole); + //var_dump($tasksarray); + //var_dump($tasksrole); $j=0; $level=0; @@ -516,9 +516,9 @@ if (count($tasksarray) > 0) print '<tr class="liste_total"> <td class="liste_total" colspan="'.$colspan.'">'; - print $langs->trans("Total"); - print ' - '.$langs->trans("ExpectedWorkedHours").': <strong>'.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).'</strong>'; - print '</td> + print $langs->trans("Total"); + print ' - '.$langs->trans("ExpectedWorkedHours").': <strong>'.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).'</strong>'; + print '</td> <td class="liste_total hide0" align="center"><div id="totalDay[0]"> </div></td> <td class="liste_total hide1" align="center"><div id="totalDay[1]"> </div></td> <td class="liste_total hide2" align="center"><div id="totalDay[2]"> </div></td> diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index eb5cd9cfe48669cd86e681d38769f1a8c602af1b..700feba4bd824ff5767c88d555635887ddbf1458 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -61,11 +61,11 @@ $extrafields = new ExtraFields($db); //include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Can't use generic include because when creating a project, ref is defined and we dont want error if fetch fails from ref. if ($id > 0 || ! empty($ref)) { - $ret = $object->fetch($id,$ref); // If we create project, ref may be defined into POST but record does not yet exists into database - if ($ret > 0) { - $object->fetch_thirdparty(); - $id=$object->id; - } + $ret = $object->fetch($id,$ref); // If we create project, ref may be defined into POST but record does not yet exists into database + if ($ret > 0) { + $object->fetch_thirdparty(); + $id=$object->id; + } } // Security check @@ -95,22 +95,22 @@ if (empty($reshook)) { if (GETPOST("comefromclone")==1) { - $result=$object->delete($user); - if ($result > 0) - { - header("Location: index.php"); - exit; - } - else - { - dol_syslog($object->error,LOG_DEBUG); - setEventMessages($langs->trans("CantRemoveProject"), null, 'errors'); - } + $result=$object->delete($user); + if ($result > 0) + { + header("Location: index.php"); + exit; + } + else + { + dol_syslog($object->error,LOG_DEBUG); + setEventMessages($langs->trans("CantRemoveProject"), null, 'errors'); + } } if ($backtopage) { - header("Location: ".$backtopage); - exit; + header("Location: ".$backtopage); + exit; } $action = ''; @@ -118,217 +118,217 @@ if (empty($reshook)) if ($action == 'add' && $user->rights->projet->creer) { - $error=0; - if (empty($_POST["ref"])) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors'); - $error++; - } - if (empty($_POST["title"])) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); - $error++; - } - - if (GETPOST('opp_amount') != '' && ! (GETPOST('opp_status') > 0)) - { - $error++; - setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); - } - - // Create with status validated immediatly - if (! empty($conf->global->PROJECT_CREATE_NO_DRAFT)) - { - $status=Project::STATUS_VALIDATED; - } - - if (! $error) - { - $error=0; - - $db->begin(); - - $object->ref = GETPOST('ref','alpha'); - $object->title = GETPOST('title','none'); // Do not use 'alpha' here, we want field as it is - $object->socid = GETPOST('socid','int'); - $object->description = GETPOST('description','none'); // Do not use 'alpha' here, we want field as it is - $object->public = GETPOST('public','alpha'); - $object->opp_amount = price2num(GETPOST('opp_amount')); - $object->budget_amount = price2num(GETPOST('budget_amount')); - $object->datec = dol_now(); - $object->date_start = $date_start; - $object->date_end = $date_end; - $object->statut = $status; - $object->opp_status = $opp_status; - $object->opp_percent = $opp_percent; - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + $error=0; + if (empty($_POST["ref"])) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors'); + $error++; + } + if (empty($_POST["title"])) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); + $error++; + } + + if (GETPOST('opp_amount') != '' && ! (GETPOST('opp_status') > 0)) + { + $error++; + setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); + } + + // Create with status validated immediatly + if (! empty($conf->global->PROJECT_CREATE_NO_DRAFT)) + { + $status=Project::STATUS_VALIDATED; + } + + if (! $error) + { + $error=0; + + $db->begin(); + + $object->ref = GETPOST('ref','alpha'); + $object->title = GETPOST('title','none'); // Do not use 'alpha' here, we want field as it is + $object->socid = GETPOST('socid','int'); + $object->description = GETPOST('description','none'); // Do not use 'alpha' here, we want field as it is + $object->public = GETPOST('public','alpha'); + $object->opp_amount = price2num(GETPOST('opp_amount')); + $object->budget_amount = price2num(GETPOST('budget_amount')); + $object->datec = dol_now(); + $object->date_start = $date_start; + $object->date_end = $date_end; + $object->statut = $status; + $object->opp_status = $opp_status; + $object->opp_percent = $opp_percent; + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); if ($ret < 0) $error++; - $result = $object->create($user); - if (! $error && $result > 0) - { - // Add myself as project leader - $result = $object->add_contact($user->id, 'PROJECTLEADER', 'internal'); - if ($result < 0) - { - $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); - $error++; - } - } - else - { - $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); - $error++; - } - if (! $error && !empty($object->id) > 0) - { - // Category association - $categories = GETPOST('categories', 'array'); - $result=$object->setCategories($categories); - if ($result<0) { - $langs->load("errors"); - setEventMessages($object->error, $object->errors, 'errors'); - $error++; - } - } - - if (! $error) - { - $db->commit(); + $result = $object->create($user); + if (! $error && $result > 0) + { + // Add myself as project leader + $result = $object->add_contact($user->id, 'PROJECTLEADER', 'internal'); + if ($result < 0) + { + $langs->load("errors"); + setEventMessages($langs->trans($object->error), null, 'errors'); + $error++; + } + } + else + { + $langs->load("errors"); + setEventMessages($langs->trans($object->error), null, 'errors'); + $error++; + } + if (! $error && !empty($object->id) > 0) + { + // Category association + $categories = GETPOST('categories', 'array'); + $result=$object->setCategories($categories); + if ($result<0) { + $langs->load("errors"); + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } - if ($backtopage) + if (! $error) + { + $db->commit(); + + if ($backtopage) { - header("Location: ".$backtopage.'&projectid='.$object->id); - exit; + header("Location: ".$backtopage.'&projectid='.$object->id); + exit; } else { - header("Location:card.php?id=".$object->id); - exit; + header("Location:card.php?id=".$object->id); + exit; } - } - else - { - $db->rollback(); - - $action = 'create'; - } - } - else - { - $action = 'create'; - } + } + else + { + $db->rollback(); + + $action = 'create'; + } + } + else + { + $action = 'create'; + } } if ($action == 'update' && ! $_POST["cancel"] && $user->rights->projet->creer) { - $error=0; - - if (empty($ref)) - { - $error++; - //$_GET["id"]=$_POST["id"]; // We return on the project card - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors'); - } - if (empty($_POST["title"])) - { - $error++; - //$_GET["id"]=$_POST["id"]; // We return on the project card - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); - } - - $db->begin(); - - if (! $error) - { + $error=0; + + if (empty($ref)) + { + $error++; + //$_GET["id"]=$_POST["id"]; // We return on the project card + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors'); + } + if (empty($_POST["title"])) + { + $error++; + //$_GET["id"]=$_POST["id"]; // We return on the project card + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); + } + + $db->begin(); + + if (! $error) + { $object->oldcopy = clone $object; $old_start_date = $object->date_start; - $object->ref = GETPOST('ref','alpha'); - $object->title = GETPOST('title','none'); // Do not use 'alpha' here, we want field as it is - $object->socid = GETPOST('socid','int'); - $object->description = GETPOST('description','none'); // Do not use 'alpha' here, we want field as it is - $object->public = GETPOST('public','alpha'); - $object->date_start = empty($_POST["projectstart"])?'':$date_start; - $object->date_end = empty($_POST["projectend"])?'':$date_end; - if (isset($_POST['opp_amount'])) $object->opp_amount = price2num(GETPOST('opp_amount')); - if (isset($_POST['budget_amount'])) $object->budget_amount= price2num(GETPOST('budget_amount')); - if (isset($_POST['opp_status'])) $object->opp_status = $opp_status; - if (isset($_POST['opp_percent'])) $object->opp_percent = $opp_percent; - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + $object->ref = GETPOST('ref','alpha'); + $object->title = GETPOST('title','none'); // Do not use 'alpha' here, we want field as it is + $object->socid = GETPOST('socid','int'); + $object->description = GETPOST('description','none'); // Do not use 'alpha' here, we want field as it is + $object->public = GETPOST('public','alpha'); + $object->date_start = empty($_POST["projectstart"])?'':$date_start; + $object->date_end = empty($_POST["projectend"])?'':$date_end; + if (isset($_POST['opp_amount'])) $object->opp_amount = price2num(GETPOST('opp_amount')); + if (isset($_POST['budget_amount'])) $object->budget_amount= price2num(GETPOST('budget_amount')); + if (isset($_POST['opp_status'])) $object->opp_status = $opp_status; + if (isset($_POST['opp_percent'])) $object->opp_percent = $opp_percent; + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); if ($ret < 0) $error++; - } + } if ($object->opp_amount && ($object->opp_status <= 0)) - { - $error++; - setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); - } - - if (! $error) - { - $result=$object->update($user); - if ($result < 0) - { - $error++; - if ($result == -4) setEventMessages($langs->trans("ErrorRefAlreadyExists"), null, 'errors'); - else setEventMessages($object->error, $object->errors, 'errors'); - }else { - // Category association - $categories = GETPOST('categories', 'array'); - $result=$object->setCategories($categories); - if ($result < 0) - { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); - } - } - } - - if (! $error) - { - if (GETPOST("reportdate") && ($object->date_start!=$old_start_date)) - { - $result=$object->shiftTaskDate($old_start_date); - if ($result < 0) - { - $error++; - setEventMessages($langs->trans("ErrorShiftTaskDate").':'.$object->error, $object->errors, 'errors'); - } - } - } + { + $error++; + setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); + } + + if (! $error) + { + $result=$object->update($user); + if ($result < 0) + { + $error++; + if ($result == -4) setEventMessages($langs->trans("ErrorRefAlreadyExists"), null, 'errors'); + else setEventMessages($object->error, $object->errors, 'errors'); + }else { + // Category association + $categories = GETPOST('categories', 'array'); + $result=$object->setCategories($categories); + if ($result < 0) + { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + } + + if (! $error) + { + if (GETPOST("reportdate") && ($object->date_start!=$old_start_date)) + { + $result=$object->shiftTaskDate($old_start_date); + if ($result < 0) + { + $error++; + setEventMessages($langs->trans("ErrorShiftTaskDate").':'.$object->error, $object->errors, 'errors'); + } + } + } // Check if we must change status - if (GETPOST('closeproject')) - { - $resclose = $object->setClose($user); - if ($resclose < 0) - { - $error++; - setEventMessages($langs->trans("FailedToCloseProject").':'.$object->error, $object->errors, 'errors'); - } - } + if (GETPOST('closeproject')) + { + $resclose = $object->setClose($user); + if ($resclose < 0) + { + $error++; + setEventMessages($langs->trans("FailedToCloseProject").':'.$object->error, $object->errors, 'errors'); + } + } - if ($error) - { + if ($error) + { $db->rollback(); - $action='edit'; - } - else + $action='edit'; + } + else { - $db->commit(); + $db->commit(); if (GETPOST('socid','int') > 0) $object->fetch_thirdparty(GETPOST('socid','int')); else unset($object->thirdparty); - } + } } @@ -338,25 +338,25 @@ if (empty($reshook)) // Save last template used to generate document if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); - $outputlangs = $langs; - if (GETPOST('lang_id','aZ09')) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang(GETPOST('lang_id','aZ09')); - } - $result= $object->generateDocument($object->modelpdf, $outputlangs); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } + $outputlangs = $langs; + if (GETPOST('lang_id','aZ09')) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang(GETPOST('lang_id','aZ09')); + } + $result= $object->generateDocument($object->modelpdf, $outputlangs); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } } // Delete file in doc form if ($action == 'remove_file' && $user->rights->projet->creer) { - if ($object->id > 0) - { + if ($object->id > 0) + { require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; $langs->load("other"); @@ -368,80 +368,80 @@ if (empty($reshook)) else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); $action = ''; - } + } } if ($action == 'confirm_validate' && $confirm == 'yes') { - $result = $object->setValid($user); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - } + $result = $object->setValid($user); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } } if ($action == 'confirm_close' && $confirm == 'yes') { - $result = $object->setClose($user); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - } + $result = $object->setClose($user); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } } if ($action == 'confirm_reopen' && $confirm == 'yes') { - $result = $object->setValid($user); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - } + $result = $object->setValid($user); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } } if ($action == 'confirm_delete' && GETPOST("confirm") == "yes" && $user->rights->projet->supprimer) { - $object->fetch($id); - $result=$object->delete($user); - if ($result > 0) - { - setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); - header("Location: index.php"); - exit; - } - else - { - dol_syslog($object->error,LOG_DEBUG); - setEventMessages($object->error, $object->errors, 'errors'); - } + $object->fetch($id); + $result=$object->delete($user); + if ($result > 0) + { + setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); + header("Location: index.php"); + exit; + } + else + { + dol_syslog($object->error,LOG_DEBUG); + setEventMessages($object->error, $object->errors, 'errors'); + } } if ($action == 'confirm_clone' && $user->rights->projet->creer && $confirm == 'yes') { - $clone_contacts=GETPOST('clone_contacts')?1:0; - $clone_tasks=GETPOST('clone_tasks')?1:0; + $clone_contacts=GETPOST('clone_contacts')?1:0; + $clone_tasks=GETPOST('clone_tasks')?1:0; $clone_project_files = GETPOST('clone_project_files') ? 1 : 0; $clone_task_files = GETPOST('clone_task_files') ? 1 : 0; - $clone_notes=GETPOST('clone_notes')?1:0; - $move_date=GETPOST('move_date')?1:0; - $clone_thirdparty=GETPOST('socid','int')?GETPOST('socid','int'):0; - - $result=$object->createFromClone($object->id,$clone_contacts,$clone_tasks,$clone_project_files,$clone_task_files,$clone_notes,$move_date,0,$clone_thirdparty); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - } - else - { - // Load new object - $newobject=new Project($db); - $newobject->fetch($result); - $newobject->fetch_optionals(); - $newobject->fetch_thirdparty(); // Load new object - $object=$newobject; - $action='edit'; - $comefromclone=true; - } + $clone_notes=GETPOST('clone_notes')?1:0; + $move_date=GETPOST('move_date')?1:0; + $clone_thirdparty=GETPOST('socid','int')?GETPOST('socid','int'):0; + + $result=$object->createFromClone($object->id,$clone_contacts,$clone_tasks,$clone_project_files,$clone_task_files,$clone_notes,$move_date,0,$clone_thirdparty); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } + else + { + // Load new object + $newobject=new Project($db); + $newobject->fetch($result); + $newobject->fetch_optionals(); + $newobject->fetch_thirdparty(); // Load new object + $object=$newobject; + $action='edit'; + $comefromclone=true; + } } } @@ -464,180 +464,180 @@ llxHeader("",$title,$help_url); if ($action == 'create' && $user->rights->projet->creer) { - /* + /* * Create */ $thirdparty=new Societe($db); if ($socid > 0) $thirdparty->fetch($socid); - print load_fiche_titre($langs->trans("NewProject"), '', 'title_project'); - - print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="add">'; - print '<input type="hidden" name="backtopage" value="'.$backtopage.'">'; - - dol_fiche_head(); - - print '<table class="border" width="100%">'; - - $defaultref=''; - $modele = empty($conf->global->PROJECT_ADDON)?'mod_project_simple':$conf->global->PROJECT_ADDON; - - // Search template files - $file=''; $classname=''; $filefound=0; - $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); - foreach($dirmodels as $reldir) - { - $file=dol_buildpath($reldir."core/modules/project/".$modele.'.php',0); - if (file_exists($file)) - { - $filefound=1; - $classname = $modele; - break; - } - } - - if ($filefound) - { - $result=dol_include_once($reldir."core/modules/project/".$modele.'.php'); - $modProject = new $classname; - - $defaultref = $modProject->getNextValue($thirdparty,$object); - } - - if (is_numeric($defaultref) && $defaultref <= 0) $defaultref=''; - - // Ref - $suggestedref=($_POST["ref"]?$_POST["ref"]:$defaultref); - print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td><input size="12" type="text" name="ref" value="'.dol_escape_htmltag($suggestedref).'">'; - print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref)); - print '</td></tr>'; - - // Label - print '<tr><td><span class="fieldrequired">'.$langs->trans("Label").'</span></td><td><input size="80" type="text" name="title" value="'.dol_escape_htmltag(GETPOST("title",'none')).'" autofocus></td></tr>'; - - // Thirdparty - if ($conf->societe->enabled) - { - print '<tr><td>'; - print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'<span class="fieldrequired">'); - print $langs->trans("ThirdParty"); - print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'</span>'); - print '</td><td class="maxwidthonsmartphone">'; - $filteronlist=''; - if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; - $text=$form->select_company(GETPOST('socid','int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300'); - if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) - { - $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); - print $form->textwithtooltip($text.' '.img_help(),$texthelp,1); - } - else print $text; - print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">'.$langs->trans("AddThirdParty").'</a>'; - print '</td></tr>'; - } - - // Status - if ($status != '') - { - print '<tr><td>'.$langs->trans("Status").'</td><td>'; - print '<input type="hidden" name="status" value="'.$status.'">'; - print $object->LibStatut($status, 4); - print '</td></tr>'; - } - - // Visibility - print '<tr><td>'.$langs->trans("Visibility").'</td><td class="maxwidthonsmartphone">'; - $array=array(); - if (empty($conf->global->PROJECT_DISABLE_PRIVATE_PROJECT)) $array[0] = $langs->trans("PrivateProject"); - if (empty($conf->global->PROJECT_DISABLE_PUBLIC_PROJECT)) $array[1] = $langs->trans("SharedProject"); - print $form->selectarray('public',$array,GETPOST('public')?GETPOST('public'):$object->public); - print '</td></tr>'; - - // Date start - print '<tr><td>'.$langs->trans("DateStart").'</td><td>'; - print $form->select_date(($date_start?$date_start:''),'projectstart',0,0,0,'',1,0,1); - print '</td></tr>'; - - // Date end - print '<tr><td>'.$langs->trans("DateEnd").'</td><td>'; - print $form->select_date(($date_end?$date_end:-1),'projectend',0,0,0,'',1,0,1); - print '</td></tr>'; - - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) - { - // Opportunity status - print '<tr><td>'.$langs->trans("OpportunityStatus").'</td>'; - print '<td class="maxwidthonsmartphone">'; - print $formproject->selectOpportunityStatus('opp_status', GETPOST('opp_status')?GETPOST('opp_status'):$object->opp_status); - print '</tr>'; - - // Opportunity probability - print '<tr><td>'.$langs->trans("OpportunityProbability").'</td>'; - print '<td><input size="5" type="text" id="opp_percent" name="opp_percent" value="'.dol_escape_htmltag(GETPOST('opp_percent')!=''?GETPOST('opp_percent'):'').'"><span class="hideonsmartphone"> %</span>'; - print '<input type="hidden" name="opp_percent_not_set" id="opp_percent_not_set" value="'.dol_escape_htmltag(GETPOST('opp_percent')!=''?'0':'1').'">'; - print '</td>'; - print '</tr>'; - - // Opportunity amount - print '<tr><td>'.$langs->trans("OpportunityAmount").'</td>'; - print '<td><input size="5" type="text" name="opp_amount" value="'.dol_escape_htmltag(GETPOST('opp_amount')!=''?GETPOST('opp_amount'):'').'"></td>'; - print '</tr>'; - } + print load_fiche_titre($langs->trans("NewProject"), '', 'title_project'); + + print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="add">'; + print '<input type="hidden" name="backtopage" value="'.$backtopage.'">'; + + dol_fiche_head(); + + print '<table class="border" width="100%">'; + + $defaultref=''; + $modele = empty($conf->global->PROJECT_ADDON)?'mod_project_simple':$conf->global->PROJECT_ADDON; + + // Search template files + $file=''; $classname=''; $filefound=0; + $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/project/".$modele.'.php',0); + if (file_exists($file)) + { + $filefound=1; + $classname = $modele; + break; + } + } + + if ($filefound) + { + $result=dol_include_once($reldir."core/modules/project/".$modele.'.php'); + $modProject = new $classname; + + $defaultref = $modProject->getNextValue($thirdparty,$object); + } + + if (is_numeric($defaultref) && $defaultref <= 0) $defaultref=''; + + // Ref + $suggestedref=($_POST["ref"]?$_POST["ref"]:$defaultref); + print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td><input size="12" type="text" name="ref" value="'.dol_escape_htmltag($suggestedref).'">'; + print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref)); + print '</td></tr>'; + + // Label + print '<tr><td><span class="fieldrequired">'.$langs->trans("Label").'</span></td><td><input size="80" type="text" name="title" value="'.dol_escape_htmltag(GETPOST("title",'none')).'" autofocus></td></tr>'; + + // Thirdparty + if ($conf->societe->enabled) + { + print '<tr><td>'; + print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'<span class="fieldrequired">'); + print $langs->trans("ThirdParty"); + print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'</span>'); + print '</td><td class="maxwidthonsmartphone">'; + $filteronlist=''; + if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; + $text=$form->select_company(GETPOST('socid','int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300'); + if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) + { + $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); + print $form->textwithtooltip($text.' '.img_help(),$texthelp,1); + } + else print $text; + print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">'.$langs->trans("AddThirdParty").'</a>'; + print '</td></tr>'; + } + + // Status + if ($status != '') + { + print '<tr><td>'.$langs->trans("Status").'</td><td>'; + print '<input type="hidden" name="status" value="'.$status.'">'; + print $object->LibStatut($status, 4); + print '</td></tr>'; + } + + // Visibility + print '<tr><td>'.$langs->trans("Visibility").'</td><td class="maxwidthonsmartphone">'; + $array=array(); + if (empty($conf->global->PROJECT_DISABLE_PRIVATE_PROJECT)) $array[0] = $langs->trans("PrivateProject"); + if (empty($conf->global->PROJECT_DISABLE_PUBLIC_PROJECT)) $array[1] = $langs->trans("SharedProject"); + print $form->selectarray('public',$array,GETPOST('public')?GETPOST('public'):$object->public); + print '</td></tr>'; + + // Date start + print '<tr><td>'.$langs->trans("DateStart").'</td><td>'; + print $form->select_date(($date_start?$date_start:''),'projectstart',0,0,0,'',1,0,1); + print '</td></tr>'; + + // Date end + print '<tr><td>'.$langs->trans("DateEnd").'</td><td>'; + print $form->select_date(($date_end?$date_end:-1),'projectend',0,0,0,'',1,0,1); + print '</td></tr>'; + + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + { + // Opportunity status + print '<tr><td>'.$langs->trans("OpportunityStatus").'</td>'; + print '<td class="maxwidthonsmartphone">'; + print $formproject->selectOpportunityStatus('opp_status', GETPOST('opp_status')?GETPOST('opp_status'):$object->opp_status); + print '</tr>'; + + // Opportunity probability + print '<tr><td>'.$langs->trans("OpportunityProbability").'</td>'; + print '<td><input size="5" type="text" id="opp_percent" name="opp_percent" value="'.dol_escape_htmltag(GETPOST('opp_percent')!=''?GETPOST('opp_percent'):'').'"><span class="hideonsmartphone"> %</span>'; + print '<input type="hidden" name="opp_percent_not_set" id="opp_percent_not_set" value="'.dol_escape_htmltag(GETPOST('opp_percent')!=''?'0':'1').'">'; + print '</td>'; + print '</tr>'; + + // Opportunity amount + print '<tr><td>'.$langs->trans("OpportunityAmount").'</td>'; + print '<td><input size="5" type="text" name="opp_amount" value="'.dol_escape_htmltag(GETPOST('opp_amount')!=''?GETPOST('opp_amount'):'').'"></td>'; + print '</tr>'; + } // Budget print '<tr><td>'.$langs->trans("Budget").'</td>'; print '<td><input size="5" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOST('budget_amount')!=''?GETPOST('budget_amount'):'').'"></td>'; print '</tr>'; - // Description - print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>'; - print '<td>'; - print '<textarea name="description" wrap="soft" class="centpercent" rows="'.ROWS_3.'">'.dol_escape_htmltag(GETPOST("description",'none')).'</textarea>'; - print '</td></tr>'; - - if ($conf->categorie->enabled) { - // Categories - print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">'; - $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1); - $arrayselected=GETPOST('categories', 'array'); - print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); - print "</td></tr>"; - } - - // Other options - $parameters=array(); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit'); - } - - print '</table>'; - - dol_fiche_end(); - - print '<div class="center">'; - print '<input type="submit" class="button" value="'.$langs->trans("CreateDraft").'">'; - if (! empty($backtopage)) - { - print ' '; - print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">'; - } - else - { - print ' '; - print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">'; - } - print '</div>'; - - print '</form>'; - - // Change probability from status - print '<script type="text/javascript" language="javascript"> + // Description + print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>'; + print '<td>'; + print '<textarea name="description" wrap="soft" class="centpercent" rows="'.ROWS_3.'">'.dol_escape_htmltag(GETPOST("description",'none')).'</textarea>'; + print '</td></tr>'; + + if ($conf->categorie->enabled) { + // Categories + print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">'; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1); + $arrayselected=GETPOST('categories', 'array'); + print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); + print "</td></tr>"; + } + + // Other options + $parameters=array(); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit'); + } + + print '</table>'; + + dol_fiche_end(); + + print '<div class="center">'; + print '<input type="submit" class="button" value="'.$langs->trans("CreateDraft").'">'; + if (! empty($backtopage)) + { + print ' '; + print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">'; + } + else + { + print ' '; + print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">'; + } + print '</div>'; + + print '</form>'; + + // Change probability from status + print '<script type="text/javascript" language="javascript"> jQuery(document).ready(function() { function change_percent() { @@ -655,328 +655,328 @@ if ($action == 'create' && $user->rights->projet->creer) } elseif ($object->id > 0) { - /* + /* * Show or edit */ - $res=$object->fetch_optionals($object->id,$extralabels); - - // To verify role of users - $userAccess = $object->restrictedProjectArea($user,'read'); - $userWrite = $object->restrictedProjectArea($user,'write'); - $userDelete = $object->restrictedProjectArea($user,'delete'); - //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; - - - // Confirmation validation - if ($action == 'validate') - { - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProject'), $langs->trans('ConfirmValidateProject'), 'confirm_validate','',0,1); - } - // Confirmation close - if ($action == 'close') - { - print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("CloseAProject"),$langs->trans("ConfirmCloseAProject"),"confirm_close",'','',1); - } - // Confirmation reopen - if ($action == 'reopen') - { - print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("ReOpenAProject"),$langs->trans("ConfirmReOpenAProject"),"confirm_reopen",'','',1); - } - // Confirmation delete - if ($action == 'delete') - { - $text=$langs->trans("ConfirmDeleteAProject"); - $task=new Task($db); - $taskarray=$task->getTasksArray(0,0,$object->id,0,0); - $nboftask=count($taskarray); - if ($nboftask) $text.='<br>'.img_warning().' '.$langs->trans("ThisWillAlsoRemoveTasks",$nboftask); - print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("DeleteAProject"),$text,"confirm_delete",'','',1); - } - - // Clone confirmation - if ($action == 'clone') - { - $formquestion=array( - 'text' => $langs->trans("ConfirmClone"), + $res=$object->fetch_optionals($object->id,$extralabels); + + // To verify role of users + $userAccess = $object->restrictedProjectArea($user,'read'); + $userWrite = $object->restrictedProjectArea($user,'write'); + $userDelete = $object->restrictedProjectArea($user,'delete'); + //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; + + + // Confirmation validation + if ($action == 'validate') + { + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProject'), $langs->trans('ConfirmValidateProject'), 'confirm_validate','',0,1); + } + // Confirmation close + if ($action == 'close') + { + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("CloseAProject"),$langs->trans("ConfirmCloseAProject"),"confirm_close",'','',1); + } + // Confirmation reopen + if ($action == 'reopen') + { + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("ReOpenAProject"),$langs->trans("ConfirmReOpenAProject"),"confirm_reopen",'','',1); + } + // Confirmation delete + if ($action == 'delete') + { + $text=$langs->trans("ConfirmDeleteAProject"); + $task=new Task($db); + $taskarray=$task->getTasksArray(0,0,$object->id,0,0); + $nboftask=count($taskarray); + if ($nboftask) $text.='<br>'.img_warning().' '.$langs->trans("ThisWillAlsoRemoveTasks",$nboftask); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("DeleteAProject"),$text,"confirm_delete",'','',1); + } + + // Clone confirmation + if ($action == 'clone') + { + $formquestion=array( + 'text' => $langs->trans("ConfirmClone"), array('type' => 'other','name' => 'socid','label' => $langs->trans("SelectThirdParty"),'value' => $form->select_company(GETPOST('socid', 'int')>0?GETPOST('socid', 'int'):$object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200')), - array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true), - array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true), - array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true), - array('type' => 'checkbox', 'name' => 'clone_notes', 'label' => $langs->trans("CloneNotes"), 'value' => true), - array('type' => 'checkbox', 'name' => 'clone_project_files','label' => $langs->trans("CloneProjectFiles"), 'value' => false), - array('type' => 'checkbox', 'name' => 'clone_task_files', 'label' => $langs->trans("CloneTaskFiles"), 'value' => false) - ); - - print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("CloneProject"), $langs->trans("ConfirmCloneProject"), "confirm_clone", $formquestion, '', 1, 300, 590); - } - - - print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="update">'; - print '<input type="hidden" name="id" value="'.$object->id.'">'; - print '<input type="hidden" name="comefromclone" value="'.$comefromclone.'">'; - - $head=project_prepare_head($object); - - if ($action == 'edit' && $userWrite > 0) - { - dol_fiche_head($head, 'project', $langs->trans("Project"), 0, ($object->public?'projectpub':'project')); - - print '<table class="border" width="100%">'; - - // Ref - $suggestedref=$object->ref; - print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Ref").'</td>'; - print '<td><input size="12" name="ref" value="'.$suggestedref.'">'; - print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref)); - print '</td></tr>'; - - // Label - print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>'; - print '<td><input class="quatrevingtpercent" name="title" value="'.$object->title.'"></td></tr>'; - - // Thirdparty - if ($conf->societe->enabled) - { - print '<tr><td>'; - print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'<span class="fieldrequired">'); - print $langs->trans("ThirdParty"); - print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'</span>'); - print '</td><td>'; - $filteronlist=''; - if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; - $text=$form->select_company($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), 0, 'minwidth300'); - if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) - { - $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); - print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2); - } - else print $text; - print '</td></tr>'; - } - - // Visibility - print '<tr><td>'.$langs->trans("Visibility").'</td><td>'; - $array=array(); - if (empty($conf->global->PROJECT_DISABLE_PRIVATE_PROJECT)) $array[0] = $langs->trans("PrivateProject"); - if (empty($conf->global->PROJECT_DISABLE_PUBLIC_PROJECT)) $array[1] = $langs->trans("SharedProject"); - print $form->selectarray('public',$array,$object->public); - print '</td></tr>'; - - // Status - print '<tr><td>'.$langs->trans("Status").'</td><td>'.$object->getLibStatut(4).'</td></tr>'; - - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) - { - // Opportunity status - print '<tr><td>'.$langs->trans("OpportunityStatus").'</td>'; - print '<td>'; - print $formproject->selectOpportunityStatus('opp_status', $object->opp_status, 1, 0, 0, 0, 'inline-block valignmiddle'); - print '<div id="divtocloseproject" class="inline-block valign" style="display: none;"> '; - print '<input type="checkbox" id="inputcloseproject" name="closeproject" /> '; - print $langs->trans("AlsoCloseAProject"); - print '</div>'; - print '</td>'; - print '</tr>'; - - // Opportunity probability - print '<tr><td>'.$langs->trans("OpportunityProbability").'</td>'; - print '<td><input size="5" type="text" id="opp_percent" name="opp_percent" value="'.(isset($_POST['opp_percent'])?GETPOST('opp_percent'):(strcmp($object->opp_percent,'')?price($object->opp_percent,0,$langs,1,0):'')).'"> %'; - print '<span id="oldopppercent"></span>'; - print '</td>'; - print '</tr>'; - - // Opportunity amount - print '<tr><td>'.$langs->trans("OpportunityAmount").'</td>'; - print '<td><input size="5" type="text" name="opp_amount" value="'.(isset($_POST['opp_amount'])?GETPOST('opp_amount'):(strcmp($object->opp_amount,'')?price($object->opp_amount,0,$langs,1,0):'')).'"></td>'; - print '</tr>'; - } - - // Date start - print '<tr><td>'.$langs->trans("DateStart").'</td><td>'; - print $form->select_date($object->date_start?$object->date_start:-1,'projectstart',0,0,0,'',1,0,1); - print ' <input type="checkbox" class="valignmiddle" name="reportdate" value="yes" '; - if ($comefromclone){print ' checked ';} + array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true), + array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true), + array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true), + array('type' => 'checkbox', 'name' => 'clone_notes', 'label' => $langs->trans("CloneNotes"), 'value' => true), + array('type' => 'checkbox', 'name' => 'clone_project_files','label' => $langs->trans("CloneProjectFiles"), 'value' => false), + array('type' => 'checkbox', 'name' => 'clone_task_files', 'label' => $langs->trans("CloneTaskFiles"), 'value' => false) + ); + + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("CloneProject"), $langs->trans("ConfirmCloneProject"), "confirm_clone", $formquestion, '', 1, 300, 590); + } + + + print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="update">'; + print '<input type="hidden" name="id" value="'.$object->id.'">'; + print '<input type="hidden" name="comefromclone" value="'.$comefromclone.'">'; + + $head=project_prepare_head($object); + + if ($action == 'edit' && $userWrite > 0) + { + dol_fiche_head($head, 'project', $langs->trans("Project"), 0, ($object->public?'projectpub':'project')); + + print '<table class="border" width="100%">'; + + // Ref + $suggestedref=$object->ref; + print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Ref").'</td>'; + print '<td><input size="12" name="ref" value="'.$suggestedref.'">'; + print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref)); + print '</td></tr>'; + + // Label + print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>'; + print '<td><input class="quatrevingtpercent" name="title" value="'.$object->title.'"></td></tr>'; + + // Thirdparty + if ($conf->societe->enabled) + { + print '<tr><td>'; + print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'<span class="fieldrequired">'); + print $langs->trans("ThirdParty"); + print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED)?'':'</span>'); + print '</td><td>'; + $filteronlist=''; + if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; + $text=$form->select_company($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), 0, 'minwidth300'); + if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) + { + $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); + print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2); + } + else print $text; + print '</td></tr>'; + } + + // Visibility + print '<tr><td>'.$langs->trans("Visibility").'</td><td>'; + $array=array(); + if (empty($conf->global->PROJECT_DISABLE_PRIVATE_PROJECT)) $array[0] = $langs->trans("PrivateProject"); + if (empty($conf->global->PROJECT_DISABLE_PUBLIC_PROJECT)) $array[1] = $langs->trans("SharedProject"); + print $form->selectarray('public',$array,$object->public); + print '</td></tr>'; + + // Status + print '<tr><td>'.$langs->trans("Status").'</td><td>'.$object->getLibStatut(4).'</td></tr>'; + + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + { + // Opportunity status + print '<tr><td>'.$langs->trans("OpportunityStatus").'</td>'; + print '<td>'; + print $formproject->selectOpportunityStatus('opp_status', $object->opp_status, 1, 0, 0, 0, 'inline-block valignmiddle'); + print '<div id="divtocloseproject" class="inline-block valign" style="display: none;"> '; + print '<input type="checkbox" id="inputcloseproject" name="closeproject" /> '; + print $langs->trans("AlsoCloseAProject"); + print '</div>'; + print '</td>'; + print '</tr>'; + + // Opportunity probability + print '<tr><td>'.$langs->trans("OpportunityProbability").'</td>'; + print '<td><input size="5" type="text" id="opp_percent" name="opp_percent" value="'.(isset($_POST['opp_percent'])?GETPOST('opp_percent'):(strcmp($object->opp_percent,'')?price($object->opp_percent,0,$langs,1,0):'')).'"> %'; + print '<span id="oldopppercent"></span>'; + print '</td>'; + print '</tr>'; + + // Opportunity amount + print '<tr><td>'.$langs->trans("OpportunityAmount").'</td>'; + print '<td><input size="5" type="text" name="opp_amount" value="'.(isset($_POST['opp_amount'])?GETPOST('opp_amount'):(strcmp($object->opp_amount,'')?price($object->opp_amount,0,$langs,1,0):'')).'"></td>'; + print '</tr>'; + } + + // Date start + print '<tr><td>'.$langs->trans("DateStart").'</td><td>'; + print $form->select_date($object->date_start?$object->date_start:-1,'projectstart',0,0,0,'',1,0,1); + print ' <input type="checkbox" class="valignmiddle" name="reportdate" value="yes" '; + if ($comefromclone){print ' checked ';} print '/> '. $langs->trans("ProjectReportDate"); - print '</td></tr>'; - - // Date end - print '<tr><td>'.$langs->trans("DateEnd").'</td><td>'; - print $form->select_date($object->date_end?$object->date_end:-1,'projectend',0,0,0,'',1,0,1); - print '</td></tr>'; - - // Budget - print '<tr><td>'.$langs->trans("Budget").'</td>'; - print '<td><input size="5" type="text" name="budget_amount" value="'.(isset($_POST['budget_amount'])?GETPOST('budget_amount'):(strcmp($object->budget_amount,'')?price($object->budget_amount,0,$langs,1,0):'')).'"></td>'; - print '</tr>'; - - // Description - print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>'; - print '<td>'; - print '<textarea name="description" wrap="soft" class="centpercent" rows="'.ROWS_3.'">'.$object->description.'</textarea>'; - print '</td></tr>'; - - // Tags-Categories - if ($conf->categorie->enabled) - { - print '<tr><td class="tdtop">'.$langs->trans("Categories").'</td><td>'; - $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1); - $c = new Categorie($db); - $cats = $c->containing($object->id,Categorie::TYPE_PROJECT); - foreach($cats as $cat) { - $arrayselected[] = $cat->id; - } - print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); - print "</td></tr>"; - } - - // Other options - $parameters=array(); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit'); - } - - print '</table>'; - } - else - { - dol_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); - - // Project card - - $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>'; - - $morehtmlref='<div class="refidno">'; - // Title - $morehtmlref.=$object->title; - // Thirdparty - $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : '; - if ($object->thirdparty->id > 0) - { - $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project'); - } - $morehtmlref.='</div>'; - - // Define a complementary filter for search of next/prev ref. - if (! $user->rights->projet->all->lire) - { - $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0); - $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")"; - } - - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - - print '<div class="fichecenter">'; - print '<div class="fichehalfleft">'; - print '<div class="underbanner clearboth"></div>'; - - print '<table class="border" width="100%">'; - - // Visibility - print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>'; - if ($object->public) print $langs->trans('SharedProject'); - else print $langs->trans('PrivateProject'); - print '</td></tr>'; - - if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) - { - // Opportunity status - print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>'; - $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code'); - if ($code) print $langs->trans("OppStatus".$code); - print '</td></tr>'; - - // Opportunity percent - print '<tr><td>'.$langs->trans("OpportunityProbability").'</td><td>'; - if (strcmp($object->opp_percent,'')) print price($object->opp_percent, 0, $langs, 1, 0).' %'; - print '</td></tr>'; - - // Opportunity Amount - print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>'; - /*if ($object->opp_status) + print '</td></tr>'; + + // Date end + print '<tr><td>'.$langs->trans("DateEnd").'</td><td>'; + print $form->select_date($object->date_end?$object->date_end:-1,'projectend',0,0,0,'',1,0,1); + print '</td></tr>'; + + // Budget + print '<tr><td>'.$langs->trans("Budget").'</td>'; + print '<td><input size="5" type="text" name="budget_amount" value="'.(isset($_POST['budget_amount'])?GETPOST('budget_amount'):(strcmp($object->budget_amount,'')?price($object->budget_amount,0,$langs,1,0):'')).'"></td>'; + print '</tr>'; + + // Description + print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>'; + print '<td>'; + print '<textarea name="description" wrap="soft" class="centpercent" rows="'.ROWS_3.'">'.$object->description.'</textarea>'; + print '</td></tr>'; + + // Tags-Categories + if ($conf->categorie->enabled) + { + print '<tr><td class="tdtop">'.$langs->trans("Categories").'</td><td>'; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1); + $c = new Categorie($db); + $cats = $c->containing($object->id,Categorie::TYPE_PROJECT); + foreach($cats as $cat) { + $arrayselected[] = $cat->id; + } + print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); + print "</td></tr>"; + } + + // Other options + $parameters=array(); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit'); + } + + print '</table>'; + } + else + { + dol_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); + + // Project card + + $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>'; + + $morehtmlref='<div class="refidno">'; + // Title + $morehtmlref.=$object->title; + // Thirdparty + $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : '; + if ($object->thirdparty->id > 0) + { + $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project'); + } + $morehtmlref.='</div>'; + + // Define a complementary filter for search of next/prev ref. + if (! $user->rights->projet->all->lire) + { + $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0); + $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")"; + } + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '<div class="fichecenter">'; + print '<div class="fichehalfleft">'; + print '<div class="underbanner clearboth"></div>'; + + print '<table class="border" width="100%">'; + + // Visibility + print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>'; + if ($object->public) print $langs->trans('SharedProject'); + else print $langs->trans('PrivateProject'); + print '</td></tr>'; + + if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + { + // Opportunity status + print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>'; + $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code'); + if ($code) print $langs->trans("OppStatus".$code); + print '</td></tr>'; + + // Opportunity percent + print '<tr><td>'.$langs->trans("OpportunityProbability").'</td><td>'; + if (strcmp($object->opp_percent,'')) print price($object->opp_percent, 0, $langs, 1, 0).' %'; + print '</td></tr>'; + + // Opportunity Amount + print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>'; + /*if ($object->opp_status) { print price($obj->opp_amount, 1, $langs, 1, 0, -1, $conf->currency); }*/ - if (strcmp($object->opp_amount,'')) print price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency); - print '</td></tr>'; - } + if (strcmp($object->opp_amount,'')) print price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency); + print '</td></tr>'; + } - // Date start - end - print '<tr><td>'.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").'</td><td>'; + // Date start - end + print '<tr><td>'.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").'</td><td>'; $start = dol_print_date($object->date_start,'dayhour'); print ($start?$start:'?'); $end = dol_print_date($object->date_end,'dayhour'); print ' - '; print ($end?$end:'?'); if ($object->hasDelay()) print img_warning("Late"); - print '</td></tr>'; + print '</td></tr>'; - // Budget - print '<tr><td>'.$langs->trans("Budget").'</td><td>'; - if (strcmp($object->budget_amount, '')) print price($object->budget_amount,0,$langs,1,0,0,$conf->currency); - print '</td></tr>'; + // Budget + print '<tr><td>'.$langs->trans("Budget").'</td><td>'; + if (strcmp($object->budget_amount, '')) print price($object->budget_amount,0,$langs,1,0,0,$conf->currency); + print '</td></tr>'; - // Other attributes - $cols = 2; - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + // Other attributes + $cols = 2; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; - print '</table>'; + print '</table>'; - print '</div>'; - print '<div class="fichehalfright">'; - print '<div class="ficheaddleft">'; - print '<div class="underbanner clearboth"></div>'; + print '</div>'; + print '<div class="fichehalfright">'; + print '<div class="ficheaddleft">'; + print '<div class="underbanner clearboth"></div>'; - print '<table class="border" width="100%">'; + print '<table class="border" width="100%">'; - // Description - print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'; - print nl2br($object->description); - print '</td></tr>'; + // Description + print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'; + print nl2br($object->description); + print '</td></tr>'; - // Categories - if($conf->categorie->enabled) { - print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td>'; - print $form->showCategories($object->id,'project',1); - print "</td></tr>"; - } + // Categories + if($conf->categorie->enabled) { + print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td>'; + print $form->showCategories($object->id,'project',1); + print "</td></tr>"; + } - print '</table>'; + print '</table>'; - print '</div>'; - print '</div>'; - print '</div>'; + print '</div>'; + print '</div>'; + print '</div>'; - print '<div class="clearboth"></div>'; - } + print '<div class="clearboth"></div>'; + } - dol_fiche_end(); + dol_fiche_end(); if ($action == 'edit' && $userWrite > 0) { - print '<div align="center">'; - print '<input name="update" class="button" type="submit" value="'.$langs->trans("Modify").'"> '; - print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">'; - print '</div>'; + print '<div align="center">'; + print '<input name="update" class="button" type="submit" value="'.$langs->trans("Modify").'"> '; + print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">'; + print '</div>'; } - print '</form>'; + print '</form>'; - // Change probability from status - if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) - { - // Default value to close or not when we set opp to 'WON'. - $defaultcheckedwhenoppclose=1; - if (empty($conf->global->PROJECT_HIDE_TASKS)) $defaultcheckedwhenoppclose=0; + // Change probability from status + if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) + { + // Default value to close or not when we set opp to 'WON'. + $defaultcheckedwhenoppclose=1; + if (empty($conf->global->PROJECT_HIDE_TASKS)) $defaultcheckedwhenoppclose=0; - print '<!-- Javascript to manage opportunity status change -->'; - print '<script type="text/javascript" language="javascript"> + print '<!-- Javascript to manage opportunity status change -->'; + print '<script type="text/javascript" language="javascript"> jQuery(document).ready(function() { function change_percent() { @@ -1019,204 +1019,204 @@ elseif ($object->id > 0) }); }); </script>'; - } + } - /* + /* * Boutons actions */ - print '<div class="tabsAction">'; - $parameters = array(); - $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook - if (empty($reshook)) - { - if ($action != "edit" ) - { - - // Create event - if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a - // "workflow" action so should appears somewhere else on - // page. - { - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&origin=' . $object->element . '&originid=' . $object->id . '&socid=' . $object->socid . '&projectid=' . $object->id . '">' . $langs->trans("AddAction") . '</a></div>'; - } + print '<div class="tabsAction">'; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if (empty($reshook)) + { + if ($action != "edit" ) + { + + // Create event + if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a + // "workflow" action so should appears somewhere else on + // page. + { + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&origin=' . $object->element . '&originid=' . $object->id . '&socid=' . $object->socid . '&projectid=' . $object->id . '">' . $langs->trans("AddAction") . '</a></div>'; + } // Modify - if ($object->statut != 2 && $user->rights->projet->creer) - { - if ($userWrite > 0) - { - print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=edit">'.$langs->trans("Modify").'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Modify').'</a></div>'; - } - } - - // Validate - if ($object->statut == 0 && $user->rights->projet->creer) - { - if ($userWrite > 0) - { - print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=validate">'.$langs->trans("Validate").'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Validate').'</a></div>'; - } - } - - // Close - if ($object->statut == 1 && $user->rights->projet->creer) - { - if ($userWrite > 0) - { - print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=close">'.$langs->trans("Close").'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Close').'</a></div>'; - } - } - - // Reopen - if ($object->statut == 2 && $user->rights->projet->creer) - { - if ($userWrite > 0) - { - print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=reopen">'.$langs->trans("ReOpen").'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('ReOpen').'</a></div>'; - } - } - - // Add button to create objects from project - if (! empty($conf->global->PROJECT_SHOW_CREATE_OBJECT_BUTTON)) - { - if (! empty($conf->propal->enabled) && $user->rights->propal->creer) - { - $langs->load("propal"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/comm/propal/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddProp").'</a></div>'; - } - if (! empty($conf->commande->enabled) && $user->rights->commande->creer) - { - $langs->load("orders"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("CreateOrder").'</a></div>'; - } - if (! empty($conf->facture->enabled) && $user->rights->facture->creer) - { - $langs->load("bills"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("CreateBill").'</a></div>'; - } - if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->creer) - { - $langs->load("supplier_proposal"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/supplier_proposal/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddSupplierProposal").'</a></div>'; - } - if (! empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->creer) - { - $langs->load("suppliers"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddSupplierOrder").'</a></div>'; - } - if (! empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->creer) - { - $langs->load("suppliers"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddSupplierInvoice").'</a></div>'; - } - if (! empty($conf->ficheinter->enabled) && $user->rights->ficheinter->creer) - { - $langs->load("interventions"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fichinter/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddIntervention").'</a></div>'; - } - if (! empty($conf->contrat->enabled) && $user->rights->contrat->creer) - { - $langs->load("contracts"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/contrat/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddContract").'</a></div>'; - } - if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->creer) - { - $langs->load("trips"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/expensereport/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddTrip").'</a></div>'; - } - if (! empty($conf->don->enabled) && $user->rights->don->creer) - { - $langs->load("donations"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/don/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddDonation").'</a></div>'; - } - } - - // Clone - if ($user->rights->projet->creer) - { - if ($userWrite > 0) - { - print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=clone">'.$langs->trans('ToClone').'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('ToClone').'</a></div>'; - } - } - - // Delete - if ($user->rights->projet->supprimer || ($object->statut == 0 && $user->rights->projet->creer)) - { - if ($userDelete > 0 || ($object->statut == 0 && $user->rights->projet->creer)) - { - print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?id='.$object->id.'&action=delete">'.$langs->trans("Delete").'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Delete').'</a></div>'; - } - } - } - } - - print "</div>"; - - if ($action != 'presend') - { - print '<div class="fichecenter"><div class="fichehalfleft">'; - print '<a name="builddoc"></a>'; // ancre - - /* + if ($object->statut != 2 && $user->rights->projet->creer) + { + if ($userWrite > 0) + { + print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=edit">'.$langs->trans("Modify").'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Modify').'</a></div>'; + } + } + + // Validate + if ($object->statut == 0 && $user->rights->projet->creer) + { + if ($userWrite > 0) + { + print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=validate">'.$langs->trans("Validate").'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Validate').'</a></div>'; + } + } + + // Close + if ($object->statut == 1 && $user->rights->projet->creer) + { + if ($userWrite > 0) + { + print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=close">'.$langs->trans("Close").'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Close').'</a></div>'; + } + } + + // Reopen + if ($object->statut == 2 && $user->rights->projet->creer) + { + if ($userWrite > 0) + { + print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=reopen">'.$langs->trans("ReOpen").'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('ReOpen').'</a></div>'; + } + } + + // Add button to create objects from project + if (! empty($conf->global->PROJECT_SHOW_CREATE_OBJECT_BUTTON)) + { + if (! empty($conf->propal->enabled) && $user->rights->propal->creer) + { + $langs->load("propal"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/comm/propal/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddProp").'</a></div>'; + } + if (! empty($conf->commande->enabled) && $user->rights->commande->creer) + { + $langs->load("orders"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("CreateOrder").'</a></div>'; + } + if (! empty($conf->facture->enabled) && $user->rights->facture->creer) + { + $langs->load("bills"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("CreateBill").'</a></div>'; + } + if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->creer) + { + $langs->load("supplier_proposal"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/supplier_proposal/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddSupplierProposal").'</a></div>'; + } + if (! empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->creer) + { + $langs->load("suppliers"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddSupplierOrder").'</a></div>'; + } + if (! empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->creer) + { + $langs->load("suppliers"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddSupplierInvoice").'</a></div>'; + } + if (! empty($conf->ficheinter->enabled) && $user->rights->ficheinter->creer) + { + $langs->load("interventions"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fichinter/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddIntervention").'</a></div>'; + } + if (! empty($conf->contrat->enabled) && $user->rights->contrat->creer) + { + $langs->load("contracts"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/contrat/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddContract").'</a></div>'; + } + if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->creer) + { + $langs->load("trips"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/expensereport/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddTrip").'</a></div>'; + } + if (! empty($conf->don->enabled) && $user->rights->don->creer) + { + $langs->load("donations"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/don/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("AddDonation").'</a></div>'; + } + } + + // Clone + if ($user->rights->projet->creer) + { + if ($userWrite > 0) + { + print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=clone">'.$langs->trans('ToClone').'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('ToClone').'</a></div>'; + } + } + + // Delete + if ($user->rights->projet->supprimer || ($object->statut == 0 && $user->rights->projet->creer)) + { + if ($userDelete > 0 || ($object->statut == 0 && $user->rights->projet->creer)) + { + print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?id='.$object->id.'&action=delete">'.$langs->trans("Delete").'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('Delete').'</a></div>'; + } + } + } + } + + print "</div>"; + + if ($action != 'presend') + { + print '<div class="fichecenter"><div class="fichehalfleft">'; + print '<a name="builddoc"></a>'; // ancre + + /* * Documents generes */ - $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->projet->dir_output . "/" . dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed=($user->rights->projet->lire && $userAccess > 0); - $delallowed=($user->rights->projet->creer && $userWrite > 0); + $filename=dol_sanitizeFileName($object->ref); + $filedir=$conf->projet->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id; + $genallowed=($user->rights->projet->lire && $userAccess > 0); + $delallowed=($user->rights->projet->creer && $userWrite > 0); - print $formfile->showdocuments('project',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf); + print $formfile->showdocuments('project',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf); - print '</div><div class="fichehalfright"><div class="ficheaddleft">'; + print '</div><div class="fichehalfright"><div class="ficheaddleft">'; - $MAX = 10; + $MAX = 10; - $morehtmlright = '<a href="'.DOL_URL_ROOT.'/projet/info.php?id='.$object->id.'">'; - $morehtmlright.= $langs->trans("SeeAll"); - $morehtmlright.= '</a>'; + $morehtmlright = '<a href="'.DOL_URL_ROOT.'/projet/info.php?id='.$object->id.'">'; + $morehtmlright.= $langs->trans("SeeAll"); + $morehtmlright.= '</a>'; - // List of actions on element - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'project', $socid, 1, '', $MAX, '', $morehtmlright); + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'project', $socid, 1, '', $MAX, '', $morehtmlright); - print '</div></div></div>'; - } + print '</div></div></div>'; + } - // Hook to add more things on page - $parameters=array(); - $reshook=$hookmanager->executeHooks('mainCardTabAddMore',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + // Hook to add more things on page + $parameters=array(); + $reshook=$hookmanager->executeHooks('mainCardTabAddMore',$parameters,$object,$action); // Note that $action and $object may have been modified by hook } else { - print $langs->trans("RecordNotFound"); + print $langs->trans("RecordNotFound"); } llxFooter(); diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index eea954033970446884eb870ba27ca2a30f339f1c..f6969075b2aedfae5beb4f6da2ad152b11a78839 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -31,25 +31,25 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; */ class Task extends CommonObject { - public $element='project_task'; //!< Id that identify managed objects - public $table_element='projet_task'; //!< Name of table without prefix where object is stored - public $fk_element='fk_task'; - public $picto = 'task'; - protected $childtables=array('projet_task_time','projet_task_comment'); // To test if we can delete object - - var $fk_task_parent; - var $label; - var $description; - var $duration_effective; // total of time spent on this task - var $planned_workload; - var $date_c; - var $date_start; - var $date_end; - var $progress; - var $fk_statut; - var $priority; - var $fk_user_creat; - var $fk_user_valid; + public $element='project_task'; //!< Id that identify managed objects + public $table_element='projet_task'; //!< Name of table without prefix where object is stored + public $fk_element='fk_task'; + public $picto = 'task'; + protected $childtables=array('projet_task_time','projet_task_comment'); // To test if we can delete object + + var $fk_task_parent; + var $label; + var $description; + var $duration_effective; // total of time spent on this task + var $planned_workload; + var $date_c; + var $date_start; + var $date_end; + var $progress; + var $fk_statut; + var $priority; + var $fk_user_creat; + var $fk_user_valid; var $rang; var $timespent_min_date; @@ -61,1296 +61,1296 @@ class Task extends CommonObject // For detail of lines of timespent record, there is the property ->lines in common // Var used to call method addTimeSpent(). Bad practice. - var $timespent_id; - var $timespent_duration; - var $timespent_old_duration; - var $timespent_date; - var $timespent_datehour; // More accurate start date (same than timespent_date but includes hours, minutes and seconds) - var $timespent_withhour; // 1 = we entered also start hours for timesheet line - var $timespent_fk_user; - var $timespent_note; - - var $comments = array(); - - public $oldcopy; - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - } - - - /** - * Create into database - * - * @param User $user User that create - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, Id of created object if OK - */ - function create($user, $notrigger=0) - { - global $conf, $langs; - - $error=0; - - // Clean parameters - $this->label = trim($this->label); - $this->description = trim($this->description); - - // Check parameters - // Put here code to add control on parameters values - - // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task ("; - $sql.= "fk_projet"; + var $timespent_id; + var $timespent_duration; + var $timespent_old_duration; + var $timespent_date; + var $timespent_datehour; // More accurate start date (same than timespent_date but includes hours, minutes and seconds) + var $timespent_withhour; // 1 = we entered also start hours for timesheet line + var $timespent_fk_user; + var $timespent_note; + + var $comments = array(); + + public $oldcopy; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + + /** + * Create into database + * + * @param User $user User that create + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + function create($user, $notrigger=0) + { + global $conf, $langs; + + $error=0; + + // Clean parameters + $this->label = trim($this->label); + $this->description = trim($this->description); + + // Check parameters + // Put here code to add control on parameters values + + // Insert request + $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task ("; + $sql.= "fk_projet"; $sql.= ", ref"; - $sql.= ", fk_task_parent"; - $sql.= ", label"; - $sql.= ", description"; - $sql.= ", datec"; - $sql.= ", fk_user_creat"; - $sql.= ", dateo"; - $sql.= ", datee"; - $sql.= ", planned_workload"; - $sql.= ", progress"; - $sql.= ") VALUES ("; - $sql.= $this->fk_project; + $sql.= ", fk_task_parent"; + $sql.= ", label"; + $sql.= ", description"; + $sql.= ", datec"; + $sql.= ", fk_user_creat"; + $sql.= ", dateo"; + $sql.= ", datee"; + $sql.= ", planned_workload"; + $sql.= ", progress"; + $sql.= ") VALUES ("; + $sql.= $this->fk_project; $sql.= ", ".(!empty($this->ref)?"'".$this->db->escape($this->ref)."'":'null'); - $sql.= ", ".$this->fk_task_parent; - $sql.= ", '".$this->db->escape($this->label)."'"; - $sql.= ", '".$this->db->escape($this->description)."'"; - $sql.= ", '".$this->db->idate($this->date_c)."'"; - $sql.= ", ".$user->id; - $sql.= ", ".($this->date_start!=''?"'".$this->db->idate($this->date_start)."'":'null'); - $sql.= ", ".($this->date_end!=''?"'".$this->db->idate($this->date_end)."'":'null'); - $sql.= ", ".(($this->planned_workload!='' && $this->planned_workload >= 0)?$this->planned_workload:'null'); - $sql.= ", ".(($this->progress!='' && $this->progress >= 0)?$this->progress:'null'); - $sql.= ")"; - - $this->db->begin(); - - dol_syslog(get_class($this)."::create", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - - if (! $error) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task"); - - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('TASK_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - // Update extrafield - if (! $error) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return $this->id; - } - } - - - /** - * Load object in memory from database - * - * @param int $id Id object - * @param int $ref ref object - * @return int <0 if KO, 0 if not found, >0 if OK - */ - function fetch($id,$ref='') - { - global $langs; - - $sql = "SELECT"; - $sql.= " t.rowid,"; + $sql.= ", ".$this->fk_task_parent; + $sql.= ", '".$this->db->escape($this->label)."'"; + $sql.= ", '".$this->db->escape($this->description)."'"; + $sql.= ", '".$this->db->idate($this->date_c)."'"; + $sql.= ", ".$user->id; + $sql.= ", ".($this->date_start!=''?"'".$this->db->idate($this->date_start)."'":'null'); + $sql.= ", ".($this->date_end!=''?"'".$this->db->idate($this->date_end)."'":'null'); + $sql.= ", ".(($this->planned_workload!='' && $this->planned_workload >= 0)?$this->planned_workload:'null'); + $sql.= ", ".(($this->progress!='' && $this->progress >= 0)?$this->progress:'null'); + $sql.= ")"; + + $this->db->begin(); + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task"); + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('TASK_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Update extrafield + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return $this->id; + } + } + + + /** + * Load object in memory from database + * + * @param int $id Id object + * @param int $ref ref object + * @return int <0 if KO, 0 if not found, >0 if OK + */ + function fetch($id,$ref='') + { + global $langs; + + $sql = "SELECT"; + $sql.= " t.rowid,"; $sql.= " t.ref,"; - $sql.= " t.fk_projet,"; - $sql.= " t.fk_task_parent,"; - $sql.= " t.label,"; - $sql.= " t.description,"; - $sql.= " t.duration_effective,"; - $sql.= " t.planned_workload,"; - $sql.= " t.datec,"; - $sql.= " t.dateo,"; - $sql.= " t.datee,"; - $sql.= " t.fk_user_creat,"; - $sql.= " t.fk_user_valid,"; - $sql.= " t.fk_statut,"; - $sql.= " t.progress,"; - $sql.= " t.priority,"; - $sql.= " t.note_private,"; + $sql.= " t.fk_projet,"; + $sql.= " t.fk_task_parent,"; + $sql.= " t.label,"; + $sql.= " t.description,"; + $sql.= " t.duration_effective,"; + $sql.= " t.planned_workload,"; + $sql.= " t.datec,"; + $sql.= " t.dateo,"; + $sql.= " t.datee,"; + $sql.= " t.fk_user_creat,"; + $sql.= " t.fk_user_valid,"; + $sql.= " t.fk_statut,"; + $sql.= " t.progress,"; + $sql.= " t.priority,"; + $sql.= " t.note_private,"; $sql.= " t.note_public,"; $sql.= " t.rang"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as t"; - $sql.= " WHERE "; - if (!empty($ref)) { - $sql.="t.ref = '".$this->db->escape($ref)."'"; - }else { - $sql.="t.rowid = ".$id; - } - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $num_rows = $this->db->num_rows($resql); - - if ($num_rows) - { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as t"; + $sql.= " WHERE "; + if (!empty($ref)) { + $sql.="t.ref = '".$this->db->escape($ref)."'"; + }else { + $sql.="t.rowid = ".$id; + } + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $num_rows = $this->db->num_rows($resql); + + if ($num_rows) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; $this->ref = $obj->ref; - $this->fk_project = $obj->fk_projet; - $this->fk_task_parent = $obj->fk_task_parent; - $this->label = $obj->label; - $this->description = $obj->description; - $this->duration_effective = $obj->duration_effective; - $this->planned_workload = $obj->planned_workload; - $this->date_c = $this->db->jdate($obj->datec); - $this->date_start = $this->db->jdate($obj->dateo); - $this->date_end = $this->db->jdate($obj->datee); - $this->fk_user_creat = $obj->fk_user_creat; - $this->fk_user_valid = $obj->fk_user_valid; - $this->fk_statut = $obj->fk_statut; - $this->progress = $obj->progress; - $this->priority = $obj->priority; - $this->note_private = $obj->note_private; - $this->note_public = $obj->note_public; + $this->fk_project = $obj->fk_projet; + $this->fk_task_parent = $obj->fk_task_parent; + $this->label = $obj->label; + $this->description = $obj->description; + $this->duration_effective = $obj->duration_effective; + $this->planned_workload = $obj->planned_workload; + $this->date_c = $this->db->jdate($obj->datec); + $this->date_start = $this->db->jdate($obj->dateo); + $this->date_end = $this->db->jdate($obj->datee); + $this->fk_user_creat = $obj->fk_user_creat; + $this->fk_user_valid = $obj->fk_user_valid; + $this->fk_statut = $obj->fk_statut; + $this->progress = $obj->progress; + $this->priority = $obj->priority; + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; $this->rang = $obj->rang; - // Retreive all extrafield for thirdparty - $this->fetch_optionals(); - } - - $this->db->free($resql); - - if ($num_rows) { - $this->fetchComments(); - return 1; - }else { - return 0; - } - } - else - { - $this->error="Error ".$this->db->lasterror(); - return -1; - } - } - - - /** - * Update database - * - * @param User $user User that modify - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <=0 if KO, >0 if OK - */ - function update($user=null, $notrigger=0) - { - global $conf, $langs; - $error=0; - - // Clean parameters - if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); - if (isset($this->ref)) $this->ref=trim($this->ref); - if (isset($this->fk_task_parent)) $this->fk_task_parent=trim($this->fk_task_parent); - if (isset($this->label)) $this->label=trim($this->label); - if (isset($this->description)) $this->description=trim($this->description); - if (isset($this->duration_effective)) $this->duration_effective=trim($this->duration_effective); - if (isset($this->planned_workload)) $this->planned_workload=trim($this->planned_workload); - - // Check parameters - // Put here code to add control on parameters values - - // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task SET"; - $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; - $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"'".$this->db->escape($this->id)."'").","; - $sql.= " fk_task_parent=".(isset($this->fk_task_parent)?$this->fk_task_parent:"null").","; - $sql.= " label=".(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").","; - $sql.= " description=".(isset($this->description)?"'".$this->db->escape($this->description)."'":"null").","; - $sql.= " duration_effective=".(isset($this->duration_effective)?$this->duration_effective:"null").","; - $sql.= " planned_workload=".((isset($this->planned_workload) && $this->planned_workload != '')?$this->planned_workload:"null").","; - $sql.= " dateo=".($this->date_start!=''?"'".$this->db->idate($this->date_start)."'":'null').","; - $sql.= " datee=".($this->date_end!=''?"'".$this->db->idate($this->date_end)."'":'null').","; - $sql.= " progress=".(($this->progress!='' && $this->progress >= 0)?$this->progress:'null').","; - $sql.= " rang=".((!empty($this->rang))?$this->rang:"0"); - $sql.= " WHERE rowid=".$this->id; - - $this->db->begin(); - - dol_syslog(get_class($this)."::update", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - - if (! $error) - { - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('TASK_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - //Update extrafield - if (!$error) { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - - if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) - { - // We remove directory - if ($conf->projet->dir_output) - { - $project = new Project($this->db); - $project->fetch($this->fk_project); - - $olddir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->oldcopy->ref); - $newdir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->ref); - if (file_exists($olddir)) - { - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $res=dol_move($olddir, $newdir); - if (! $res) - { - $langs->load("errors"); - $this->error=$langs->trans('ErrorFailToRenameDir',$olddir,$newdir); - $error++; - } - } - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return 1; - } - } - - - /** - * Delete task from database - * - * @param User $user User that delete - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function delete($user, $notrigger=0) - { - - global $conf, $langs; - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $error=0; - - $this->db->begin(); - - if ($this->hasChildren() > 0) - { - dol_syslog(get_class($this)."::delete Can't delete record as it has some sub tasks", LOG_WARNING); - $this->error='ErrorRecordHasSubTasks'; - $this->db->rollback(); - return 0; - } - - $objectisused = $this->isObjectUsed($this->id); - if (! empty($objectisused)) - { - dol_syslog(get_class($this)."::delete Can't delete record as it has some child", LOG_WARNING); - $this->error='ErrorRecordHasChildren'; - $this->db->rollback(); - return 0; - } - - if (! $error) - { - // Delete linked contacts - $res = $this->delete_linked_contact(); - if ($res < 0) - { - $this->error='ErrorFailToDeleteLinkedContact'; - //$error++; - $this->db->rollback(); - return 0; - } - } - - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time"; - $sql.= " WHERE fk_task=".$this->id; - - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - } - - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_extrafields"; - $sql.= " WHERE fk_object=".$this->id; - - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - } - - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task"; - $sql.= " WHERE rowid=".$this->id; - - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - } - - if (! $error) - { - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('TASK_DELETE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else + // Retreive all extrafield for thirdparty + $this->fetch_optionals(); + } + + $this->db->free($resql); + + if ($num_rows) { + $this->fetchComments(); + return 1; + }else { + return 0; + } + } + else + { + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <=0 if KO, >0 if OK + */ + function update($user=null, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Clean parameters + if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); + if (isset($this->ref)) $this->ref=trim($this->ref); + if (isset($this->fk_task_parent)) $this->fk_task_parent=trim($this->fk_task_parent); + if (isset($this->label)) $this->label=trim($this->label); + if (isset($this->description)) $this->description=trim($this->description); + if (isset($this->duration_effective)) $this->duration_effective=trim($this->duration_effective); + if (isset($this->planned_workload)) $this->planned_workload=trim($this->planned_workload); + + // Check parameters + // Put here code to add control on parameters values + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task SET"; + $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; + $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"'".$this->db->escape($this->id)."'").","; + $sql.= " fk_task_parent=".(isset($this->fk_task_parent)?$this->fk_task_parent:"null").","; + $sql.= " label=".(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").","; + $sql.= " description=".(isset($this->description)?"'".$this->db->escape($this->description)."'":"null").","; + $sql.= " duration_effective=".(isset($this->duration_effective)?$this->duration_effective:"null").","; + $sql.= " planned_workload=".((isset($this->planned_workload) && $this->planned_workload != '')?$this->planned_workload:"null").","; + $sql.= " dateo=".($this->date_start!=''?"'".$this->db->idate($this->date_start)."'":'null').","; + $sql.= " datee=".($this->date_end!=''?"'".$this->db->idate($this->date_end)."'":'null').","; + $sql.= " progress=".(($this->progress!='' && $this->progress >= 0)?$this->progress:'null').","; + $sql.= " rang=".((!empty($this->rang))?$this->rang:"0"); + $sql.= " WHERE rowid=".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('TASK_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + //Update extrafield + if (!$error) { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + + if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) + { + // We remove directory + if ($conf->projet->dir_output) + { + $project = new Project($this->db); + $project->fetch($this->fk_project); + + $olddir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->oldcopy->ref); + $newdir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->ref); + if (file_exists($olddir)) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $res=dol_move($olddir, $newdir); + if (! $res) + { + $langs->load("errors"); + $this->error=$langs->trans('ErrorFailToRenameDir',$olddir,$newdir); + $error++; + } + } + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Delete task from database + * + * @param User $user User that delete + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function delete($user, $notrigger=0) + { + + global $conf, $langs; + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $error=0; + + $this->db->begin(); + + if ($this->hasChildren() > 0) + { + dol_syslog(get_class($this)."::delete Can't delete record as it has some sub tasks", LOG_WARNING); + $this->error='ErrorRecordHasSubTasks'; + $this->db->rollback(); + return 0; + } + + $objectisused = $this->isObjectUsed($this->id); + if (! empty($objectisused)) + { + dol_syslog(get_class($this)."::delete Can't delete record as it has some child", LOG_WARNING); + $this->error='ErrorRecordHasChildren'; + $this->db->rollback(); + return 0; + } + + if (! $error) + { + // Delete linked contacts + $res = $this->delete_linked_contact(); + if ($res < 0) + { + $this->error='ErrorFailToDeleteLinkedContact'; + //$error++; + $this->db->rollback(); + return 0; + } + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time"; + $sql.= " WHERE fk_task=".$this->id; + + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_extrafields"; + $sql.= " WHERE fk_object=".$this->id; + + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task"; + $sql.= " WHERE rowid=".$this->id; + + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + } + + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('TASK_DELETE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + //Delete associated link file + if ($conf->projet->dir_output) + { + $projectstatic=new Project($this->db); + $projectstatic->fetch($this->fk_project); + + $dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($projectstatic->ref) . '/' . dol_sanitizeFileName($this->id); + dol_syslog(get_class($this)."::delete dir=".$dir, LOG_DEBUG); + if (file_exists($dir)) + { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $res = @dol_delete_dir_recursive($dir); + if (!$res) + { + $this->error = 'ErrorFailToDeleteDir'; + $this->db->rollback(); + return 0; + } + } + } + + $this->db->commit(); + + return 1; + } + } + + /** + * Return nb of children + * + * @return int <0 if KO, 0 if no children, >0 if OK + */ + function hasChildren() + { + $error=0; + $ret=0; + + $sql = "SELECT COUNT(*) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task"; + $sql.= " WHERE fk_task_parent=".$this->id; + + dol_syslog(get_class($this)."::hasChildren", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + else + { + $obj=$this->db->fetch_object($resql); + if ($obj) $ret=$obj->nb; + $this->db->free($resql); + } + + if (! $error) + { + return $ret; + } + else + { + return -1; + } + } + + /** + * Return nb of time spent + * + * @return int <0 if KO, 0 if no children, >0 if OK + */ + function hasTimeSpent() + { + $error=0; + $ret=0; + + $sql = "SELECT COUNT(*) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time"; + $sql.= " WHERE fk_task=".$this->id; + + dol_syslog(get_class($this)."::hasTimeSpent", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + else + { + $obj=$this->db->fetch_object($resql); + if ($obj) $ret=$obj->nb; + $this->db->free($resql); + } + + if (! $error) + { + return $ret; + } + else + { + return -1; + } + } + + + /** + * Return clicable name (with picto eventually) + * + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param string $option 'withproject' or '' + * @param string $mode Mode 'task', 'time', 'contact', 'note', document' define page to link to. + * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string + * @param string $sep Separator between ref and label if option addlabel is set + * @param int $notooltip 1=Disable tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string Chaine avec URL + */ + function getNomUrl($withpicto=0,$option='',$mode='task', $addlabel=0, $sep=' - ', $notooltip=0, $save_lastsearch_value=-1) + { + global $conf, $langs, $user; + + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + + $result=''; + $label = '<u>' . $langs->trans("ShowTask") . '</u>'; + if (! empty($this->ref)) + $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; + if (! empty($this->label)) + $label .= '<br><b>' . $langs->trans('LabelTask') . ':</b> ' . $this->label; + if ($this->date_start || $this->date_end) + { + $label .= "<br>".get_date_range($this->date_start,$this->date_end,'',$langs,0); + } + + $url = DOL_URL_ROOT.'/projet/tasks/'.$mode.'.php?id='.$this->id.($option=='withproject'?'&withproject=1':''); + // Add param to save lastsearch_values or not + $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; + if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; + + $linkclose = ''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowTask"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; + } + + $linkstart = '<a href="'.$url.'"'; + $linkstart.=$linkclose.'>'; + $linkend='</a>'; + + $picto='projecttask'; + + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); + if ($withpicto && $withpicto != 2) $result.=' '; + if ($withpicto != 2) $result.=$linkstart.$this->ref.$linkend . (($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + return $result; + } + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + $this->id=0; + + $this->fk_projet=''; + $this->ref='TK01'; + $this->fk_task_parent=''; + $this->label='Specimen task TK01'; + $this->duration_effective=''; + $this->fk_user_creat=''; + $this->progress='25'; + $this->fk_statut=''; + $this->note='This is a specimen task not'; + } + + /** + * Return list of tasks for all projects or for one particular project + * Sort order is on project, then on position of task, and last on start date of first level task + * + * @param User $usert Object user to limit tasks affected to a particular user + * @param User $userp Object user to limit projects of a particular user and public projects + * @param int $projectid Project id + * @param int $socid Third party id + * @param int $mode 0=Return list of tasks and their projects, 1=Return projects and tasks if exists + * @param string $filteronprojref Filter on project ref + * @param string $filteronprojstatus Filter on project status + * @param string $morewherefilter Add more filter into where SQL request (must start with ' AND ...') + * @param string $filteronprojuser Filter on user that is a contact of project + * @param string $filterontaskuser Filter on user assigned to task + * @return array Array of tasks + */ + function getTasksArray($usert=0, $userp=0, $projectid=0, $socid=0, $mode=0, $filteronprojref='', $filteronprojstatus=-1, $morewherefilter='',$filteronprojuser=0,$filterontaskuser=0) + { + global $conf; + + $tasks = array(); + + //print $usert.'-'.$userp.'-'.$projectid.'-'.$socid.'-'.$mode.'<br>'; + + // List of tasks (does not care about permissions. Filtering will be done later) + $sql = "SELECT "; + if ($filteronprojuser > 0 || $filterontaskuser > 0) $sql.= " DISTINCT"; // We may get several time the same record if user has several roles on same project/task + $sql.= " p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus,"; + $sql.= " t.rowid as taskid, t.ref as taskref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut as status,"; + $sql.= " t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang,"; + $sql.= " s.rowid as thirdparty_id, s.nom as thirdparty_name"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; + if ($mode == 0) + { + if ($filteronprojuser > 0) + { + $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec"; + $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc"; + } + $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + if ($filterontaskuser > 0) + { + $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2"; + $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; + } + $sql.= " WHERE p.entity IN (".getEntity('project').")"; + $sql.= " AND t.fk_projet = p.rowid"; + } + elseif ($mode == 1) + { + if ($filteronprojuser > 0) + { + $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec"; + $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc"; + } + if ($filterontaskuser > 0) + { + $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2"; + $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; + } + else + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; + } + $sql.= " WHERE p.entity IN (".getEntity('project').")"; + } + else return 'BadValueForParameterMode'; + + if ($filteronprojuser > 0) + { + $sql.= " AND p.rowid = ec.element_id"; + $sql.= " AND ctc.rowid = ec.fk_c_type_contact"; + $sql.= " AND ctc.element = 'project'"; + $sql.= " AND ec.fk_socpeople = ".$filteronprojuser; + $sql.= " AND ec.statut = 4"; + $sql.= " AND ctc.source = 'internal'"; + } + if ($filterontaskuser > 0) + { + $sql.= " AND t.fk_projet = p.rowid"; + $sql.= " AND p.rowid = ec2.element_id"; + $sql.= " AND ctc2.rowid = ec2.fk_c_type_contact"; + $sql.= " AND ctc2.element = 'project_task'"; + $sql.= " AND ec2.fk_socpeople = ".$filterontaskuser; + $sql.= " AND ec2.statut = 4"; + $sql.= " AND ctc2.source = 'internal'"; + } + if ($socid) $sql.= " AND p.fk_soc = ".$socid; + if ($projectid) $sql.= " AND p.rowid in (".$projectid.")"; + if ($filteronprojref) $sql.= " AND p.ref LIKE '%".$this->db->escape($filteronprojref)."%'"; + if ($filteronprojstatus > -1) $sql.= " AND p.fk_statut = ".$filteronprojstatus; + if ($morewherefilter) $sql.=$morewherefilter; + $sql.= " ORDER BY p.ref, t.rang, t.dateo"; + + //print $sql;exit; + dol_syslog(get_class($this)."::getTasksArray", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + // Loop on each record found, so each couple (project id, task id) + while ($i < $num) + { + $error=0; + + $obj = $this->db->fetch_object($resql); + + if ((! $obj->public) && (is_object($userp))) // If not public project and we ask a filter on project owned by a user + { + if (! $this->getUserRolesForProjectsOrTasks($userp, 0, $obj->projectid, 0)) + { + $error++; + } + } + if (is_object($usert)) // If we ask a filter on a user affected to a task + { + if (! $this->getUserRolesForProjectsOrTasks(0, $usert, $obj->projectid, $obj->taskid)) + { + $error++; + } + } + + if (! $error) + { + $tasks[$i] = new Task($this->db); + $tasks[$i]->id = $obj->taskid; + $tasks[$i]->ref = $obj->taskref; + $tasks[$i]->fk_project = $obj->projectid; + $tasks[$i]->projectref = $obj->ref; + $tasks[$i]->projectlabel = $obj->plabel; + $tasks[$i]->projectstatus = $obj->projectstatus; + $tasks[$i]->label = $obj->label; + $tasks[$i]->description = $obj->description; + $tasks[$i]->fk_parent = $obj->fk_task_parent; // deprecated + $tasks[$i]->fk_task_parent = $obj->fk_task_parent; + $tasks[$i]->duration = $obj->duration_effective; + $tasks[$i]->planned_workload= $obj->planned_workload; + $tasks[$i]->progress = $obj->progress; + $tasks[$i]->fk_statut = $obj->status; + $tasks[$i]->public = $obj->public; + $tasks[$i]->date_start = $this->db->jdate($obj->date_start); + $tasks[$i]->date_end = $this->db->jdate($obj->date_end); + $tasks[$i]->rang = $obj->rang; + + $tasks[$i]->thirdparty_id = $obj->thirdparty_id; + $tasks[$i]->thirdparty_name = $obj->thirdparty_name; + } + + $i++; + } + $this->db->free($resql); + } + else + { + dol_print_error($this->db); + } + + return $tasks; + } + + /** + * Return list of roles for a user for each projects or each tasks (or a particular project or a particular task). + * + * @param User $userp Return roles on project for this internal user. If set, usert and taskid must not be defined. + * @param User $usert Return roles on task for this internal user. If set userp must NOT be defined. -1 means no filter. + * @param int $projectid Project id list separated with , to filter on project + * @param int $taskid Task id to filter on a task + * @param integer $filteronprojstatus Filter on project status if userp is set. Not used if userp not defined. + * @return array Array (projectid => 'list of roles for project' or taskid => 'list of roles for task') + */ + function getUserRolesForProjectsOrTasks($userp, $usert, $projectid='', $taskid=0, $filteronprojstatus=-1) + { + $arrayroles = array(); + + dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks userp=".is_object($userp)." usert=".is_object($usert)." projectid=".$projectid." taskid=".$taskid); + + // We want role of user for a projet or role of user for a task. Both are not possible. + if (empty($userp) && empty($usert)) { - //Delete associated link file - if ($conf->projet->dir_output) - { - $projectstatic=new Project($this->db); - $projectstatic->fetch($this->fk_project); - - $dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($projectstatic->ref) . '/' . dol_sanitizeFileName($this->id); - dol_syslog(get_class($this)."::delete dir=".$dir, LOG_DEBUG); - if (file_exists($dir)) - { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $res = @dol_delete_dir_recursive($dir); - if (!$res) - { - $this->error = 'ErrorFailToDeleteDir'; - $this->db->rollback(); - return 0; - } - } - } - - $this->db->commit(); - - return 1; - } - } - - /** - * Return nb of children - * - * @return int <0 if KO, 0 if no children, >0 if OK - */ - function hasChildren() - { - $error=0; - $ret=0; - - $sql = "SELECT COUNT(*) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet_task"; - $sql.= " WHERE fk_task_parent=".$this->id; - - dol_syslog(get_class($this)."::hasChildren", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - else - { - $obj=$this->db->fetch_object($resql); - if ($obj) $ret=$obj->nb; - $this->db->free($resql); - } - - if (! $error) - { - return $ret; - } - else - { - return -1; - } - } + $this->error="CallWithWrongParameters"; + return -1; + } + if (! empty($userp) && ! empty($usert)) + { + $this->error="CallWithWrongParameters"; + return -1; + } + + /* Liste des taches et role sur les projets ou taches */ + $sql = "SELECT pt.rowid as pid, ec.element_id, ctc.code, ctc.source"; + if ($userp) $sql.= " FROM ".MAIN_DB_PREFIX."projet as pt"; + if ($usert && $filteronprojstatus > -1) $sql.= " FROM ".MAIN_DB_PREFIX."projet as p, ".MAIN_DB_PREFIX."projet_task as pt"; + if ($usert && $filteronprojstatus <= -1) $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as pt"; + $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec"; + $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc"; + $sql.= " WHERE pt.rowid = ec.element_id"; + if ($userp && $filteronprojstatus > -1) $sql.= " AND pt.fk_statut = ".$filteronprojstatus; + if ($usert && $filteronprojstatus > -1) $sql.= " AND pt.fk_projet = p.rowid AND p.fk_statut = ".$filteronprojstatus; + if ($userp) $sql.= " AND ctc.element = 'project'"; + if ($usert) $sql.= " AND ctc.element = 'project_task'"; + $sql.= " AND ctc.rowid = ec.fk_c_type_contact"; + if ($userp) $sql.= " AND ec.fk_socpeople = ".$userp->id; + if ($usert) $sql.= " AND ec.fk_socpeople = ".$usert->id; + $sql.= " AND ec.statut = 4"; + $sql.= " AND ctc.source = 'internal'"; + if ($projectid) + { + if ($userp) $sql.= " AND pt.rowid in (".$projectid.")"; + if ($usert) $sql.= " AND pt.fk_projet in (".$projectid.")"; + } + if ($taskid) + { + if ($userp) $sql.= " ERROR SHOULD NOT HAPPENS"; + if ($usert) $sql.= " AND pt.rowid = ".$taskid; + } + //print $sql; + + dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks execute request", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + if (empty($arrayroles[$obj->pid])) $arrayroles[$obj->pid] = $obj->code; + else $arrayroles[$obj->pid].=','.$obj->code; + $i++; + } + $this->db->free($resql); + } + else + { + dol_print_error($this->db); + } + + return $arrayroles; + } + /** - * Return nb of time spent - * - * @return int <0 if KO, 0 if no children, >0 if OK - */ - function hasTimeSpent() - { - $error=0; - $ret=0; - - $sql = "SELECT COUNT(*) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time"; - $sql.= " WHERE fk_task=".$this->id; - - dol_syslog(get_class($this)."::hasTimeSpent", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - else - { - $obj=$this->db->fetch_object($resql); - if ($obj) $ret=$obj->nb; - $this->db->free($resql); - } - - if (! $error) - { - return $ret; - } - else - { - return -1; - } - } - - - /** - * Return clicable name (with picto eventually) - * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param string $option 'withproject' or '' - * @param string $mode Mode 'task', 'time', 'contact', 'note', document' define page to link to. - * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string - * @param string $sep Separator between ref and label if option addlabel is set - * @param int $notooltip 1=Disable tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string Chaine avec URL - */ - function getNomUrl($withpicto=0,$option='',$mode='task', $addlabel=0, $sep=' - ', $notooltip=0, $save_lastsearch_value=-1) - { - global $conf, $langs, $user; - - if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips - - $result=''; - $label = '<u>' . $langs->trans("ShowTask") . '</u>'; - if (! empty($this->ref)) - $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; - if (! empty($this->label)) - $label .= '<br><b>' . $langs->trans('LabelTask') . ':</b> ' . $this->label; - if ($this->date_start || $this->date_end) - { - $label .= "<br>".get_date_range($this->date_start,$this->date_end,'',$langs,0); - } - - $url = DOL_URL_ROOT.'/projet/tasks/'.$mode.'.php?id='.$this->id.($option=='withproject'?'&withproject=1':''); - // Add param to save lastsearch_values or not - $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; - if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; - - $linkclose = ''; - if (empty($notooltip)) - { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label=$langs->trans("ShowTask"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip"'; - } - - $linkstart = '<a href="'.$url.'"'; - $linkstart.=$linkclose.'>'; - $linkend='</a>'; - - $picto='projecttask'; - - if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$linkstart.$this->ref.$linkend . (($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); - return $result; - } - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - function initAsSpecimen() - { - $this->id=0; - - $this->fk_projet=''; - $this->ref='TK01'; - $this->fk_task_parent=''; - $this->label='Specimen task TK01'; - $this->duration_effective=''; - $this->fk_user_creat=''; - $this->progress='25'; - $this->fk_statut=''; - $this->note='This is a specimen task not'; - } - - /** - * Return list of tasks for all projects or for one particular project - * Sort order is on project, then on position of task, and last on start date of first level task - * - * @param User $usert Object user to limit tasks affected to a particular user - * @param User $userp Object user to limit projects of a particular user and public projects - * @param int $projectid Project id - * @param int $socid Third party id - * @param int $mode 0=Return list of tasks and their projects, 1=Return projects and tasks if exists - * @param string $filteronprojref Filter on project ref - * @param string $filteronprojstatus Filter on project status - * @param string $morewherefilter Add more filter into where SQL request (must start with ' AND ...') - * @param string $filteronprojuser Filter on user that is a contact of project - * @param string $filterontaskuser Filter on user assigned to task - * @return array Array of tasks - */ - function getTasksArray($usert=0, $userp=0, $projectid=0, $socid=0, $mode=0, $filteronprojref='', $filteronprojstatus=-1, $morewherefilter='',$filteronprojuser=0,$filterontaskuser=0) - { - global $conf; - - $tasks = array(); - - //print $usert.'-'.$userp.'-'.$projectid.'-'.$socid.'-'.$mode.'<br>'; - - // List of tasks (does not care about permissions. Filtering will be done later) - $sql = "SELECT "; - if ($filteronprojuser > 0 || $filterontaskuser > 0) $sql.= " DISTINCT"; // We may get several time the same record if user has several roles on same project/task - $sql.= " p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus,"; - $sql.= " t.rowid as taskid, t.ref as taskref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut as status,"; - $sql.= " t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang,"; - $sql.= " s.rowid as thirdparty_id, s.nom as thirdparty_name"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; - if ($mode == 0) - { - if ($filteronprojuser > 0) - { - $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec"; - $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc"; - } - $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; - if ($filterontaskuser > 0) - { - $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2"; - $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; - } - $sql.= " WHERE p.entity IN (".getEntity('project').")"; - $sql.= " AND t.fk_projet = p.rowid"; - } - elseif ($mode == 1) - { - if ($filteronprojuser > 0) - { - $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec"; - $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc"; - } - if ($filterontaskuser > 0) - { - $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; - $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2"; - $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; - } - else - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; - } - $sql.= " WHERE p.entity IN (".getEntity('project').")"; - } - else return 'BadValueForParameterMode'; - - if ($filteronprojuser > 0) - { - $sql.= " AND p.rowid = ec.element_id"; - $sql.= " AND ctc.rowid = ec.fk_c_type_contact"; - $sql.= " AND ctc.element = 'project'"; - $sql.= " AND ec.fk_socpeople = ".$filteronprojuser; - $sql.= " AND ec.statut = 4"; - $sql.= " AND ctc.source = 'internal'"; - } - if ($filterontaskuser > 0) - { - $sql.= " AND t.fk_projet = p.rowid"; - $sql.= " AND p.rowid = ec2.element_id"; - $sql.= " AND ctc2.rowid = ec2.fk_c_type_contact"; - $sql.= " AND ctc2.element = 'project_task'"; - $sql.= " AND ec2.fk_socpeople = ".$filterontaskuser; - $sql.= " AND ec2.statut = 4"; - $sql.= " AND ctc2.source = 'internal'"; - } - if ($socid) $sql.= " AND p.fk_soc = ".$socid; - if ($projectid) $sql.= " AND p.rowid in (".$projectid.")"; - if ($filteronprojref) $sql.= " AND p.ref LIKE '%".$this->db->escape($filteronprojref)."%'"; - if ($filteronprojstatus > -1) $sql.= " AND p.fk_statut = ".$filteronprojstatus; - if ($morewherefilter) $sql.=$morewherefilter; - $sql.= " ORDER BY p.ref, t.rang, t.dateo"; - - //print $sql;exit; - dol_syslog(get_class($this)."::getTasksArray", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - // Loop on each record found, so each couple (project id, task id) - while ($i < $num) - { - $error=0; - - $obj = $this->db->fetch_object($resql); - - if ((! $obj->public) && (is_object($userp))) // If not public project and we ask a filter on project owned by a user - { - if (! $this->getUserRolesForProjectsOrTasks($userp, 0, $obj->projectid, 0)) - { - $error++; - } - } - if (is_object($usert)) // If we ask a filter on a user affected to a task - { - if (! $this->getUserRolesForProjectsOrTasks(0, $usert, $obj->projectid, $obj->taskid)) - { - $error++; - } - } - - if (! $error) - { - $tasks[$i] = new Task($this->db); - $tasks[$i]->id = $obj->taskid; - $tasks[$i]->ref = $obj->taskref; - $tasks[$i]->fk_project = $obj->projectid; - $tasks[$i]->projectref = $obj->ref; - $tasks[$i]->projectlabel = $obj->plabel; - $tasks[$i]->projectstatus = $obj->projectstatus; - $tasks[$i]->label = $obj->label; - $tasks[$i]->description = $obj->description; - $tasks[$i]->fk_parent = $obj->fk_task_parent; // deprecated - $tasks[$i]->fk_task_parent = $obj->fk_task_parent; - $tasks[$i]->duration = $obj->duration_effective; - $tasks[$i]->planned_workload= $obj->planned_workload; - $tasks[$i]->progress = $obj->progress; - $tasks[$i]->fk_statut = $obj->status; - $tasks[$i]->public = $obj->public; - $tasks[$i]->date_start = $this->db->jdate($obj->date_start); - $tasks[$i]->date_end = $this->db->jdate($obj->date_end); - $tasks[$i]->rang = $obj->rang; - - $tasks[$i]->thirdparty_id = $obj->thirdparty_id; - $tasks[$i]->thirdparty_name = $obj->thirdparty_name; - } - - $i++; - } - $this->db->free($resql); - } - else - { - dol_print_error($this->db); - } - - return $tasks; - } - - /** - * Return list of roles for a user for each projects or each tasks (or a particular project or a particular task). - * - * @param User $userp Return roles on project for this internal user. If set, usert and taskid must not be defined. - * @param User $usert Return roles on task for this internal user. If set userp must NOT be defined. -1 means no filter. - * @param int $projectid Project id list separated with , to filter on project - * @param int $taskid Task id to filter on a task - * @param integer $filteronprojstatus Filter on project status if userp is set. Not used if userp not defined. - * @return array Array (projectid => 'list of roles for project' or taskid => 'list of roles for task') - */ - function getUserRolesForProjectsOrTasks($userp, $usert, $projectid='', $taskid=0, $filteronprojstatus=-1) - { - $arrayroles = array(); - - dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks userp=".is_object($userp)." usert=".is_object($usert)." projectid=".$projectid." taskid=".$taskid); - - // We want role of user for a projet or role of user for a task. Both are not possible. - if (empty($userp) && empty($usert)) - { - $this->error="CallWithWrongParameters"; - return -1; - } - if (! empty($userp) && ! empty($usert)) - { - $this->error="CallWithWrongParameters"; - return -1; - } - - /* Liste des taches et role sur les projets ou taches */ - $sql = "SELECT pt.rowid as pid, ec.element_id, ctc.code, ctc.source"; - if ($userp) $sql.= " FROM ".MAIN_DB_PREFIX."projet as pt"; - if ($usert && $filteronprojstatus > -1) $sql.= " FROM ".MAIN_DB_PREFIX."projet as p, ".MAIN_DB_PREFIX."projet_task as pt"; - if ($usert && $filteronprojstatus <= -1) $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as pt"; - $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec"; - $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc"; - $sql.= " WHERE pt.rowid = ec.element_id"; - if ($userp && $filteronprojstatus > -1) $sql.= " AND pt.fk_statut = ".$filteronprojstatus; - if ($usert && $filteronprojstatus > -1) $sql.= " AND pt.fk_projet = p.rowid AND p.fk_statut = ".$filteronprojstatus; - if ($userp) $sql.= " AND ctc.element = 'project'"; - if ($usert) $sql.= " AND ctc.element = 'project_task'"; - $sql.= " AND ctc.rowid = ec.fk_c_type_contact"; - if ($userp) $sql.= " AND ec.fk_socpeople = ".$userp->id; - if ($usert) $sql.= " AND ec.fk_socpeople = ".$usert->id; - $sql.= " AND ec.statut = 4"; - $sql.= " AND ctc.source = 'internal'"; - if ($projectid) - { - if ($userp) $sql.= " AND pt.rowid in (".$projectid.")"; - if ($usert) $sql.= " AND pt.fk_projet in (".$projectid.")"; - } - if ($taskid) - { - if ($userp) $sql.= " ERROR SHOULD NOT HAPPENS"; - if ($usert) $sql.= " AND pt.rowid = ".$taskid; - } - //print $sql; - - dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks execute request", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - if (empty($arrayroles[$obj->pid])) $arrayroles[$obj->pid] = $obj->code; - else $arrayroles[$obj->pid].=','.$obj->code; - $i++; - } - $this->db->free($resql); - } - else - { - dol_print_error($this->db); - } - - return $arrayroles; - } - - - /** - * Return list of id of contacts of task - * - * @param string $source Source - * @return array Array of id of contacts - */ - function getListContactId($source='internal') - { - $contactAlreadySelected = array(); - $tab = $this->liste_contact(-1,$source); - //var_dump($tab); - $num=count($tab); - $i = 0; - while ($i < $num) - { - if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid']; - else $contactAlreadySelected[$i] = $tab[$i]['id']; - $i++; - } - return $contactAlreadySelected; - } - - - /** - * Add time spent - * - * @param User $user User object - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <=0 if KO, >0 if OK - */ - function addTimeSpent($user, $notrigger=0) - { - global $conf,$langs; - - dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); - - $ret = 0; - - // Check parameters - if (! is_object($user)) - { - dol_print_error('',"Method addTimeSpent was called with wrong parameter user"); - return -1; - } - - // Clean parameters - if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note); + * Return list of id of contacts of task + * + * @param string $source Source + * @return array Array of id of contacts + */ + function getListContactId($source='internal') + { + $contactAlreadySelected = array(); + $tab = $this->liste_contact(-1,$source); + //var_dump($tab); + $num=count($tab); + $i = 0; + while ($i < $num) + { + if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid']; + else $contactAlreadySelected[$i] = $tab[$i]['id']; + $i++; + } + return $contactAlreadySelected; + } + + + /** + * Add time spent + * + * @param User $user User object + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <=0 if KO, >0 if OK + */ + function addTimeSpent($user, $notrigger=0) + { + global $conf,$langs; + + dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); + + $ret = 0; + + // Check parameters + if (! is_object($user)) + { + dol_print_error('',"Method addTimeSpent was called with wrong parameter user"); + return -1; + } + + // Clean parameters + if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note); if (empty($this->timespent_datehour)) $this->timespent_datehour = $this->timespent_date; - $this->db->begin(); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task_time ("; - $sql.= "fk_task"; - $sql.= ", task_date"; - $sql.= ", task_datehour"; - $sql.= ", task_date_withhour"; - $sql.= ", task_duration"; - $sql.= ", fk_user"; - $sql.= ", note"; - $sql.= ") VALUES ("; - $sql.= $this->id; - $sql.= ", '".$this->db->idate($this->timespent_date)."'"; - $sql.= ", '".$this->db->idate($this->timespent_datehour)."'"; - $sql.= ", ".(empty($this->timespent_withhour)?0:1); - $sql.= ", ".$this->timespent_duration; - $sql.= ", ".$this->timespent_fk_user; - $sql.= ", ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null"); - $sql.= ")"; - - $resql=$this->db->query($sql); - if ($resql) - { - $tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_time"); - $ret = $tasktime_id; + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task_time ("; + $sql.= "fk_task"; + $sql.= ", task_date"; + $sql.= ", task_datehour"; + $sql.= ", task_date_withhour"; + $sql.= ", task_duration"; + $sql.= ", fk_user"; + $sql.= ", note"; + $sql.= ") VALUES ("; + $sql.= $this->id; + $sql.= ", '".$this->db->idate($this->timespent_date)."'"; + $sql.= ", '".$this->db->idate($this->timespent_datehour)."'"; + $sql.= ", ".(empty($this->timespent_withhour)?0:1); + $sql.= ", ".$this->timespent_duration; + $sql.= ", ".$this->timespent_fk_user; + $sql.= ", ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null"); + $sql.= ")"; + + $resql=$this->db->query($sql); + if ($resql) + { + $tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_time"); + $ret = $tasktime_id; $this->timespent_id = $ret; - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('TASK_TIMESPENT_CREATE',$user); - if ($result < 0) { $ret=-1; } - // End call triggers - } - } - else - { - $this->error=$this->db->lasterror(); - $ret = -1; - } - - if ($ret > 0) - { - // Recalculate amount of time spent for task and update denormalized field - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; - $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->id.")"; + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('TASK_TIMESPENT_CREATE',$user); + if ($result < 0) { $ret=-1; } + // End call triggers + } + } + else + { + $this->error=$this->db->lasterror(); + $ret = -1; + } + + if ($ret > 0) + { + // Recalculate amount of time spent for task and update denormalized field + $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; + $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->id.")"; if (isset($this->progress)) $sql.= ", progress = " . $this->progress; // Do not overwrite value if not provided - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); - if (! $this->db->query($sql) ) - { - $this->error=$this->db->lasterror(); - $ret = -2; - } - - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time"; - $sql.= " SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->timespent_fk_user.")"; // set average hour rate of user - $sql.= " WHERE rowid = ".$tasktime_id; - - dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); - if (! $this->db->query($sql) ) - { - $this->error=$this->db->lasterror(); - $ret = -2; - } - } - - if ($ret >0) - { - $this->db->commit(); - } - else - { - $this->db->rollback(); - } - return $ret; - } - - /** - * Calculate total of time spent for task - * - * @param int $userid Filter on user id. 0=No filter - * @return array Array of info for task array('min_date', 'max_date', 'total_duration', 'total_amount', 'nblines', 'nblinesnull') - */ - function getSummaryOfTimeSpent($userid=0) - { - global $langs; - - $id=$this->id; - if (empty($id)) - { - dol_syslog("getSummaryOfTimeSpent called on a not loaded task", LOG_ERR); - return -1; - } - - $result=array(); - - $sql = "SELECT"; - $sql.= " MIN(t.task_datehour) as min_date,"; - $sql.= " MAX(t.task_datehour) as max_date,"; - $sql.= " SUM(t.task_duration) as total_duration,"; - $sql.= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as total_amount,"; - $sql.= " COUNT(t.rowid) as nblines,"; - $sql.= " SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; - $sql.= " WHERE t.fk_task = ".$id; - if ($userid > 0) $sql.=" AND t.fk_user = ".$userid; - - dol_syslog(get_class($this)."::getSummaryOfTimeSpent", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - - $result['min_date'] = $obj->min_date; // deprecated. use the ->timespent_xxx instead - $result['max_date'] = $obj->max_date; // deprecated. use the ->timespent_xxx instead - $result['total_duration'] = $obj->total_duration; // deprecated. use the ->timespent_xxx instead - - $this->timespent_min_date=$this->db->jdate($obj->min_date); - $this->timespent_max_date=$this->db->jdate($obj->max_date); - $this->timespent_total_duration=$obj->total_duration; - $this->timespent_total_amount=$obj->total_amount; - $this->timespent_nblinesnull=($obj->nblinesnull?$obj->nblinesnull:0); - $this->timespent_nblines=($obj->nblines?$obj->nblines:0); - - $this->db->free($resql); - } - else - { - dol_print_error($this->db); - } - return $result; - } - - /** - * Calculate quantity and value of time consumed using the thm (hourly amount value of work for user entering time) - * - * @param User $fuser Filter on a dedicated user - * @param string $dates Start date (ex 00:00:00) - * @param string $datee End date (ex 23:59:59) - * @return array Array of info for task array('amount','nbseconds','nblinesnull') - */ - function getSumOfAmount($fuser='', $dates='', $datee='') - { - global $langs; - - if (empty($id)) $id=$this->id; - - $result=array(); - - $sql = "SELECT"; - $sql.= " SUM(t.task_duration) as nbseconds,"; - $sql.= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as amount, SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; - $sql.= " WHERE t.fk_task = ".$id; - if (is_object($fuser) && $fuser->id > 0) - { - $sql.=" AND fk_user = ".$fuser->id; - } - if ($dates > 0) + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); + if (! $this->db->query($sql) ) + { + $this->error=$this->db->lasterror(); + $ret = -2; + } + + $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time"; + $sql.= " SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->timespent_fk_user.")"; // set average hour rate of user + $sql.= " WHERE rowid = ".$tasktime_id; + + dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); + if (! $this->db->query($sql) ) + { + $this->error=$this->db->lasterror(); + $ret = -2; + } + } + + if ($ret >0) + { + $this->db->commit(); + } + else + { + $this->db->rollback(); + } + return $ret; + } + + /** + * Calculate total of time spent for task + * + * @param int $userid Filter on user id. 0=No filter + * @return array Array of info for task array('min_date', 'max_date', 'total_duration', 'total_amount', 'nblines', 'nblinesnull') + */ + function getSummaryOfTimeSpent($userid=0) + { + global $langs; + + $id=$this->id; + if (empty($id)) + { + dol_syslog("getSummaryOfTimeSpent called on a not loaded task", LOG_ERR); + return -1; + } + + $result=array(); + + $sql = "SELECT"; + $sql.= " MIN(t.task_datehour) as min_date,"; + $sql.= " MAX(t.task_datehour) as max_date,"; + $sql.= " SUM(t.task_duration) as total_duration,"; + $sql.= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as total_amount,"; + $sql.= " COUNT(t.rowid) as nblines,"; + $sql.= " SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; + $sql.= " WHERE t.fk_task = ".$id; + if ($userid > 0) $sql.=" AND t.fk_user = ".$userid; + + dol_syslog(get_class($this)."::getSummaryOfTimeSpent", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + + $result['min_date'] = $obj->min_date; // deprecated. use the ->timespent_xxx instead + $result['max_date'] = $obj->max_date; // deprecated. use the ->timespent_xxx instead + $result['total_duration'] = $obj->total_duration; // deprecated. use the ->timespent_xxx instead + + $this->timespent_min_date=$this->db->jdate($obj->min_date); + $this->timespent_max_date=$this->db->jdate($obj->max_date); + $this->timespent_total_duration=$obj->total_duration; + $this->timespent_total_amount=$obj->total_amount; + $this->timespent_nblinesnull=($obj->nblinesnull?$obj->nblinesnull:0); + $this->timespent_nblines=($obj->nblines?$obj->nblines:0); + + $this->db->free($resql); + } + else + { + dol_print_error($this->db); + } + return $result; + } + + /** + * Calculate quantity and value of time consumed using the thm (hourly amount value of work for user entering time) + * + * @param User $fuser Filter on a dedicated user + * @param string $dates Start date (ex 00:00:00) + * @param string $datee End date (ex 23:59:59) + * @return array Array of info for task array('amount','nbseconds','nblinesnull') + */ + function getSumOfAmount($fuser='', $dates='', $datee='') + { + global $langs; + + if (empty($id)) $id=$this->id; + + $result=array(); + + $sql = "SELECT"; + $sql.= " SUM(t.task_duration) as nbseconds,"; + $sql.= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as amount, SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; + $sql.= " WHERE t.fk_task = ".$id; + if (is_object($fuser) && $fuser->id > 0) + { + $sql.=" AND fk_user = ".$fuser->id; + } + if ($dates > 0) { $datefieldname="task_datehour"; $sql.=" AND (".$datefieldname." >= '".$this->db->idate($dates)."' OR ".$datefieldname." IS NULL)"; } - if ($datee > 0) + if ($datee > 0) { $datefieldname="task_datehour"; $sql.=" AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)"; } //print $sql; - dol_syslog(get_class($this)."::getSumOfAmount", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $obj = $this->db->fetch_object($resql); - - $result['amount'] = $obj->amount; - $result['nbseconds'] = $obj->nbseconds; - $result['nblinesnull'] = $obj->nblinesnull; - - $this->db->free($resql); - return $result; - } - else - { - dol_print_error($this->db); - return $result; - } - } - - /** - * Load one record of time spent - * - * @param int $id Id object - * @return int <0 if KO, >0 if OK - */ - function fetchTimeSpent($id) - { - global $langs; - - $sql = "SELECT"; - $sql.= " t.rowid,"; - $sql.= " t.fk_task,"; - $sql.= " t.task_date,"; - $sql.= " t.task_datehour,"; - $sql.= " t.task_date_withhour,"; - $sql.= " t.task_duration,"; - $sql.= " t.fk_user,"; - $sql.= " t.note"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; - $sql.= " WHERE t.rowid = ".$id; - - dol_syslog(get_class($this)."::fetchTimeSpent", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); - - $this->timespent_id = $obj->rowid; - $this->id = $obj->fk_task; - $this->timespent_date = $this->db->jdate($obj->task_date); - $this->timespent_datehour = $this->db->jdate($obj->task_datehour); - $this->timespent_withhour = $obj->task_date_withhour; - $this->timespent_duration = $obj->task_duration; - $this->timespent_fk_user = $obj->fk_user; - $this->timespent_note = $obj->note; - } - - $this->db->free($resql); - - return 1; - } - else - { - $this->error="Error ".$this->db->lasterror(); - return -1; - } - } - - /** - * Update time spent - * - * @param User $user User id - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function updateTimeSpent($user, $notrigger=0) - { - global $conf,$langs; - - $ret = 0; - - // Clean parameters - if (empty($this->timespent_datehour)) $this->timespent_datehour = $this->timespent_date; - if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note); - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time SET"; - $sql.= " task_date = '".$this->db->idate($this->timespent_date)."',"; - $sql.= " task_datehour = '".$this->db->idate($this->timespent_datehour)."',"; - $sql.= " task_date_withhour = ".(empty($this->timespent_withhour)?0:1).","; - $sql.= " task_duration = ".$this->timespent_duration.","; - $sql.= " fk_user = ".$this->timespent_fk_user.","; - $sql.= " note = ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null"); - $sql.= " WHERE rowid = ".$this->timespent_id; - - dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG); - if ($this->db->query($sql) ) - { - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('TASK_TIMESPENT_MODIFY',$user); - if ($result < 0) - { - $this->db->rollback(); - $ret = -1; - } - else $ret = 1; - // End call triggers - } - else $ret = 1; - } - else - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - $ret = -1; - } - - if ($ret == 1 && ($this->timespent_old_duration != $this->timespent_duration)) - { - $newDuration = $this->timespent_duration - $this->timespent_old_duration; - - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; - $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->db->escape($this->id).")"; - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG); - if (! $this->db->query($sql) ) - { - $this->error=$this->db->lasterror(); - $this->db->rollback(); - $ret = -2; - } - } - - if ($ret >= 0) $this->db->commit(); - return $ret; - } - - /** - * Delete time spent - * - * @param User $user User that delete - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function delTimeSpent($user, $notrigger=0) - { - global $conf, $langs; - - $error=0; - - $this->db->begin(); - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time"; - $sql.= " WHERE rowid = ".$this->timespent_id; - - dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - - if (! $error) - { - if (! $notrigger) - { - // Call trigger - $result=$this->call_trigger('TASK_TIMESPENT_DELETE',$user); - if ($result < 0) { $error++; } - // End call triggers - } - } - - if (! $error) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; - $sql.= " SET duration_effective = duration_effective - ".$this->db->escape($this->timespent_duration?$this->timespent_duration:0); - $sql.= " WHERE rowid = ".$this->id; - - dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG); - if ($this->db->query($sql) ) - { - $result = 0; - } - else - { - $this->error=$this->db->lasterror(); - $result = -2; - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::delTimeSpent ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return 1; - } - } - - /** Load an object from its id and create a new one in database + dol_syslog(get_class($this)."::getSumOfAmount", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + + $result['amount'] = $obj->amount; + $result['nbseconds'] = $obj->nbseconds; + $result['nblinesnull'] = $obj->nblinesnull; + + $this->db->free($resql); + return $result; + } + else + { + dol_print_error($this->db); + return $result; + } + } + + /** + * Load one record of time spent + * + * @param int $id Id object + * @return int <0 if KO, >0 if OK + */ + function fetchTimeSpent($id) + { + global $langs; + + $sql = "SELECT"; + $sql.= " t.rowid,"; + $sql.= " t.fk_task,"; + $sql.= " t.task_date,"; + $sql.= " t.task_datehour,"; + $sql.= " t.task_date_withhour,"; + $sql.= " t.task_duration,"; + $sql.= " t.fk_user,"; + $sql.= " t.note"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; + $sql.= " WHERE t.rowid = ".$id; + + dol_syslog(get_class($this)."::fetchTimeSpent", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->timespent_id = $obj->rowid; + $this->id = $obj->fk_task; + $this->timespent_date = $this->db->jdate($obj->task_date); + $this->timespent_datehour = $this->db->jdate($obj->task_datehour); + $this->timespent_withhour = $obj->task_date_withhour; + $this->timespent_duration = $obj->task_duration; + $this->timespent_fk_user = $obj->fk_user; + $this->timespent_note = $obj->note; + } + + $this->db->free($resql); + + return 1; + } + else + { + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + /** + * Update time spent + * + * @param User $user User id + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function updateTimeSpent($user, $notrigger=0) + { + global $conf,$langs; + + $ret = 0; + + // Clean parameters + if (empty($this->timespent_datehour)) $this->timespent_datehour = $this->timespent_date; + if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note); + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time SET"; + $sql.= " task_date = '".$this->db->idate($this->timespent_date)."',"; + $sql.= " task_datehour = '".$this->db->idate($this->timespent_datehour)."',"; + $sql.= " task_date_withhour = ".(empty($this->timespent_withhour)?0:1).","; + $sql.= " task_duration = ".$this->timespent_duration.","; + $sql.= " fk_user = ".$this->timespent_fk_user.","; + $sql.= " note = ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null"); + $sql.= " WHERE rowid = ".$this->timespent_id; + + dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG); + if ($this->db->query($sql) ) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('TASK_TIMESPENT_MODIFY',$user); + if ($result < 0) + { + $this->db->rollback(); + $ret = -1; + } + else $ret = 1; + // End call triggers + } + else $ret = 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + $ret = -1; + } + + if ($ret == 1 && ($this->timespent_old_duration != $this->timespent_duration)) + { + $newDuration = $this->timespent_duration - $this->timespent_old_duration; + + $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; + $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->db->escape($this->id).")"; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG); + if (! $this->db->query($sql) ) + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + $ret = -2; + } + } + + if ($ret >= 0) $this->db->commit(); + return $ret; + } + + /** + * Delete time spent * - * @param int $fromid Id of object to clone - * @param int $project_id Id of project to attach clone task - * @param int $parent_task_id Id of task to attach clone task - * @param bool $clone_change_dt recalculate date of task regarding new project start date - * @param bool $clone_affectation clone affectation of project - * @param bool $clone_time clone time of project - * @param bool $clone_file clone file of project - * @param bool $clone_note clone note of project - * @param bool $clone_prog clone progress of project - * @return int New id of clone + * @param User $user User that delete + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK */ + function delTimeSpent($user, $notrigger=0) + { + global $conf, $langs; + + $error=0; + + $this->db->begin(); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time"; + $sql.= " WHERE rowid = ".$this->timespent_id; + + dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('TASK_TIMESPENT_DELETE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + if (! $error) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; + $sql.= " SET duration_effective = duration_effective - ".$this->db->escape($this->timespent_duration?$this->timespent_duration:0); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG); + if ($this->db->query($sql) ) + { + $result = 0; + } + else + { + $this->error=$this->db->lasterror(); + $result = -2; + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delTimeSpent ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + /** Load an object from its id and create a new one in database + * + * @param int $fromid Id of object to clone + * @param int $project_id Id of project to attach clone task + * @param int $parent_task_id Id of task to attach clone task + * @param bool $clone_change_dt recalculate date of task regarding new project start date + * @param bool $clone_affectation clone affectation of project + * @param bool $clone_time clone time of project + * @param bool $clone_file clone file of project + * @param bool $clone_note clone note of project + * @param bool $clone_prog clone progress of project + * @return int New id of clone + */ function createFromClone($fromid,$project_id,$parent_task_id,$clone_change_dt=false,$clone_affectation=false,$clone_time=false,$clone_file=false,$clone_note=false,$clone_prog=false) { global $user,$langs,$conf; @@ -1389,39 +1389,39 @@ class Task extends CommonObject $clone_task->id = 0; $clone_task->ref = $defaultref; - $clone_task->fk_project = $project_id; - $clone_task->fk_task_parent = $parent_task_id; - $clone_task->date_c = $datec; - $clone_task->planned_workload = $origin_task->planned_workload; + $clone_task->fk_project = $project_id; + $clone_task->fk_task_parent = $parent_task_id; + $clone_task->date_c = $datec; + $clone_task->planned_workload = $origin_task->planned_workload; $clone_task->rang = $origin_task->rang; - //Manage Task Date - if ($clone_change_dt) - { - $projectstatic=new Project($this->db); - $projectstatic->fetch($ori_project_id); + //Manage Task Date + if ($clone_change_dt) + { + $projectstatic=new Project($this->db); + $projectstatic->fetch($ori_project_id); - //Origin project strat date - $orign_project_dt_start = $projectstatic->date_start; + //Origin project strat date + $orign_project_dt_start = $projectstatic->date_start; - //Calcultate new task start date with difference between origin proj start date and origin task start date - if (!empty($clone_task->date_start)) - { + //Calcultate new task start date with difference between origin proj start date and origin task start date + if (!empty($clone_task->date_start)) + { $clone_task->date_start = $now + $clone_task->date_start - $orign_project_dt_start; - } + } - //Calcultate new task end date with difference between origin proj end date and origin task end date - if (!empty($clone_task->date_end)) - { + //Calcultate new task end date with difference between origin proj end date and origin task end date + if (!empty($clone_task->date_end)) + { $clone_task->date_end = $now + $clone_task->date_end - $orign_project_dt_start; - } + } - } + } if (!$clone_prog) - { - $clone_task->progress=0; - } + { + $clone_task->progress=0; + } // Create clone $result=$clone_task->create($user); @@ -1439,15 +1439,15 @@ class Task extends CommonObject $clone_task_id=$clone_task->id; $clone_task_ref = $clone_task->ref; - //Note Update + //Note Update if (!$clone_note) - { - $clone_task->note_private=''; - $clone_task->note_public=''; - } - else - { - $this->db->begin(); + { + $clone_task->note_private=''; + $clone_task->note_public=''; + } + else + { + $this->db->begin(); $res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_public, ENT_QUOTES),'_public'); if ($res < 0) { @@ -1472,7 +1472,7 @@ class Task extends CommonObject { $this->db->commit(); } - } + } //Duplicate file if ($clone_file) @@ -1481,18 +1481,18 @@ class Task extends CommonObject //retreive project origin ref to know folder to copy $projectstatic=new Project($this->db); - $projectstatic->fetch($ori_project_id); - $ori_project_ref=$projectstatic->ref; - - if ($ori_project_id!=$project_id) - { - $projectstatic->fetch($project_id); - $clone_project_ref=$projectstatic->ref; - } - else - { - $clone_project_ref=$ori_project_ref; - } + $projectstatic->fetch($ori_project_id); + $ori_project_ref=$projectstatic->ref; + + if ($ori_project_id!=$project_id) + { + $projectstatic->fetch($project_id); + $clone_project_ref=$projectstatic->ref; + } + else + { + $clone_project_ref=$ori_project_ref; + } $clone_task_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($clone_project_ref). "/" . dol_sanitizeFileName($clone_task_ref); $ori_task_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($ori_project_ref). "/" . dol_sanitizeFileName($fromid); @@ -1659,8 +1659,8 @@ class Task extends CommonObject if ($statut==3) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut4'); if ($statut==4) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6'); if ($statut==5) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5');*/ - //return $this->progress.' %'; - return ' '; + //return $this->progress.' %'; + return ' '; } } @@ -1822,16 +1822,16 @@ class Task extends CommonObject */ public function hasDelay() { - global $conf; + global $conf; - if (! ($this->progress >= 0 && $this->progress < 100)) { - return false; - } + if (! ($this->progress >= 0 && $this->progress < 100)) { + return false; + } - $now = dol_now(); + $now = dol_now(); - $datetouse = ($this->date_end > 0) ? $this->date_end : ($this->datee > 0 ? $this->datee : 0); + $datetouse = ($this->date_end > 0) ? $this->date_end : ($this->datee > 0 ? $this->datee : 0); - return ($datetouse > 0 && ($datetouse < ($now - $conf->projet->task->warning_delay))); + return ($datetouse > 0 && ($datetouse < ($now - $conf->projet->task->warning_delay))); } } \ No newline at end of file diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index ba44629cc215c520452eff6ba8370dc5daac13ce..8eb9ba4b4216a26f20e05f1e62efedb99d509787 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -112,32 +112,32 @@ $fieldstosearchall = array( 'p.ref'=>"Ref", 'p.title'=>"Label", 's.nom'=>"ThirdPartyName", - "p.note_public"=>"NotePublic" + "p.note_public"=>"NotePublic" ); if (empty($user->socid)) $fieldstosearchall["p.note_private"]="NotePrivate"; $arrayfields=array( - 'p.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), - 'p.title'=>array('label'=>$langs->trans("Label"), 'checked'=>1), - 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1, 'enabled'=>$conf->societe->enabled), - 'commercial'=>array('label'=>$langs->trans("SaleRepresentativesOfThirdParty"), 'checked'=>0), + 'p.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), + 'p.title'=>array('label'=>$langs->trans("Label"), 'checked'=>1), + 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1, 'enabled'=>$conf->societe->enabled), + 'commercial'=>array('label'=>$langs->trans("SaleRepresentativesOfThirdParty"), 'checked'=>0), 'p.dateo'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1, 'position'=>100), - 'p.datee'=>array('label'=>$langs->trans("DateEnd"), 'checked'=>1, 'position'=>101), - 'p.public'=>array('label'=>$langs->trans("Visibility"), 'checked'=>1, 'position'=>102), - 'p.opp_amount'=>array('label'=>$langs->trans("OpportunityAmountShort"), 'checked'=>1, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>103), - 'p.fk_opp_status'=>array('label'=>$langs->trans("OpportunityStatusShort"), 'checked'=>1, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>104), - 'p.opp_percent'=>array('label'=>$langs->trans("OpportunityProbabilityShort"), 'checked'=>1, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>105), - 'p.budget_amount'=>array('label'=>$langs->trans("Budget"), 'checked'=>0, 'position'=>110), - 'p.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), - 'p.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - 'p.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), + 'p.datee'=>array('label'=>$langs->trans("DateEnd"), 'checked'=>1, 'position'=>101), + 'p.public'=>array('label'=>$langs->trans("Visibility"), 'checked'=>1, 'position'=>102), + 'p.opp_amount'=>array('label'=>$langs->trans("OpportunityAmountShort"), 'checked'=>1, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>103), + 'p.fk_opp_status'=>array('label'=>$langs->trans("OpportunityStatusShort"), 'checked'=>1, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>104), + 'p.opp_percent'=>array('label'=>$langs->trans("OpportunityProbabilityShort"), 'checked'=>1, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>105), + 'p.budget_amount'=>array('label'=>$langs->trans("Budget"), 'checked'=>0, 'position'=>110), + 'p.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), + 'p.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), + 'p.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), ); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { foreach($extrafields->attribute_label as $key => $val) { - if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -157,44 +157,44 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - // Selection of new fields - include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - - // Purge search criteria - if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers - { - $search_all=''; - $search_categ=''; - $search_ref=""; - $search_label=""; - $search_societe=""; - $search_year=""; - $search_status=-1; - $search_opp_status=-1; - $search_opp_amount=''; - $search_opp_percent=''; - $search_budget_amount=''; - $search_public=""; - $search_sale=""; - $search_project_user=''; - $search_sday=""; - $search_smonth=""; - $search_syear=""; - $search_eday=""; - $search_emonth=""; - $search_eyear=""; - $toselect=''; - $search_array_options=array(); - } - - - // Mass actions - $objectclass='Project'; - $objectlabel='Project'; - $permtoread = $user->rights->projet->lire; - $permtodelete = $user->rights->projet->supprimer; - $uploaddir = $conf->projet->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // Purge search criteria + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_all=''; + $search_categ=''; + $search_ref=""; + $search_label=""; + $search_societe=""; + $search_year=""; + $search_status=-1; + $search_opp_status=-1; + $search_opp_amount=''; + $search_opp_percent=''; + $search_budget_amount=''; + $search_public=""; + $search_sale=""; + $search_project_user=''; + $search_sday=""; + $search_smonth=""; + $search_syear=""; + $search_eday=""; + $search_emonth=""; + $search_eyear=""; + $toselect=''; + $search_array_options=array(); + } + + + // Mass actions + $objectclass='Project'; + $objectlabel='Project'; + $permtoread = $user->rights->projet->lire; + $permtodelete = $user->rights->projet->supprimer; + $uploaddir = $conf->projet->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -223,10 +223,10 @@ $sql.= " AND ctc.source = 'internal'"; $resql = $db->query($sql); if ($resql) { - while($obj = $db->fetch_object($resql)) - { - $listofprojectcontacttype[$obj->rowid]=$obj->code; - } + while($obj = $db->fetch_object($resql)) + { + $listofprojectcontacttype[$obj->rowid]=$obj->code; + } } else dol_print_error($db); if (count($listofprojectcontacttype) == 0) $listofprojectcontacttype[0]='0'; // To avoid sql syntax error if not found @@ -272,42 +272,42 @@ if ($search_opp_amount) $sql .= natural_search('p.opp_amount', $search_opp_amoun if ($search_opp_percent) $sql .= natural_search('p.opp_percent', $search_opp_percent, 1); if ($search_smonth > 0) { - if ($search_syear > 0 && empty($search_sday)) - $sql.= " AND p.dateo BETWEEN '".$db->idate(dol_get_first_day($search_syear,$search_smonth,false))."' AND '".$db->idate(dol_get_last_day($search_syear,$search_smonth,false))."'"; - else if ($search_syear > 0 && ! empty($search_sday)) - $sql.= " AND p.dateo BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_smonth, $search_sday, $search_syear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_smonth, $search_sday, $search_syear))."'"; - else - $sql.= " AND date_format(p.dateo, '%m') = '".$search_smonth."'"; + if ($search_syear > 0 && empty($search_sday)) + $sql.= " AND p.dateo BETWEEN '".$db->idate(dol_get_first_day($search_syear,$search_smonth,false))."' AND '".$db->idate(dol_get_last_day($search_syear,$search_smonth,false))."'"; + else if ($search_syear > 0 && ! empty($search_sday)) + $sql.= " AND p.dateo BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_smonth, $search_sday, $search_syear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_smonth, $search_sday, $search_syear))."'"; + else + $sql.= " AND date_format(p.dateo, '%m') = '".$search_smonth."'"; } else if ($search_syear > 0) { - $sql.= " AND p.dateo BETWEEN '".$db->idate(dol_get_first_day($search_syear,1,false))."' AND '".$db->idate(dol_get_last_day($search_syear,12,false))."'"; + $sql.= " AND p.dateo BETWEEN '".$db->idate(dol_get_first_day($search_syear,1,false))."' AND '".$db->idate(dol_get_last_day($search_syear,12,false))."'"; } if ($search_emonth > 0) { - if ($search_eyear > 0 && empty($search_eday)) - $sql.= " AND p.datee BETWEEN '".$db->idate(dol_get_first_day($search_eyear,$search_emonth,false))."' AND '".$db->idate(dol_get_last_day($search_eyear,$search_emonth,false))."'"; - else if ($search_eyear > 0 && ! empty($search_eday)) - $sql.= " AND p.datee BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_emonth, $search_eday, $search_eyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_emonth, $search_eday, $search_eyear))."'"; - else - $sql.= " AND date_format(p.datee, '%m') = '".$search_emonth."'"; + if ($search_eyear > 0 && empty($search_eday)) + $sql.= " AND p.datee BETWEEN '".$db->idate(dol_get_first_day($search_eyear,$search_emonth,false))."' AND '".$db->idate(dol_get_last_day($search_eyear,$search_emonth,false))."'"; + else if ($search_eyear > 0 && ! empty($search_eday)) + $sql.= " AND p.datee BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_emonth, $search_eday, $search_eyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_emonth, $search_eday, $search_eyear))."'"; + else + $sql.= " AND date_format(p.datee, '%m') = '".$search_emonth."'"; } else if ($search_eyear > 0) { - $sql.= " AND p.datee BETWEEN '".$db->idate(dol_get_first_day($search_eyear,1,false))."' AND '".$db->idate(dol_get_last_day($search_eyear,12,false))."'"; + $sql.= " AND p.datee BETWEEN '".$db->idate(dol_get_first_day($search_eyear,1,false))."' AND '".$db->idate(dol_get_last_day($search_eyear,12,false))."'"; } if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); if ($search_status >= 0) { - if ($search_status == 99) $sql .= " AND p.fk_statut <> 2"; - else $sql .= " AND p.fk_statut = ".$db->escape($search_status); + if ($search_status == 99) $sql .= " AND p.fk_statut <> 2"; + else $sql .= " AND p.fk_statut = ".$db->escape($search_status); } if ($search_opp_status) { - if (is_numeric($search_opp_status) && $search_opp_status > 0) $sql .= " AND p.fk_opp_status = ".$db->escape($search_opp_status); - if ($search_opp_status == 'all') $sql .= " AND p.fk_opp_status IS NOT NULL"; - if ($search_opp_status == 'openedopp') $sql .= " AND p.fk_opp_status IS NOT NULL AND p.fk_opp_status NOT IN (SELECT rowid FROM ".MAIN_DB_PREFIX."c_lead_status WHERE code IN ('WON','LOST'))"; - if ($search_opp_status == 'none') $sql .= " AND p.fk_opp_status IS NULL"; + if (is_numeric($search_opp_status) && $search_opp_status > 0) $sql .= " AND p.fk_opp_status = ".$db->escape($search_opp_status); + if ($search_opp_status == 'all') $sql .= " AND p.fk_opp_status IS NOT NULL"; + if ($search_opp_status == 'openedopp') $sql .= " AND p.fk_opp_status IS NOT NULL AND p.fk_opp_status NOT IN (SELECT rowid FROM ".MAIN_DB_PREFIX."c_lead_status WHERE code IN ('WON','LOST'))"; + if ($search_opp_status == 'none') $sql .= " AND p.fk_opp_status IS NULL"; } if ($search_public!='') $sql .= " AND p.public = ".$db->escape($search_public); if ($search_sale > 0) $sql.= " AND sc.fk_user = " .$search_sale; @@ -319,16 +319,16 @@ if ($search_budget_amount != '') $sql .= natural_search('p.budget_amount', $sear // Add where from extra fields foreach ($search_array_options as $key => $val) { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode=0; - if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric - if (in_array($typ, array('sellist')) && $crit != '0' && $crit != '-1') $mode=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); - } + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode=0; + if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric + if (in_array($typ, array('sellist')) && $crit != '0' && $crit != '-1') $mode=2; // Search on a foreign key int + if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0')) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); + } } // Add where from hooks $parameters=array(); @@ -339,8 +339,8 @@ $sql.= $db->order($sortfield,$sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); } $sql.= $db->plimit($limit + 1,$offset); @@ -351,8 +351,8 @@ dol_syslog("list allowed project", LOG_DEBUG); $resql = $db->query($sql); if (! $resql) { - dol_print_error($db); - exit; + dol_print_error($db); + exit; } $num = $db->num_rows($resql); @@ -361,9 +361,9 @@ $arrayofselected=is_array($toselect)?$toselect:array(); if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) { - $obj = $db->fetch_object($resql); - header("Location: ".DOL_URL_ROOT.'/projet/card.php?id='.$obj->id); - exit; + $obj = $db->fetch_object($resql); + header("Location: ".DOL_URL_ROOT.'/projet/card.php?id='.$obj->id); + exit; } $help_url="EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; @@ -395,9 +395,9 @@ if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields foreach ($search_array_options as $key => $val) { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); } // List of mass actions available @@ -433,8 +433,8 @@ else if ($search_all) { - foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); - print $langs->trans("FilterOnInto", $search_all) . join(', ',$fieldstosearchall); + foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); + print $langs->trans("FilterOnInto", $search_all) . join(', ',$fieldstosearchall); } $moreforfilter=''; @@ -442,11 +442,11 @@ $moreforfilter=''; // Filter on categories if (! empty($conf->categorie->enabled)) { - require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; - $moreforfilter.='<div class="divsearchfield">'; - $moreforfilter.=$langs->trans('ProjectCategories'). ': '; - $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300'); - $moreforfilter.='</div>'; + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $moreforfilter.='<div class="divsearchfield">'; + $moreforfilter.=$langs->trans('ProjectCategories'). ': '; + $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300'); + $moreforfilter.='</div>'; } // If the user can view user other than himself @@ -536,14 +536,14 @@ if (! empty($arrayfields['p.public']['checked'])) { print '<td class="liste_titre">'; $array=array(''=>'',0 => $langs->trans("PrivateProject"),1 => $langs->trans("SharedProject")); - print $form->selectarray('search_public',$array,$search_public); - print '</td>'; + print $form->selectarray('search_public',$array,$search_public); + print '</td>'; } if (! empty($arrayfields['p.fk_opp_status']['checked'])) { print '<td class="liste_titre nowrap center">'; print $formproject->selectOpportunityStatus('search_opp_status', $search_opp_status, 1, 1, 1, 0, 'maxwidth100'); - print '</td>'; + print '</td>'; } if (! empty($arrayfields['p.opp_amount']['checked'])) { @@ -561,30 +561,30 @@ if (! empty($arrayfields['p.budget_amount']['checked'])) { print '<td class="liste_titre nowrap" align="right">'; print '<input type="text" class="flat" name="search_budget_amount" size="4" value="'.$search_budget_amount.'">'; - print '</td>'; + print '</td>'; } // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print '<td class="liste_titre'.($align?' '.$align:'').'">'; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')) && empty($extrafields->attribute_computed[$key])) + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print '<td class="liste_titre'.($align?' '.$align:'').'">'; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')) && empty($extrafields->attribute_computed[$key])) { - $crit=$val; + $crit=$val; $tmpkey=preg_replace('/search_options_/','',$key); $searchclass=''; if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; print '<input class="flat'.($searchclass?' '.$searchclass:'').'" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">'; } - print '</td>'; - } - } + print '</td>'; + } + } } // Fields from hook $parameters=array('arrayfields'=>$arrayfields); @@ -592,24 +592,24 @@ $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // N print $hookmanager->resPrint; if (! empty($arrayfields['p.datec']['checked'])) { - // Date creation - print '<td class="liste_titre">'; - print '</td>'; + // Date creation + print '<td class="liste_titre">'; + print '</td>'; } if (! empty($arrayfields['p.tms']['checked'])) { - // Date modification - print '<td class="liste_titre">'; - print '</td>'; + // Date modification + print '<td class="liste_titre">'; + print '</td>'; } if (! empty($arrayfields['p.fk_statut']['checked'])) { print '<td class="liste_titre nowrap" align="right">'; - $arrayofstatus = array(); - foreach($object->statuts_short as $key => $val) $arrayofstatus[$key]=$langs->trans($val); - $arrayofstatus['99']=$langs->trans("NotClosed").' ('.$langs->trans('Draft').'+'.$langs->trans('Opened').')'; + $arrayofstatus = array(); + foreach($object->statuts_short as $key => $val) $arrayofstatus[$key]=$langs->trans($val); + $arrayofstatus['99']=$langs->trans("NotClosed").' ('.$langs->trans('Draft').'+'.$langs->trans('Opened').')'; print $form->selectarray('search_status', $arrayofstatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); - print '</td>'; + print '</td>'; } // Action column print '<td class="liste_titre" align="right">'; @@ -634,16 +634,16 @@ if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $sortonfield = "ef.".$key; + if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } } // Hook fields $parameters=array('arrayfields'=>$arrayfields); @@ -675,168 +675,168 @@ while ($i < min($num,$limit)) print '<tr class="oddeven">'; // Project url - if (! empty($arrayfields['p.ref']['checked'])) - { - print '<td class="nowrap">'; - print $object->getNomUrl(1); - if ($object->hasDelay()) print img_warning($langs->trans('Late')); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + if (! empty($arrayfields['p.ref']['checked'])) + { + print '<td class="nowrap">'; + print $object->getNomUrl(1); + if ($object->hasDelay()) print img_warning($langs->trans('Late')); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } // Title - if (! empty($arrayfields['p.title']['checked'])) - { - print '<td class="tdoverflowmax100">'; - print dol_trunc($obj->title,80); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + if (! empty($arrayfields['p.title']['checked'])) + { + print '<td class="tdoverflowmax100">'; + print dol_trunc($obj->title,80); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } // Company - if (! empty($arrayfields['s.nom']['checked'])) - { - print '<td class="tdoverflowmax100">'; - if ($obj->socid) - { - $socstatic->id=$obj->socid; - $socstatic->name=$obj->name; - print $socstatic->getNomUrl(1); - } - else - { - print ' '; - } - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + if (! empty($arrayfields['s.nom']['checked'])) + { + print '<td class="tdoverflowmax100">'; + if ($obj->socid) + { + $socstatic->id=$obj->socid; + $socstatic->name=$obj->name; + print $socstatic->getNomUrl(1); + } + else + { + print ' '; + } + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } // Sales Representatives - if (! empty($arrayfields['commercial']['checked'])) - { - print '<td>'; - if ($obj->socid) - { - $socstatic->id=$obj->socid; - $socstatic->name=$obj->name; - $listsalesrepresentatives=$socstatic->getSalesRepresentatives($user); - $nbofsalesrepresentative=count($listsalesrepresentatives); - if ($nbofsalesrepresentative > 3) // We print only number - { - print '<a href="'.DOL_URL_ROOT.'/societe/commerciaux.php?socid='.$socstatic->id.'">'; - print $nbofsalesrepresentative; - print '</a>'; - } - else if ($nbofsalesrepresentative > 0) - { - $userstatic=new User($db); - $j=0; - foreach($listsalesrepresentatives as $val) - { - $userstatic->id=$val['id']; - $userstatic->lastname=$val['lastname']; - $userstatic->firstname=$val['firstname']; - $userstatic->email=$val['email']; - $userstatic->statut=$val['statut']; - $userstatic->entity=$val['entity']; - $userstatic->photo=$val['photo']; - //print $userstatic->getNomUrl(1, '', 0, 0, 12); - print $userstatic->getNomUrl(-2); - $j++; - if ($j < $nbofsalesrepresentative) print ' '; - } - } - //else print $langs->trans("NoSalesRepresentativeAffected"); - } - else - { - print ' '; - } - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + if (! empty($arrayfields['commercial']['checked'])) + { + print '<td>'; + if ($obj->socid) + { + $socstatic->id=$obj->socid; + $socstatic->name=$obj->name; + $listsalesrepresentatives=$socstatic->getSalesRepresentatives($user); + $nbofsalesrepresentative=count($listsalesrepresentatives); + if ($nbofsalesrepresentative > 3) // We print only number + { + print '<a href="'.DOL_URL_ROOT.'/societe/commerciaux.php?socid='.$socstatic->id.'">'; + print $nbofsalesrepresentative; + print '</a>'; + } + else if ($nbofsalesrepresentative > 0) + { + $userstatic=new User($db); + $j=0; + foreach($listsalesrepresentatives as $val) + { + $userstatic->id=$val['id']; + $userstatic->lastname=$val['lastname']; + $userstatic->firstname=$val['firstname']; + $userstatic->email=$val['email']; + $userstatic->statut=$val['statut']; + $userstatic->entity=$val['entity']; + $userstatic->photo=$val['photo']; + //print $userstatic->getNomUrl(1, '', 0, 0, 12); + print $userstatic->getNomUrl(-2); + $j++; + if ($j < $nbofsalesrepresentative) print ' '; + } + } + //else print $langs->trans("NoSalesRepresentativeAffected"); + } + else + { + print ' '; + } + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } // Date start - if (! empty($arrayfields['p.dateo']['checked'])) - { + if (! empty($arrayfields['p.dateo']['checked'])) + { print '<td class="center">'; - print dol_print_date($db->jdate($obj->date_start),'day'); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + print dol_print_date($db->jdate($obj->date_start),'day'); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } // Date end - if (! empty($arrayfields['p.datee']['checked'])) - { + if (! empty($arrayfields['p.datee']['checked'])) + { print '<td class="center">'; - print dol_print_date($db->jdate($obj->date_end),'day'); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } + print dol_print_date($db->jdate($obj->date_end),'day'); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } // Visibility - if (! empty($arrayfields['p.public']['checked'])) - { - print '<td align="left">'; - if ($obj->public) print $langs->trans('SharedProject'); - else print $langs->trans('PrivateProject'); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // Opp Status - if (! empty($arrayfields['p.fk_opp_status']['checked'])) - { - print '<td class="center">'; + if (! empty($arrayfields['p.public']['checked'])) + { + print '<td align="left">'; + if ($obj->public) print $langs->trans('SharedProject'); + else print $langs->trans('PrivateProject'); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + // Opp Status + if (! empty($arrayfields['p.fk_opp_status']['checked'])) + { + print '<td class="center">'; if ($obj->opp_status_code) print $langs->trans("OppStatusShort".$obj->opp_status_code); print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // Opp Amount - if (! empty($arrayfields['p.opp_amount']['checked'])) - { + if (! $i) $totalarray['nbfield']++; + } + // Opp Amount + if (! empty($arrayfields['p.opp_amount']['checked'])) + { print '<td align="right">'; //if ($obj->opp_status_code) if (strcmp($obj->opp_amount,'')) { - print price($obj->opp_amount, 1, $langs, 1, -1, -1, ''); - $totalarray['totalopp'] += $obj->opp_amount; + print price($obj->opp_amount, 1, $langs, 1, -1, -1, ''); + $totalarray['totalopp'] += $obj->opp_amount; } print '</td>'; if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totaloppfield']=$totalarray['nbfield']; - } - // Opp percent - if (! empty($arrayfields['p.opp_percent']['checked'])) - { + } + // Opp percent + if (! empty($arrayfields['p.opp_percent']['checked'])) + { print '<td align="right">'; if ($obj->opp_percent) print price($obj->opp_percent, 1, $langs, 1, 0).'%'; print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - // Budget - if (! empty($arrayfields['p.budget_amount']['checked'])) - { + if (! $i) $totalarray['nbfield']++; + } + // Budget + if (! empty($arrayfields['p.budget_amount']['checked'])) + { print '<td align="right">'; if ($obj->budget_amount != '') { - print price($obj->budget_amount, 1, $langs, 1, -1, -1); - $totalarray['totalbudget'] += $obj->budget_amount; + print price($obj->budget_amount, 1, $langs, 1, -1, -1); + $totalarray['totalbudget'] += $obj->budget_amount; } print '</td>'; if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totalbudgetfield']=$totalarray['nbfield']; - } + } // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print '<td'; - $align=$extrafields->getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print '</td>'; - if (! $i) $totalarray['nbfield']++; - } - } + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print '<td'; + $align=$extrafields->getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print '</td>'; + if (! $i) $totalarray['nbfield']++; + } + } } // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); @@ -845,34 +845,34 @@ while ($i < min($num,$limit)) // Date creation if (! empty($arrayfields['p.datec']['checked'])) { - print '<td align="center">'; - print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); - print '</td>'; + print '<td align="center">'; + print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); + print '</td>'; if (! $i) $totalarray['nbfield']++; } // Date modification if (! empty($arrayfields['p.tms']['checked'])) { - print '<td align="center">'; - print dol_print_date($db->jdate($obj->date_update), 'dayhour'); - print '</td>'; + print '<td align="center">'; + print dol_print_date($db->jdate($obj->date_update), 'dayhour'); + print '</td>'; if (! $i) $totalarray['nbfield']++; } // Status if (! empty($arrayfields['p.fk_statut']['checked'])) { - print '<td align="right">'.$object->getLibStatut(5).'</td>'; + print '<td align="right">'.$object->getLibStatut(5).'</td>'; if (! $i) $totalarray['nbfield']++; } - // Action column - print '<td class="nowrap" align="center">'; - if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - { - $selected=0; - if (in_array($obj->id, $arrayofselected)) $selected=1; - print '<input id="cb'.$obj->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->id.'"'.($selected?' checked="checked"':'').'>'; - } - print '</td>'; + // Action column + print '<td class="nowrap" align="center">'; + if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected=0; + if (in_array($obj->id, $arrayofselected)) $selected=1; + print '<input id="cb'.$obj->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->id.'"'.($selected?' checked="checked"':'').'>'; + } + print '</td>'; if (! $i) $totalarray['nbfield']++; print "</tr>\n"; @@ -885,21 +885,21 @@ while ($i < min($num,$limit)) // Show total line if (isset($totalarray['totaloppfield']) || isset($totalarray['totalbudgetfield'])) { - print '<tr class="liste_total">'; - $i=0; - while ($i < $totalarray['nbfield']) - { - $i++; - if ($i == 1) - { - if ($num < $limit && empty($offset)) print '<td align="left">'.$langs->trans("Total").'</td>'; - else print '<td align="left">'.$langs->trans("Totalforthispage").'</td>'; - } - elseif ($totalarray['totaloppfield'] == $i) print '<td align="right">'.price($totalarray['totalopp'], 1, $langs, 1, -1, -1).'</td>'; - elseif ($totalarray['totalbudgetfield'] == $i) print '<td align="right">'.price($totalarray['totalbudget'], 1, $langs, 1, -1, -1).'</td>'; - else print '<td></td>'; - } - print '</tr>'; + print '<tr class="liste_total">'; + $i=0; + while ($i < $totalarray['nbfield']) + { + $i++; + if ($i == 1) + { + if ($num < $limit && empty($offset)) print '<td align="left">'.$langs->trans("Total").'</td>'; + else print '<td align="left">'.$langs->trans("Totalforthispage").'</td>'; + } + elseif ($totalarray['totaloppfield'] == $i) print '<td align="right">'.price($totalarray['totalopp'], 1, $langs, 1, -1, -1).'</td>'; + elseif ($totalarray['totalbudgetfield'] == $i) print '<td align="right">'.price($totalarray['totalbudget'], 1, $langs, 1, -1, -1).'</td>'; + else print '<td></td>'; + } + print '</tr>'; } $db->free($resql); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 407bbc99b87f482a2e0c0a6aae8a834b777c8a24..8df7d34cc16ad3cf42ca205f90670e57ce5480ae 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -115,11 +115,11 @@ if (! isset($conf->global->THEME_ELDY_TEXTLINK)) $conf->global->THEME_ELDY_TEXTL // Case of option editable only if option THEME_ELDY_ENABLE_PERSONALIZED is on if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) { - $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255'; // card - $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234'; - $conf->global->THEME_ELDY_TEXT='0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1='13'; - $conf->global->THEME_ELDY_FONT_SIZE2='12'; + $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255'; // card + $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234'; + $conf->global->THEME_ELDY_TEXT='0,0,0'; + $conf->global->THEME_ELDY_FONT_SIZE1='13'; + $conf->global->THEME_ELDY_FONT_SIZE2='12'; } // Case of option availables only if THEME_ELDY_ENABLE_PERSONALIZED is on @@ -145,7 +145,7 @@ $fontsizesmaller =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty( $colorbacklinepairhover=((! isset($conf->global->THEME_ELDY_USE_HOVER) || (string) $conf->global->THEME_ELDY_USE_HOVER === '0')?'':($conf->global->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$conf->global->THEME_ELDY_USE_HOVER)); if (! empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)) { - $colorbacklinepairhover=((! isset($user->conf->THEME_ELDY_USE_HOVER) || $user->conf->THEME_ELDY_USE_HOVER === '0')?'':($user->conf->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$user->conf->THEME_ELDY_USE_HOVER)); + $colorbacklinepairhover=((! isset($user->conf->THEME_ELDY_USE_HOVER) || $user->conf->THEME_ELDY_USE_HOVER === '0')?'':($user->conf->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$user->conf->THEME_ELDY_USE_HOVER)); } //$colortopbordertitle1=$colorbackhmenu1; @@ -167,9 +167,9 @@ $colorbacktitle1=join(',',colorStringToArray($colorbacktitle1)); // Normalize $tmppart=explode(',',$colorbacktitle1); if ($colortexttitle == '') { - $tmpval=(! empty($tmppart[0]) ? $tmppart[0] : 0)+(! empty($tmppart[1]) ? $tmppart[1] : 0)+(! empty($tmppart[2]) ? $tmppart[2] : 0); - if ($tmpval <= 460) { $colortexttitle='FFFFFF'; $colorshadowtitle='888888'; } - else { $colortexttitle='000000'; $colorshadowtitle='FFFFFF'; } + $tmpval=(! empty($tmppart[0]) ? $tmppart[0] : 0)+(! empty($tmppart[1]) ? $tmppart[1] : 0)+(! empty($tmppart[2]) ? $tmppart[2] : 0); + if ($tmpval <= 460) { $colortexttitle='FFFFFF'; $colorshadowtitle='888888'; } + else { $colortexttitle='000000'; $colorshadowtitle='FFFFFF'; } } $colorbacktabcard1=join(',',colorStringToArray($colorbacktabcard1)); // Normalize value to 'x,y,z' diff --git a/htdocs/user/card.php b/htdocs/user/card.php index ed2ae731fd32ca0987ea6deef4e3e914ee32ddfa..a2560d7d6c386a5c2580ed2f34903ac09f5f758b 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -71,17 +71,17 @@ $canreadgroup=$canreaduser; $caneditgroup=$canedituser; if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup=(! empty($user->admin) || $user->rights->user->group_advance->read); - $caneditgroup=(! empty($user->admin) || $user->rights->user->group_advance->write); + $canreadgroup=(! empty($user->admin) || $user->rights->user->group_advance->read); + $caneditgroup=(! empty($user->admin) || $user->rights->user->group_advance->write); } // Define value to know what current user can do on properties of edited user if ($id) { - // $user est le user qui edite, $id est l'id de l'utilisateur edite - $caneditfield=((($user->id == $id) && $user->rights->user->self->creer) - || (($user->id != $id) && $user->rights->user->user->creer)); - $caneditpassword=((($user->id == $id) && $user->rights->user->self->password) - || (($user->id != $id) && $user->rights->user->user->password)); + // $user est le user qui edite, $id est l'id de l'utilisateur edite + $caneditfield=((($user->id == $id) && $user->rights->user->self->creer) + || (($user->id != $id) && $user->rights->user->user->creer)); + $caneditpassword=((($user->id == $id) && $user->rights->user->self->password) + || (($user->id != $id) && $user->rights->user->user->password)); } // Security check @@ -215,7 +215,7 @@ if (empty($reshook)) { $object->note = GETPOST("note"); $object->ldap_sid = GETPOST("ldap_sid"); $object->fk_user = GETPOST("fk_user") > 0 ? GETPOST("fk_user") : 0; - $object->employee = GETPOST('employee'); + $object->employee = GETPOST('employee'); $object->thm = GETPOST("thm") != '' ? GETPOST("thm") : ''; $object->tjm = GETPOST("tjm") != '' ? GETPOST("tjm") : ''; @@ -247,7 +247,7 @@ if (empty($reshook)) { } } else { $object->entity = ($entity == '' ? 1 : $entity); - /*if ($user->admin && $user->entity == 0 && GETPOST("admin",'alpha')) + /*if ($user->admin && $user->entity == 0 && GETPOST("admin",'alpha')) { }*/ } @@ -259,7 +259,7 @@ if (empty($reshook)) { if (GETPOST('password')) { $object->setPassword($user, GETPOST('password')); } - if (! empty($conf->categorie->enabled)) { + if (! empty($conf->categorie->enabled)) { // Categories association $usercats = GETPOST('usercats', 'array'); $object->setCategories($usercats); @@ -467,8 +467,8 @@ if (empty($reshook)) { if (!$result > 0) { setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors'); } else { - // Create thumbs - $object->addThumbs($newfile); + // Create thumbs + $object->addThumbs($newfile); } } else { $error ++; @@ -478,12 +478,12 @@ if (empty($reshook)) { } } - if (! $error && ! count($object->errors)) - { - // Then we add the associated categories - $categories = GETPOST('usercats', 'array'); - $object->setCategories($categories); - } + if (! $error && ! count($object->errors)) + { + // Then we add the associated categories + $categories = GETPOST('usercats', 'array'); + $object->setCategories($categories); + } if (!$error && !count($object->errors)) { setEventMessages($langs->trans("UserModified"), null, 'mesgs'); @@ -498,123 +498,123 @@ if (empty($reshook)) { } } else { - $db->rollback(); + $db->rollback(); } - } - } + } + } else { - if ($caneditpassword) // Case we can edit only password - { - dol_syslog("Not allowed to change fields, only password"); + if ($caneditpassword) // Case we can edit only password + { + dol_syslog("Not allowed to change fields, only password"); - $object->fetch($id); + $object->fetch($id); - $object->oldcopy = clone $object; + $object->oldcopy = clone $object; - $ret = $object->setPassword($user, GETPOST("password")); - if ($ret < 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - } - } + $ret = $object->setPassword($user, GETPOST("password")); + if ($ret < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } } } // Change password with a new generated one - if ((($action == 'confirm_password' && $confirm == 'yes') - || ($action == 'confirm_passwordsend' && $confirm == 'yes')) && $caneditpassword - ) { - $object->fetch($id); - - $newpassword = $object->setPassword($user, ''); - if ($newpassword < 0) { - // Echec - setEventMessages($langs->trans("ErrorFailedToSetNewPassword"), null, 'errors'); - } else { - // Succes - if ($action == 'confirm_passwordsend' && $confirm == 'yes') { - if ($object->send_password($user, $newpassword) > 0) - { - setEventMessages($langs->trans("PasswordChangedAndSentTo", $object->email), null, 'mesgs'); - } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - } - } - else - { - setEventMessages($langs->trans("PasswordChangedTo", $newpassword), null, 'warnings'); - } - } - } + if ((($action == 'confirm_password' && $confirm == 'yes') + || ($action == 'confirm_passwordsend' && $confirm == 'yes')) && $caneditpassword + ) { + $object->fetch($id); + + $newpassword = $object->setPassword($user, ''); + if ($newpassword < 0) { + // Echec + setEventMessages($langs->trans("ErrorFailedToSetNewPassword"), null, 'errors'); + } else { + // Succes + if ($action == 'confirm_passwordsend' && $confirm == 'yes') { + if ($object->send_password($user, $newpassword) > 0) + { + setEventMessages($langs->trans("PasswordChangedAndSentTo", $object->email), null, 'mesgs'); + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + else + { + setEventMessages($langs->trans("PasswordChangedTo", $newpassword), null, 'warnings'); + } + } + } // Action initialisation donnees depuis record LDAP - if ($action == 'adduserldap') { - $selecteduser = $_POST['users']; - - $required_fields = array( - $conf->global->LDAP_KEY_USERS, - $conf->global->LDAP_FIELD_NAME, - $conf->global->LDAP_FIELD_FIRSTNAME, - $conf->global->LDAP_FIELD_LOGIN, - $conf->global->LDAP_FIELD_LOGIN_SAMBA, - $conf->global->LDAP_FIELD_PASSWORD, - $conf->global->LDAP_FIELD_PASSWORD_CRYPTED, - $conf->global->LDAP_FIELD_PHONE, - $conf->global->LDAP_FIELD_FAX, - $conf->global->LDAP_FIELD_MOBILE, - $conf->global->LDAP_FIELD_SKYPE, - $conf->global->LDAP_FIELD_MAIL, - $conf->global->LDAP_FIELD_TITLE, - $conf->global->LDAP_FIELD_DESCRIPTION, - $conf->global->LDAP_FIELD_SID - ); - - $ldap = new Ldap(); - $result = $ldap->connect_bind(); - if ($result >= 0) { - // Remove from required_fields all entries not configured in LDAP (empty) and duplicated - $required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement"))); - - $ldapusers = $ldap->getRecords($selecteduser, $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields); - //print_r($ldapusers); - - if (is_array($ldapusers)) { - foreach ($ldapusers as $key => $attribute) { - $ldap_lastname = $attribute[$conf->global->LDAP_FIELD_NAME]; - $ldap_firstname = $attribute[$conf->global->LDAP_FIELD_FIRSTNAME]; - $ldap_login = $attribute[$conf->global->LDAP_FIELD_LOGIN]; - $ldap_loginsmb = $attribute[$conf->global->LDAP_FIELD_LOGIN_SAMBA]; - $ldap_pass = $attribute[$conf->global->LDAP_FIELD_PASSWORD]; - $ldap_pass_crypted = $attribute[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED]; - $ldap_phone = $attribute[$conf->global->LDAP_FIELD_PHONE]; - $ldap_fax = $attribute[$conf->global->LDAP_FIELD_FAX]; - $ldap_mobile = $attribute[$conf->global->LDAP_FIELD_MOBILE]; - $ldap_skype = $attribute[$conf->global->LDAP_FIELD_SKYPE]; - $ldap_mail = $attribute[$conf->global->LDAP_FIELD_MAIL]; - $ldap_sid = $attribute[$conf->global->LDAP_FIELD_SID]; - } - } - } - else - { - setEventMessages($ldap->error, $ldap->errors, 'errors'); - } - } - - // Actions to send emails - $trigger_name='USER_SENTBYMAIL'; - $paramname='id'; // Name of param key to open the card - $mode='emailfromuser'; - $trackid='use'.$object->id; - include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - - // Actions to build doc - $upload_dir = $conf->user->dir_output; - $permissioncreate=$user->rights->user->user->creer; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + if ($action == 'adduserldap') { + $selecteduser = $_POST['users']; + + $required_fields = array( + $conf->global->LDAP_KEY_USERS, + $conf->global->LDAP_FIELD_NAME, + $conf->global->LDAP_FIELD_FIRSTNAME, + $conf->global->LDAP_FIELD_LOGIN, + $conf->global->LDAP_FIELD_LOGIN_SAMBA, + $conf->global->LDAP_FIELD_PASSWORD, + $conf->global->LDAP_FIELD_PASSWORD_CRYPTED, + $conf->global->LDAP_FIELD_PHONE, + $conf->global->LDAP_FIELD_FAX, + $conf->global->LDAP_FIELD_MOBILE, + $conf->global->LDAP_FIELD_SKYPE, + $conf->global->LDAP_FIELD_MAIL, + $conf->global->LDAP_FIELD_TITLE, + $conf->global->LDAP_FIELD_DESCRIPTION, + $conf->global->LDAP_FIELD_SID + ); + + $ldap = new Ldap(); + $result = $ldap->connect_bind(); + if ($result >= 0) { + // Remove from required_fields all entries not configured in LDAP (empty) and duplicated + $required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement"))); + + $ldapusers = $ldap->getRecords($selecteduser, $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields); + //print_r($ldapusers); + + if (is_array($ldapusers)) { + foreach ($ldapusers as $key => $attribute) { + $ldap_lastname = $attribute[$conf->global->LDAP_FIELD_NAME]; + $ldap_firstname = $attribute[$conf->global->LDAP_FIELD_FIRSTNAME]; + $ldap_login = $attribute[$conf->global->LDAP_FIELD_LOGIN]; + $ldap_loginsmb = $attribute[$conf->global->LDAP_FIELD_LOGIN_SAMBA]; + $ldap_pass = $attribute[$conf->global->LDAP_FIELD_PASSWORD]; + $ldap_pass_crypted = $attribute[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED]; + $ldap_phone = $attribute[$conf->global->LDAP_FIELD_PHONE]; + $ldap_fax = $attribute[$conf->global->LDAP_FIELD_FAX]; + $ldap_mobile = $attribute[$conf->global->LDAP_FIELD_MOBILE]; + $ldap_skype = $attribute[$conf->global->LDAP_FIELD_SKYPE]; + $ldap_mail = $attribute[$conf->global->LDAP_FIELD_MAIL]; + $ldap_sid = $attribute[$conf->global->LDAP_FIELD_SID]; + } + } + } + else + { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + } + + // Actions to send emails + $trigger_name='USER_SENTBYMAIL'; + $paramname='id'; // Name of param key to open the card + $mode='emailfromuser'; + $trackid='use'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + // Actions to build doc + $upload_dir = $conf->user->dir_output; + $permissioncreate=$user->rights->user->user->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -631,32 +631,32 @@ llxHeader('',$langs->trans("UserCard")); if ($action == 'create' || $action == 'adduserldap') { - /* ************************************************************************** */ - /* */ - /* Affichage fiche en mode creation */ - /* */ - /* ************************************************************************** */ + /* ************************************************************************** */ + /* */ + /* Affichage fiche en mode creation */ + /* */ + /* ************************************************************************** */ - print load_fiche_titre($langs->trans("NewUser")); + print load_fiche_titre($langs->trans("NewUser")); - print $langs->trans("CreateInternalUserDesc")."<br>\n"; - print "<br>"; + print $langs->trans("CreateInternalUserDesc")."<br>\n"; + print "<br>"; - if (! empty($conf->ldap->enabled) && (isset($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr')) - { - /* + if (! empty($conf->ldap->enabled) && (isset($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr')) + { + /* * Affiche formulaire d'ajout d'un compte depuis LDAP * si on est en synchro LDAP vers Dolibarr */ - $ldap = new Ldap(); - $result = $ldap->connect_bind(); - if ($result >= 0) - { - $required_fields=array( + $ldap = new Ldap(); + $result = $ldap->connect_bind(); + if ($result >= 0) + { + $required_fields=array( $conf->global->LDAP_KEY_USERS, - $conf->global->LDAP_FIELD_FULLNAME, + $conf->global->LDAP_FIELD_FULLNAME, $conf->global->LDAP_FIELD_NAME, $conf->global->LDAP_FIELD_FIRSTNAME, $conf->global->LDAP_FIELD_LOGIN, @@ -670,219 +670,219 @@ if ($action == 'create' || $action == 'adduserldap') $conf->global->LDAP_FIELD_MAIL, $conf->global->LDAP_FIELD_TITLE, $conf->global->LDAP_FIELD_DESCRIPTION, - $conf->global->LDAP_FIELD_SID - ); + $conf->global->LDAP_FIELD_SID + ); - // Remove from required_fields all entries not configured in LDAP (empty) and duplicated - $required_fields=array_unique(array_values(array_filter($required_fields, "dol_validElement"))); + // Remove from required_fields all entries not configured in LDAP (empty) and duplicated + $required_fields=array_unique(array_values(array_filter($required_fields, "dol_validElement"))); - // Get from LDAP database an array of results - $ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields, 1); + // Get from LDAP database an array of results + $ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields, 1); - if (is_array($ldapusers)) - { - $liste=array(); - foreach ($ldapusers as $key => $ldapuser) - { - // Define the label string for this user - $label=''; - foreach ($required_fields as $value) - { - if ($value) - { - $label.=$value."=".$ldapuser[$value]." "; - } - } - $liste[$key] = $label; - } + if (is_array($ldapusers)) + { + $liste=array(); + foreach ($ldapusers as $key => $ldapuser) + { + // Define the label string for this user + $label=''; + foreach ($required_fields as $value) + { + if ($value) + { + $label.=$value."=".$ldapuser[$value]." "; + } + } + $liste[$key] = $label; + } - } - else - { - setEventMessages($ldap->error, $ldap->errors, 'errors'); - } - } - else - { - setEventMessages($ldap->error, $ldap->errors, 'errors'); - } - - // If user list is full, we show drop-down list - print "\n\n<!-- Form liste LDAP debut -->\n"; - - print '<form name="add_user_ldap" action="'.$_SERVER["PHP_SELF"].'" method="post">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<table width="100%" class="border"><tr>'; - print '<td width="160">'; - print $langs->trans("LDAPUsers"); - print '</td>'; - print '<td>'; - print '<input type="hidden" name="action" value="adduserldap">'; - if (is_array($liste) && count($liste)) - { - print $form->selectarray('users', $liste, '', 1); - print ajax_combobox('users'); - } - print '</td><td align="center">'; - print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Get')).'"'.(count($liste)?'':' disabled').'>'; - print '</td></tr></table>'; - print '</form>'; - - print "\n<!-- Form liste LDAP fin -->\n\n"; - print '<br>'; - } - - - print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST" name="createuser">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="add">'; - if (! empty($ldap_sid)) print '<input type="hidden" name="ldap_sid" value="'.dol_escape_htmltag($ldap_sid).'">'; - print '<input type="hidden" name="entity" value="'.$conf->entity.'">'; - - dol_fiche_head('', '', '', 0, ''); - - print dol_set_focus('#lastname'); - - print '<table class="border centpercent">'; - - // Lastname - print '<tr>'; - print '<td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Lastname").'</span></td>'; - print '<td>'; - if (! empty($ldap_lastname)) - { - print '<input type="hidden" id="lastname" name="lastname" value="'.$ldap_lastname.'">'; - print $ldap_lastname; - } - else - { - print '<input class="minwidth100" type="text" id="lastname" name="lastname" value="'.GETPOST('lastname').'">'; - } - print '</td></tr>'; - - // Firstname - print '<tr><td>'.$langs->trans("Firstname").'</td>'; - print '<td>'; - if (! empty($ldap_firstname)) - { - print '<input type="hidden" name="firstname" value="'.$ldap_firstname.'">'; - print $ldap_firstname; - } - else - { - print '<input class="minwidth100" type="text" name="firstname" value="'.GETPOST('firstname').'">'; - } - print '</td></tr>'; + } + else + { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + } + else + { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + + // If user list is full, we show drop-down list + print "\n\n<!-- Form liste LDAP debut -->\n"; + + print '<form name="add_user_ldap" action="'.$_SERVER["PHP_SELF"].'" method="post">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<table width="100%" class="border"><tr>'; + print '<td width="160">'; + print $langs->trans("LDAPUsers"); + print '</td>'; + print '<td>'; + print '<input type="hidden" name="action" value="adduserldap">'; + if (is_array($liste) && count($liste)) + { + print $form->selectarray('users', $liste, '', 1); + print ajax_combobox('users'); + } + print '</td><td align="center">'; + print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Get')).'"'.(count($liste)?'':' disabled').'>'; + print '</td></tr></table>'; + print '</form>'; + + print "\n<!-- Form liste LDAP fin -->\n\n"; + print '<br>'; + } + + + print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST" name="createuser">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="add">'; + if (! empty($ldap_sid)) print '<input type="hidden" name="ldap_sid" value="'.dol_escape_htmltag($ldap_sid).'">'; + print '<input type="hidden" name="entity" value="'.$conf->entity.'">'; + + dol_fiche_head('', '', '', 0, ''); + + print dol_set_focus('#lastname'); + + print '<table class="border centpercent">'; + + // Lastname + print '<tr>'; + print '<td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Lastname").'</span></td>'; + print '<td>'; + if (! empty($ldap_lastname)) + { + print '<input type="hidden" id="lastname" name="lastname" value="'.$ldap_lastname.'">'; + print $ldap_lastname; + } + else + { + print '<input class="minwidth100" type="text" id="lastname" name="lastname" value="'.GETPOST('lastname').'">'; + } + print '</td></tr>'; + + // Firstname + print '<tr><td>'.$langs->trans("Firstname").'</td>'; + print '<td>'; + if (! empty($ldap_firstname)) + { + print '<input type="hidden" name="firstname" value="'.$ldap_firstname.'">'; + print $ldap_firstname; + } + else + { + print '<input class="minwidth100" type="text" name="firstname" value="'.GETPOST('firstname').'">'; + } + print '</td></tr>'; // Employee - $defaultemployee=1; - print '<tr>'; - print '<td>'.$langs->trans('Employee').'</td><td>'; - print $form->selectyesno("employee",(GETPOST('employee')!=''?GETPOST('employee'):$defaultemployee),1); - print '</td></tr>'; - - // Position/Job - print '<tr><td>'.$langs->trans("PostOrFunction").'</td>'; - print '<td>'; - print '<input class="maxwidth200" type="text" name="job" value="'.GETPOST('job').'">'; - print '</td></tr>'; - - // Gender - print '<tr><td>'.$langs->trans("Gender").'</td>'; - print '<td>'; - $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); - print $form->selectarray('gender', $arraygender, GETPOST('gender'), 1); - print '</td></tr>'; - - // Date employment - print '<tr><td>'.$langs->trans("DateToBirth").'</td>'; - print '<td>'; - echo $form->select_date(GETPOST('birth'),'birth',0,0,1,'createuser',1,0,1); - print '</td>'; - print "</tr>\n"; - - // Login - print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>'; - print '<td>'; - if (! empty($ldap_login)) - { - print '<input type="hidden" name="login" value="'.$ldap_login.'">'; - print $ldap_login; - } - elseif (! empty($ldap_loginsmb)) - { - print '<input type="hidden" name="login" value="'.$ldap_loginsmb.'">'; - print $ldap_loginsmb; - } - else - { - print '<input class="maxwidth200" maxsize="24" type="text" name="login" value="'.GETPOST('login').'">'; - } - print '</td></tr>'; - - $generated_password=''; - if (empty($ldap_sid)) // ldap_sid is for activedirectory - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; - $generated_password=getRandomPassword(false); - } - $password=$generated_password; - - // Password - print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td>'; - print '<td>'; - if (! empty($ldap_sid)) - { - print 'Mot de passe du domaine'; - } - else - { - if (! empty($ldap_pass)) - { - print '<input type="hidden" name="password" value="'.$ldap_pass.'">'; - print preg_replace('/./i','*',$ldap_pass); - } - else - { - // We do not use a field password but a field text to show new password to use. - print '<input size="30" maxsize="32" type="text" name="password" value="'.$password.'" autocomplete="off">'; - } - } - print '</td></tr>'; - - if(! empty($conf->api->enabled)) - { - // API key - $generated_api_key = ''; - require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; - $generated_password=getRandomPassword(false); - print '<tr><td>'.$langs->trans("ApiKey").'</td>'; - print '<td>'; - print '<input size="30" maxsize="32" type="text" id="api_key" name="api_key" value="'.$api_key.'" autocomplete="off">'; - if (! empty($conf->use_javascript_ajax)) - print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"'); - print '</td></tr>'; - } - else - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; - // PARTIAL WORKAROUND - $generated_fake_api_key=getRandomPassword(false); - print '<input type="hidden" name="api_key" value="'.$generated_fake_api_key.'">'; - } - - // Administrator - if (! empty($user->admin)) - { - print '<tr><td>'.$langs->trans("Administrator").'</td>'; - print '<td>'; - print $form->selectyesno('admin',GETPOST('admin'),1); - - if (! empty($conf->multicompany->enabled) && ! $user->entity && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) - { - if (! empty($conf->use_javascript_ajax)) - { - print '<script type="text/javascript"> + $defaultemployee=1; + print '<tr>'; + print '<td>'.$langs->trans('Employee').'</td><td>'; + print $form->selectyesno("employee",(GETPOST('employee')!=''?GETPOST('employee'):$defaultemployee),1); + print '</td></tr>'; + + // Position/Job + print '<tr><td>'.$langs->trans("PostOrFunction").'</td>'; + print '<td>'; + print '<input class="maxwidth200" type="text" name="job" value="'.GETPOST('job').'">'; + print '</td></tr>'; + + // Gender + print '<tr><td>'.$langs->trans("Gender").'</td>'; + print '<td>'; + $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); + print $form->selectarray('gender', $arraygender, GETPOST('gender'), 1); + print '</td></tr>'; + + // Date employment + print '<tr><td>'.$langs->trans("DateToBirth").'</td>'; + print '<td>'; + echo $form->select_date(GETPOST('birth'),'birth',0,0,1,'createuser',1,0,1); + print '</td>'; + print "</tr>\n"; + + // Login + print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>'; + print '<td>'; + if (! empty($ldap_login)) + { + print '<input type="hidden" name="login" value="'.$ldap_login.'">'; + print $ldap_login; + } + elseif (! empty($ldap_loginsmb)) + { + print '<input type="hidden" name="login" value="'.$ldap_loginsmb.'">'; + print $ldap_loginsmb; + } + else + { + print '<input class="maxwidth200" maxsize="24" type="text" name="login" value="'.GETPOST('login').'">'; + } + print '</td></tr>'; + + $generated_password=''; + if (empty($ldap_sid)) // ldap_sid is for activedirectory + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $generated_password=getRandomPassword(false); + } + $password=$generated_password; + + // Password + print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td>'; + print '<td>'; + if (! empty($ldap_sid)) + { + print 'Mot de passe du domaine'; + } + else + { + if (! empty($ldap_pass)) + { + print '<input type="hidden" name="password" value="'.$ldap_pass.'">'; + print preg_replace('/./i','*',$ldap_pass); + } + else + { + // We do not use a field password but a field text to show new password to use. + print '<input size="30" maxsize="32" type="text" name="password" value="'.$password.'" autocomplete="off">'; + } + } + print '</td></tr>'; + + if(! empty($conf->api->enabled)) + { + // API key + $generated_api_key = ''; + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $generated_password=getRandomPassword(false); + print '<tr><td>'.$langs->trans("ApiKey").'</td>'; + print '<td>'; + print '<input size="30" maxsize="32" type="text" id="api_key" name="api_key" value="'.$api_key.'" autocomplete="off">'; + if (! empty($conf->use_javascript_ajax)) + print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"'); + print '</td></tr>'; + } + else + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + // PARTIAL WORKAROUND + $generated_fake_api_key=getRandomPassword(false); + print '<input type="hidden" name="api_key" value="'.$generated_fake_api_key.'">'; + } + + // Administrator + if (! empty($user->admin)) + { + print '<tr><td>'.$langs->trans("Administrator").'</td>'; + print '<td>'; + print $form->selectyesno('admin',GETPOST('admin'),1); + + if (! empty($conf->multicompany->enabled) && ! $user->entity && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + if (! empty($conf->use_javascript_ajax)) + { + print '<script type="text/javascript"> $(function() { $("select[name=admin]").change(function() { if ( $(this).val() == 0 ) { @@ -907,187 +907,187 @@ if ($action == 'create' || $action == 'adduserldap') }); }); </script>'; - } - $checked=(GETPOST('superadmin', 'int')?' checked':''); - $disabled=(GETPOST('superadmin', 'int')?'':' disabled'); - print '<input type="checkbox" name="superadmin" value="1"'.$checked.$disabled.' /> '.$langs->trans("SuperAdministrator"); - } - print "</td></tr>\n"; - } - - // Type - print '<tr><td>'.$langs->trans("Type").'</td>'; - print '<td>'; - print $form->textwithpicto($langs->trans("Internal"),$langs->trans("InternalExternalDesc"), 1, 'help', '', 0, 2); - print '</td></tr>'; - - // Address - print '<tr><td class="tdtop">'.fieldLabel('Address','address').'</td>'; + } + $checked=(GETPOST('superadmin', 'int')?' checked':''); + $disabled=(GETPOST('superadmin', 'int')?'':' disabled'); + print '<input type="checkbox" name="superadmin" value="1"'.$checked.$disabled.' /> '.$langs->trans("SuperAdministrator"); + } + print "</td></tr>\n"; + } + + // Type + print '<tr><td>'.$langs->trans("Type").'</td>'; + print '<td>'; + print $form->textwithpicto($langs->trans("Internal"),$langs->trans("InternalExternalDesc"), 1, 'help', '', 0, 2); + print '</td></tr>'; + + // Address + print '<tr><td class="tdtop">'.fieldLabel('Address','address').'</td>'; print '<td><textarea name="address" id="address" class="quatrevingtpercent" rows="3" wrap="soft">'; - print $object->address; - print '</textarea></td></tr>'; + print $object->address; + print '</textarea></td></tr>'; - // Zip - print '<tr><td>'.fieldLabel('Zip','zipcode').'</td><td>'; - print $formcompany->select_ziptown($object->zip,'zipcode',array('town','selectcountry_id','state_id'),6); - print '</td></tr>'; + // Zip + print '<tr><td>'.fieldLabel('Zip','zipcode').'</td><td>'; + print $formcompany->select_ziptown($object->zip,'zipcode',array('town','selectcountry_id','state_id'),6); + print '</td></tr>'; // Town print '<tr><td>'.fieldLabel('Town','town').'</td><td>'; - print $formcompany->select_ziptown($object->town,'town',array('zipcode','selectcountry_id','state_id')); - print '</td></tr>'; - - // Country - print '<tr><td>'.fieldLabel('Country','selectcountry_id').'</td><td class="maxwidthonsmartphone">'; - print $form->select_country((GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id)); - if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - print '</td></tr>'; - - // State - if (empty($conf->global->USER_DISABLE_STATE)) - { - print '<tr><td>'.fieldLabel('State','state_id').'</td><td class="maxwidthonsmartphone">'; - print $formcompany->select_state($object->state_id,$object->country_code, 'state_id'); - print '</td></tr>'; - } - - // Tel - print '<tr><td>'.$langs->trans("PhonePro").'</td>'; - print '<td>'; - if (! empty($ldap_phone)) - { - print '<input type="hidden" name="office_phone" value="'.$ldap_phone.'">'; - print $ldap_phone; - } - else - { - print '<input size="20" type="text" name="office_phone" value="'.GETPOST('office_phone').'">'; - } - print '</td></tr>'; - - // Tel portable - print '<tr><td>'.$langs->trans("PhoneMobile").'</td>'; - print '<td>'; - if (! empty($ldap_mobile)) - { - print '<input type="hidden" name="user_mobile" value="'.$ldap_mobile.'">'; - print $ldap_mobile; - } - else - { - print '<input size="20" type="text" name="user_mobile" value="'.GETPOST('user_mobile').'">'; - } - print '</td></tr>'; - - // Fax - print '<tr><td>'.$langs->trans("Fax").'</td>'; - print '<td>'; - if (! empty($ldap_fax)) - { - print '<input type="hidden" name="office_fax" value="'.$ldap_fax.'">'; - print $ldap_fax; - } - else - { - print '<input size="20" type="text" name="office_fax" value="'.GETPOST('office_fax').'">'; - } - print '</td></tr>'; - - // Skype - if (! empty($conf->skype->enabled)) - { - print '<tr><td>'.$langs->trans("Skype").'</td>'; - print '<td>'; - if (! empty($ldap_skype)) - { - print '<input type="hidden" name="skype" value="'.$ldap_skype.'">'; - print $ldap_skype; - } - else - { - print '<input size="40" type="text" name="skype" value="'.GETPOST('skype').'">'; - } - print '</td></tr>'; - } - - // EMail - print '<tr><td'.(! empty($conf->global->USER_MAIL_REQUIRED)?' class="fieldrequired"':'').'>'.$langs->trans("EMail").'</td>'; - print '<td>'; - if (! empty($ldap_mail)) - { - print '<input type="hidden" name="email" value="'.$ldap_mail.'">'; - print $ldap_mail; - } - else - { - print '<input size="40" type="text" name="email" value="'.GETPOST('email').'">'; - } - print '</td></tr>'; - - // Accountancy code - if ($conf->accounting->enabled) - { - print '<tr><td>'.$langs->trans("AccountancyCode").'</td>'; - print '<td>'; - print '<input size="30" type="text" name="accountancy_code" value="'.GETPOST('accountancy_code').'">'; - print '</td></tr>'; - } - - // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) - - // Hierarchy - print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>'; - print '<td>'; - print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $conf->entity, 0, 0, '', 0, '', 'maxwidth300'); - print '</td>'; - print "</tr>\n"; - - if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) - || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) + print $formcompany->select_ziptown($object->town,'town',array('zipcode','selectcountry_id','state_id')); + print '</td></tr>'; + + // Country + print '<tr><td>'.fieldLabel('Country','selectcountry_id').'</td><td class="maxwidthonsmartphone">'; + print $form->select_country((GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id)); + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + print '</td></tr>'; + + // State + if (empty($conf->global->USER_DISABLE_STATE)) + { + print '<tr><td>'.fieldLabel('State','state_id').'</td><td class="maxwidthonsmartphone">'; + print $formcompany->select_state($object->state_id,$object->country_code, 'state_id'); + print '</td></tr>'; + } + + // Tel + print '<tr><td>'.$langs->trans("PhonePro").'</td>'; + print '<td>'; + if (! empty($ldap_phone)) + { + print '<input type="hidden" name="office_phone" value="'.$ldap_phone.'">'; + print $ldap_phone; + } + else + { + print '<input size="20" type="text" name="office_phone" value="'.GETPOST('office_phone').'">'; + } + print '</td></tr>'; + + // Tel portable + print '<tr><td>'.$langs->trans("PhoneMobile").'</td>'; + print '<td>'; + if (! empty($ldap_mobile)) + { + print '<input type="hidden" name="user_mobile" value="'.$ldap_mobile.'">'; + print $ldap_mobile; + } + else + { + print '<input size="20" type="text" name="user_mobile" value="'.GETPOST('user_mobile').'">'; + } + print '</td></tr>'; + + // Fax + print '<tr><td>'.$langs->trans("Fax").'</td>'; + print '<td>'; + if (! empty($ldap_fax)) + { + print '<input type="hidden" name="office_fax" value="'.$ldap_fax.'">'; + print $ldap_fax; + } + else + { + print '<input size="20" type="text" name="office_fax" value="'.GETPOST('office_fax').'">'; + } + print '</td></tr>'; + + // Skype + if (! empty($conf->skype->enabled)) + { + print '<tr><td>'.$langs->trans("Skype").'</td>'; + print '<td>'; + if (! empty($ldap_skype)) + { + print '<input type="hidden" name="skype" value="'.$ldap_skype.'">'; + print $ldap_skype; + } + else + { + print '<input size="40" type="text" name="skype" value="'.GETPOST('skype').'">'; + } + print '</td></tr>'; + } + + // EMail + print '<tr><td'.(! empty($conf->global->USER_MAIL_REQUIRED)?' class="fieldrequired"':'').'>'.$langs->trans("EMail").'</td>'; + print '<td>'; + if (! empty($ldap_mail)) + { + print '<input type="hidden" name="email" value="'.$ldap_mail.'">'; + print $ldap_mail; + } + else + { + print '<input size="40" type="text" name="email" value="'.GETPOST('email').'">'; + } + print '</td></tr>'; + + // Accountancy code + if ($conf->accounting->enabled) + { + print '<tr><td>'.$langs->trans("AccountancyCode").'</td>'; + print '<td>'; + print '<input size="30" type="text" name="accountancy_code" value="'.GETPOST('accountancy_code').'">'; + print '</td></tr>'; + } + + // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) + + // Hierarchy + print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>'; + print '<td>'; + print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $conf->entity, 0, 0, '', 0, '', 'maxwidth300'); + print '</td>'; + print "</tr>\n"; + + if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) + || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) { $langs->load("salaries"); - // THM - print '<tr><td>'; + // THM + print '<tr><td>'; $text=$langs->trans("THM"); print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); - print '</td>'; - print '<td>'; - print '<input size="8" type="text" name="thm" value="'.GETPOST('thm').'">'; - print '</td>'; - print "</tr>\n"; - - // TJM - print '<tr><td>'; + print '</td>'; + print '<td>'; + print '<input size="8" type="text" name="thm" value="'.GETPOST('thm').'">'; + print '</td>'; + print "</tr>\n"; + + // TJM + print '<tr><td>'; $text=$langs->trans("TJM"); print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm'); - print '</td>'; - print '<td>'; - print '<input size="8" type="text" name="tjm" value="'.GETPOST('tjm').'">'; - print '</td>'; - print "</tr>\n"; - - // Salary - print '<tr><td>'.$langs->trans("Salary").'</td>'; - print '<td>'; - print '<input size="8" type="text" name="salary" value="'.GETPOST('salary').'">'; - print '</td>'; - print "</tr>\n"; + print '</td>'; + print '<td>'; + print '<input size="8" type="text" name="tjm" value="'.GETPOST('tjm').'">'; + print '</td>'; + print "</tr>\n"; + + // Salary + print '<tr><td>'.$langs->trans("Salary").'</td>'; + print '<td>'; + print '<input size="8" type="text" name="salary" value="'.GETPOST('salary').'">'; + print '</td>'; + print "</tr>\n"; } - // Weeklyhours - print '<tr><td>'.$langs->trans("WeeklyHours").'</td>'; - print '<td>'; - print '<input size="8" type="text" name="weeklyhours" value="'.GETPOST('weeklyhours').'">'; - print '</td>'; - print "</tr>\n"; + // Weeklyhours + print '<tr><td>'.$langs->trans("WeeklyHours").'</td>'; + print '<td>'; + print '<input size="8" type="text" name="weeklyhours" value="'.GETPOST('weeklyhours').'">'; + print '</td>'; + print "</tr>\n"; - // Date employment - print '<tr><td>'.$langs->trans("DateEmployment").'</td>'; - print '<td>'; + // Date employment + print '<tr><td>'.$langs->trans("DateEmployment").'</td>'; + print '<td>'; echo $form->select_date(GETPOST('dateemployment'),'dateemployment',0,0,1,'form'.'dateemployment',1,0,1); print '</td>'; - print "</tr>\n"; + print "</tr>\n"; // User color if (! empty($conf->agenda->enabled)) @@ -1140,108 +1140,108 @@ if ($action == 'create' || $action == 'adduserldap') print '</td></tr>'; } - // Other attributes - $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit'); - } - - // Note - print '<tr><td class="tdtop">'; - print $langs->trans("Note"); - print '</td><td>'; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note','','',120,'dolibarr_notes','',false,true,$conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_3,'90%'); - $doleditor->Create(); - print "</td></tr>\n"; - - // Signature - print '<tr><td class="tdtop">'.$langs->trans("Signature").'</td>'; - print '<td>'; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('signature',GETPOST('signature'),'',138,'dolibarr_mailings','In',true,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); - print $doleditor->Create(1); - print '</td></tr>'; - - print "</table>\n"; + // Other attributes + $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit'); + } + + // Note + print '<tr><td class="tdtop">'; + print $langs->trans("Note"); + print '</td><td>'; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('note','','',120,'dolibarr_notes','',false,true,$conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_3,'90%'); + $doleditor->Create(); + print "</td></tr>\n"; + + // Signature + print '<tr><td class="tdtop">'.$langs->trans("Signature").'</td>'; + print '<td>'; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('signature',GETPOST('signature'),'',138,'dolibarr_mailings','In',true,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); + print $doleditor->Create(1); + print '</td></tr>'; + + print "</table>\n"; dol_fiche_end(); - print '<div align="center">'; - print '<input class="button" value="'.$langs->trans("CreateUser").'" name="create" type="submit">'; - //print ' '; - //print '<input value="'.$langs->trans("Cancel").'" class="button" type="submit" name="cancel">'; - print '</div>'; + print '<div align="center">'; + print '<input class="button" value="'.$langs->trans("CreateUser").'" name="create" type="submit">'; + //print ' '; + //print '<input value="'.$langs->trans("Cancel").'" class="button" type="submit" name="cancel">'; + print '</div>'; - print "</form>"; + print "</form>"; } else { - /* ************************************************************************** */ - /* */ - /* View and edition */ - /* */ - /* ************************************************************************** */ - - if ($id > 0) - { - $object->fetch($id, '', '', 1); - if ($res < 0) { dol_print_error($db,$object->error); exit; } - $res=$object->fetch_optionals($object->id,$extralabels); + /* ************************************************************************** */ + /* */ + /* View and edition */ + /* */ + /* ************************************************************************** */ + + if ($id > 0) + { + $object->fetch($id, '', '', 1); + if ($res < 0) { dol_print_error($db,$object->error); exit; } + $res=$object->fetch_optionals($object->id,$extralabels); // Check if user has rights $object->getrights(); if (empty($object->nb_rights) && $object->statut != 0) setEventMessages($langs->trans('UserHasNoPermissions'), null, 'warnings'); - // Connexion ldap - // pour recuperer passDoNotExpire et userChangePassNextLogon - if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) - { - $ldap = new Ldap(); - $result=$ldap->connect_bind(); - if ($result > 0) - { - $userSearchFilter = '('.$conf->global->LDAP_FILTER_CONNECTION.'('.$ldap->getUserIdentifier().'='.$object->login.'))'; - $entries = $ldap->fetch($object->login,$userSearchFilter); - if (! $entries) - { - setEventMessages($ldap->error, $ldap->errors, 'errors'); - } - - $passDoNotExpire = 0; - $userChangePassNextLogon = 0; - $userDisabled = 0; - $statutUACF = ''; - - // Check options of user account - if (count($ldap->uacf) > 0) - { - foreach ($ldap->uacf as $key => $statut) - { - if ($key == 65536) - { - $passDoNotExpire = 1; - $statutUACF = $statut; - } - } - } - else - { - $userDisabled = 1; - $statutUACF = "ACCOUNTDISABLE"; - } - - if ($ldap->pwdlastset == 0) - { - $userChangePassNextLogon = 1; - } - } - } + // Connexion ldap + // pour recuperer passDoNotExpire et userChangePassNextLogon + if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) + { + $ldap = new Ldap(); + $result=$ldap->connect_bind(); + if ($result > 0) + { + $userSearchFilter = '('.$conf->global->LDAP_FILTER_CONNECTION.'('.$ldap->getUserIdentifier().'='.$object->login.'))'; + $entries = $ldap->fetch($object->login,$userSearchFilter); + if (! $entries) + { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + + $passDoNotExpire = 0; + $userChangePassNextLogon = 0; + $userDisabled = 0; + $statutUACF = ''; + + // Check options of user account + if (count($ldap->uacf) > 0) + { + foreach ($ldap->uacf as $key => $statut) + { + if ($key == 65536) + { + $passDoNotExpire = 1; + $statutUACF = $statut; + } + } + } + else + { + $userDisabled = 1; + $statutUACF = "ACCOUNTDISABLE"; + } + + if ($ldap->pwdlastset == 0) + { + $userChangePassNextLogon = 1; + } + } + } - // Show tabs + // Show tabs if ($mode == 'employee') // For HRM module development { $title = $langs->trans("Employee"); @@ -1257,284 +1257,284 @@ else } } - $head = user_prepare_head($object); + $head = user_prepare_head($object); - /* + /* * Confirmation reinitialisation mot de passe */ - if ($action == 'password') - { - print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("ReinitPassword"),$langs->trans("ConfirmReinitPassword",$object->login),"confirm_password", '', 0, 1); - } + if ($action == 'password') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("ReinitPassword"),$langs->trans("ConfirmReinitPassword",$object->login),"confirm_password", '', 0, 1); + } - /* + /* * Confirmation envoi mot de passe */ - if ($action == 'passwordsend') - { - print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("SendNewPassword"),$langs->trans("ConfirmSendNewPassword",$object->login),"confirm_passwordsend", '', 0, 1); - } + if ($action == 'passwordsend') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("SendNewPassword"),$langs->trans("ConfirmSendNewPassword",$object->login),"confirm_passwordsend", '', 0, 1); + } - /* + /* * Confirm deactivation */ - if ($action == 'disable') - { - print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("DisableAUser"),$langs->trans("ConfirmDisableUser",$object->login),"confirm_disable", '', 0, 1); - } + if ($action == 'disable') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("DisableAUser"),$langs->trans("ConfirmDisableUser",$object->login),"confirm_disable", '', 0, 1); + } - /* + /* * Confirm activation */ - if ($action == 'enable') - { - print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("EnableAUser"),$langs->trans("ConfirmEnableUser",$object->login),"confirm_enable", '', 0, 1); - } + if ($action == 'enable') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("EnableAUser"),$langs->trans("ConfirmEnableUser",$object->login),"confirm_enable", '', 0, 1); + } - /* + /* * Confirmation suppression */ - if ($action == 'delete') - { - print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("DeleteAUser"),$langs->trans("ConfirmDeleteUser",$object->login),"confirm_delete", '', 0, 1); - } + if ($action == 'delete') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("DeleteAUser"),$langs->trans("ConfirmDeleteUser",$object->login),"confirm_delete", '', 0, 1); + } - /* + /* * Fiche en mode visu */ - if ($action != 'edit') - { + if ($action != 'edit') + { dol_fiche_head($head, 'user', $title, -1, 'user'); - dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin); + dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin); - print '<div class="fichecenter">'; - print '<div class="fichehalfleft">'; + print '<div class="fichecenter">'; + print '<div class="fichehalfleft">'; - print '<div class="underbanner clearboth"></div>'; - print '<table class="border tableforfield" width="100%">'; + print '<div class="underbanner clearboth"></div>'; + print '<table class="border tableforfield" width="100%">'; - // Login - print '<tr><td class="titlefield">'.$langs->trans("Login").'</td>'; - if (! empty($object->ldap_sid) && $object->statut==0) - { - print '<td class="error">'.$langs->trans("LoginAccountDisableInDolibarr").'</td>'; - } - else - { - print '<td>'.$object->login.'</td>'; - } - print '</tr>'."\n"; + // Login + print '<tr><td class="titlefield">'.$langs->trans("Login").'</td>'; + if (! empty($object->ldap_sid) && $object->statut==0) + { + print '<td class="error">'.$langs->trans("LoginAccountDisableInDolibarr").'</td>'; + } + else + { + print '<td>'.$object->login.'</td>'; + } + print '</tr>'."\n"; - // Password - print '<tr><td>'.$langs->trans("Password").'</td>'; - if (! empty($object->ldap_sid)) - { - if ($passDoNotExpire) - { - print '<td>'.$langs->trans("LdapUacf_".$statutUACF).'</td>'; - } - else if($userChangePassNextLogon) - { - print '<td class="warning">'.$langs->trans("UserMustChangePassNextLogon",$ldap->domainFQDN).'</td>'; - } - else if($userDisabled) - { - print '<td class="warning">'.$langs->trans("LdapUacf_".$statutUACF,$ldap->domainFQDN).'</td>'; - } - else - { - print '<td>'.$langs->trans("DomainPassword").'</td>'; - } - } - else - { - print '<td>'; - if ($object->pass) print preg_replace('/./i','*',$object->pass); - else - { - if ($user->admin) print $langs->trans("Crypted").': '.$object->pass_indatabase_crypted; - else print $langs->trans("Hidden"); - } - print "</td>"; - } - print '</tr>'."\n"; - - // Employee - print '<tr><td>'.$langs->trans("Employee").'</td><td colspan="2">'; - print yn($object->employee); - print '</td></tr>'."\n"; - - // Position/Job - print '<tr><td>'.$langs->trans("PostOrFunction").'</td>'; - print '<td>'.$object->job.'</td>'; - print '</tr>'."\n"; - - // Gender - print '<tr><td>'.$langs->trans("Gender").'</td>'; - print '<td>'; - if ($object->gender) print $langs->trans("Gender".$object->gender); - print '</td></tr>'; - - // Date of birth - print '<tr><td>'.$langs->trans("DateToBirth").'</td>'; - print '<td>'; - print dol_print_date($object->birth, 'day'); - print '</td>'; - print "</tr>\n"; - - // API key - if(! empty($conf->api->enabled) && $user->admin) { - print '<tr><td>'.$langs->trans("ApiKey").'</td>'; - print '<td>'; - if (! empty($object->api_key)) print preg_replace('/./','*',$object->api_key); - print '</td></tr>'; - } + // Password + print '<tr><td>'.$langs->trans("Password").'</td>'; + if (! empty($object->ldap_sid)) + { + if ($passDoNotExpire) + { + print '<td>'.$langs->trans("LdapUacf_".$statutUACF).'</td>'; + } + else if($userChangePassNextLogon) + { + print '<td class="warning">'.$langs->trans("UserMustChangePassNextLogon",$ldap->domainFQDN).'</td>'; + } + else if($userDisabled) + { + print '<td class="warning">'.$langs->trans("LdapUacf_".$statutUACF,$ldap->domainFQDN).'</td>'; + } + else + { + print '<td>'.$langs->trans("DomainPassword").'</td>'; + } + } + else + { + print '<td>'; + if ($object->pass) print preg_replace('/./i','*',$object->pass); + else + { + if ($user->admin) print $langs->trans("Crypted").': '.$object->pass_indatabase_crypted; + else print $langs->trans("Hidden"); + } + print "</td>"; + } + print '</tr>'."\n"; + + // Employee + print '<tr><td>'.$langs->trans("Employee").'</td><td colspan="2">'; + print yn($object->employee); + print '</td></tr>'."\n"; + + // Position/Job + print '<tr><td>'.$langs->trans("PostOrFunction").'</td>'; + print '<td>'.$object->job.'</td>'; + print '</tr>'."\n"; + + // Gender + print '<tr><td>'.$langs->trans("Gender").'</td>'; + print '<td>'; + if ($object->gender) print $langs->trans("Gender".$object->gender); + print '</td></tr>'; + + // Date of birth + print '<tr><td>'.$langs->trans("DateToBirth").'</td>'; + print '<td>'; + print dol_print_date($object->birth, 'day'); + print '</td>'; + print "</tr>\n"; - // Administrator - print '<tr><td>'.$langs->trans("Administrator").'</td><td>'; - if (! empty($conf->multicompany->enabled) && $object->admin && ! $object->entity) - { - print $form->textwithpicto(yn($object->admin),$langs->trans("SuperAdministratorDesc"),1,"superadmin"); - } - else if ($object->admin) - { - print $form->textwithpicto(yn($object->admin),$langs->trans("AdministratorDesc"),1,"admin"); - } - else - { - print yn($object->admin); - } - print '</td></tr>'."\n"; - - // Type - print '<tr><td>'; - $text=$langs->trans("Type"); - print $form->textwithpicto($text, $langs->trans("InternalExternalDesc")); - print '</td><td>'; - $type=$langs->trans("Internal"); - if ($object->societe_id > 0) $type=$langs->trans("External"); + // API key + if(! empty($conf->api->enabled) && $user->admin) { + print '<tr><td>'.$langs->trans("ApiKey").'</td>'; + print '<td>'; + if (! empty($object->api_key)) print preg_replace('/./','*',$object->api_key); + print '</td></tr>'; + } + + // Administrator + print '<tr><td>'.$langs->trans("Administrator").'</td><td>'; + if (! empty($conf->multicompany->enabled) && $object->admin && ! $object->entity) + { + print $form->textwithpicto(yn($object->admin),$langs->trans("SuperAdministratorDesc"),1,"superadmin"); + } + else if ($object->admin) + { + print $form->textwithpicto(yn($object->admin),$langs->trans("AdministratorDesc"),1,"admin"); + } + else + { + print yn($object->admin); + } + print '</td></tr>'."\n"; + + // Type + print '<tr><td>'; + $text=$langs->trans("Type"); + print $form->textwithpicto($text, $langs->trans("InternalExternalDesc")); + print '</td><td>'; + $type=$langs->trans("Internal"); + if ($object->societe_id > 0) $type=$langs->trans("External"); print $type; - if ($object->ldap_sid) print ' ('.$langs->trans("DomainUser").')'; - print '</td></tr>'."\n"; + if ($object->ldap_sid) print ' ('.$langs->trans("DomainUser").')'; + print '</td></tr>'."\n"; - // Ldap sid - if ($object->ldap_sid) - { - print '<tr><td>'.$langs->trans("Type").'</td><td>'; - print $langs->trans("DomainUser",$ldap->domainFQDN); - print '</td></tr>'."\n"; - } + // Ldap sid + if ($object->ldap_sid) + { + print '<tr><td>'.$langs->trans("Type").'</td><td>'; + print $langs->trans("DomainUser",$ldap->domainFQDN); + print '</td></tr>'."\n"; + } - // Accountancy code - if ($conf->accounting->enabled) - { - print '<tr><td>'.$langs->trans("AccountancyCode").'</td>'; - print '<td>'.$object->accountancy_code.'</td></tr>'; - } + // Accountancy code + if ($conf->accounting->enabled) + { + print '<tr><td>'.$langs->trans("AccountancyCode").'</td>'; + print '<td>'.$object->accountancy_code.'</td></tr>'; + } - // TODO Move this into tab RH, visible when salarie or RH is visible (HierarchicalResponsible must be on both tab) + // TODO Move this into tab RH, visible when salarie or RH is visible (HierarchicalResponsible must be on both tab) - // Hierarchy - print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>'; - print '<td>'; - if (empty($object->fk_user)) print $langs->trans("None"); - else { - $huser=new User($db); - $huser->fetch($object->fk_user); - print $huser->getNomUrl(1); - } - print '</td>'; - print "</tr>\n"; + // Hierarchy + print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>'; + print '<td>'; + if (empty($object->fk_user)) print $langs->trans("None"); + else { + $huser=new User($db); + $huser->fetch($object->fk_user); + print $huser->getNomUrl(1); + } + print '</td>'; + print "</tr>\n"; - if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) - || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) - { - $langs->load("salaries"); - - // THM - print '<tr><td>'; - $text=$langs->trans("THM"); - print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); - print '</td>'; - print '<td>'; - print ($object->thm!=''?price($object->thm,'',$langs,1,-1,-1,$conf->currency):''); - print '</td>'; - print "</tr>\n"; - - // TJM - print '<tr><td>'; - $text=$langs->trans("TJM"); - print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm'); - print '</td>'; - print '<td>'; - print ($object->tjm!=''?price($object->tjm,'',$langs,1,-1,-1,$conf->currency):''); - print '</td>'; - print "</tr>\n"; - - // Salary - print '<tr><td>'.$langs->trans("Salary").'</td>'; - print '<td>'; - print ($object->salary!=''?price($object->salary,'',$langs,1,-1,-1,$conf->currency):''); - print '</td>'; - print "</tr>\n"; - } + if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) + || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) + { + $langs->load("salaries"); + + // THM + print '<tr><td>'; + $text=$langs->trans("THM"); + print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); + print '</td>'; + print '<td>'; + print ($object->thm!=''?price($object->thm,'',$langs,1,-1,-1,$conf->currency):''); + print '</td>'; + print "</tr>\n"; + + // TJM + print '<tr><td>'; + $text=$langs->trans("TJM"); + print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm'); + print '</td>'; + print '<td>'; + print ($object->tjm!=''?price($object->tjm,'',$langs,1,-1,-1,$conf->currency):''); + print '</td>'; + print "</tr>\n"; + + // Salary + print '<tr><td>'.$langs->trans("Salary").'</td>'; + print '<td>'; + print ($object->salary!=''?price($object->salary,'',$langs,1,-1,-1,$conf->currency):''); + print '</td>'; + print "</tr>\n"; + } - // Weeklyhours - print '<tr><td>'.$langs->trans("WeeklyHours").'</td>'; - print '<td>'; + // Weeklyhours + print '<tr><td>'.$langs->trans("WeeklyHours").'</td>'; + print '<td>'; print price2num($object->weeklyhours); - print '</td>'; - print "</tr>\n"; + print '</td>'; + print "</tr>\n"; - // Date employment - print '<tr><td>'.$langs->trans("DateEmployment").'</td>'; - print '<td>'; + // Date employment + print '<tr><td>'.$langs->trans("DateEmployment").'</td>'; + print '<td>'; print dol_print_date($object->dateemployment); - print '</td>'; - print "</tr>\n"; + print '</td>'; + print "</tr>\n"; - print '</table>'; + print '</table>'; - print '</div>'; - print '<div class="fichehalfright"><div class="ficheaddleft">'; + print '</div>'; + print '<div class="fichehalfright"><div class="ficheaddleft">'; - print '<div class="underbanner clearboth"></div>'; - print '<table class="border tableforfield" width="100%">'; + print '<div class="underbanner clearboth"></div>'; + print '<table class="border tableforfield" width="100%">'; - // Color user - if (! empty($conf->agenda->enabled)) - { - print '<tr><td>'.$langs->trans("ColorUser").'</td>'; - print '<td>'; - print $formother->showColor($object->color, ''); - print '</td>'; - print "</tr>\n"; - } + // Color user + if (! empty($conf->agenda->enabled)) + { + print '<tr><td>'.$langs->trans("ColorUser").'</td>'; + print '<td>'; + print $formother->showColor($object->color, ''); + print '</td>'; + print "</tr>\n"; + } - // Categories - if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) - { + // Categories + if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) + { print '<tr><td>' . $langs->trans( "Categories" ) . '</td>'; print '<td colspan="3">'; print $form->showCategories( $object->id, 'user', 1 ); print '</td></tr>'; - } + } - if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file->main_authentication) && ! empty($conf->global->MAIN_OPENIDURL_PERUSER)) - { - print '<tr><td>'.$langs->trans("OpenIDURL").'</td>'; - print '<td>'.$object->openid.'</td>'; - print "</tr>\n"; - } + if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file->main_authentication) && ! empty($conf->global->MAIN_OPENIDURL_PERUSER)) + { + print '<tr><td>'.$langs->trans("OpenIDURL").'</td>'; + print '<td>'.$object->openid.'</td>'; + print "</tr>\n"; + } - print '<tr><td class="titlefield">'.$langs->trans("LastConnexion").'</td>'; - print '<td>'.dol_print_date($object->datelastlogin,"dayhour").'</td>'; - print "</tr>\n"; + print '<tr><td class="titlefield">'.$langs->trans("LastConnexion").'</td>'; + print '<td>'.dol_print_date($object->datelastlogin,"dayhour").'</td>'; + print "</tr>\n"; - print '<tr><td>'.$langs->trans("PreviousConnexion").'</td>'; - print '<td>'.dol_print_date($object->datepreviouslogin,"dayhour").'</td>'; - print "</tr>\n"; + print '<tr><td>'.$langs->trans("PreviousConnexion").'</td>'; + print '<td>'.dol_print_date($object->datepreviouslogin,"dayhour").'</td>'; + print "</tr>\n"; if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) { @@ -1549,9 +1549,9 @@ else print '</td></tr>'; } - // Multicompany - // This is now done with hook formObjectOptions (included into /core/tpl/extrafields_view.tpl.php) - /* + // Multicompany + // This is now done with hook formObjectOptions (included into /core/tpl/extrafields_view.tpl.php) + /* if (! empty($conf->multicompany->enabled) && is_object($mc)) { if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) @@ -1567,547 +1567,547 @@ else } }*/ - // Other attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; - // Company / Contact - if (! empty($conf->societe->enabled)) - { - print '<tr><td>'.$langs->trans("LinkToCompanyContact").'</td>'; - print '<td>'; - if (isset($object->socid) && $object->socid > 0) - { - $societe = new Societe($db); - $societe->fetch($object->socid); - print $societe->getNomUrl(1,''); - } - else - { - print $langs->trans("ThisUserIsNot"); - } - if (! empty($object->contactid)) - { - $contact = new Contact($db); - $contact->fetch($object->contactid); - if ($object->socid > 0) print ' / '; - else print '<br>'; - print '<a href="'.DOL_URL_ROOT.'/contact/card.php?id='.$object->contactid.'">'.img_object($langs->trans("ShowContact"),'contact').' '.dol_trunc($contact->getFullName($langs),32).'</a>'; - } - print '</td>'; - print '</tr>'."\n"; - } + // Company / Contact + if (! empty($conf->societe->enabled)) + { + print '<tr><td>'.$langs->trans("LinkToCompanyContact").'</td>'; + print '<td>'; + if (isset($object->socid) && $object->socid > 0) + { + $societe = new Societe($db); + $societe->fetch($object->socid); + print $societe->getNomUrl(1,''); + } + else + { + print $langs->trans("ThisUserIsNot"); + } + if (! empty($object->contactid)) + { + $contact = new Contact($db); + $contact->fetch($object->contactid); + if ($object->socid > 0) print ' / '; + else print '<br>'; + print '<a href="'.DOL_URL_ROOT.'/contact/card.php?id='.$object->contactid.'">'.img_object($langs->trans("ShowContact"),'contact').' '.dol_trunc($contact->getFullName($langs),32).'</a>'; + } + print '</td>'; + print '</tr>'."\n"; + } - // Module Adherent - if (! empty($conf->adherent->enabled)) - { - $langs->load("members"); - print '<tr><td>'.$langs->trans("LinkedToDolibarrMember").'</td>'; - print '<td>'; - if ($object->fk_member) - { - $adh=new Adherent($db); - $adh->fetch($object->fk_member); - $adh->ref=$adh->getFullname($langs); // Force to show login instead of id - print $adh->getNomUrl(1); - } - else - { - print $langs->trans("UserNotLinkedToMember"); - } - print '</td>'; - print '</tr>'."\n"; - } + // Module Adherent + if (! empty($conf->adherent->enabled)) + { + $langs->load("members"); + print '<tr><td>'.$langs->trans("LinkedToDolibarrMember").'</td>'; + print '<td>'; + if ($object->fk_member) + { + $adh=new Adherent($db); + $adh->fetch($object->fk_member); + $adh->ref=$adh->getFullname($langs); // Force to show login instead of id + print $adh->getNomUrl(1); + } + else + { + print $langs->trans("UserNotLinkedToMember"); + } + print '</td>'; + print '</tr>'."\n"; + } - // Signature - print '<tr><td class="tdtop">'.$langs->trans('Signature').'</td><td>'; - print dol_htmlentitiesbr($object->signature); - print "</td></tr>\n"; + // Signature + print '<tr><td class="tdtop">'.$langs->trans('Signature').'</td><td>'; + print dol_htmlentitiesbr($object->signature); + print "</td></tr>\n"; - print "</table>\n"; + print "</table>\n"; print '</div>'; - print '</div></div>'; - print '<div style="clear:both"></div>'; + print '</div></div>'; + print '<div style="clear:both"></div>'; - dol_fiche_end(); + dol_fiche_end(); - /* + /* * Buttons actions */ - print '<div class="tabsAction">'; + print '<div class="tabsAction">'; - if (! empty($object->email)) - { - $langs->load("mails"); - print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=presend&mode=init#presend">'.$langs->trans('SendMail').'</a></div>'; - } - else - { - $langs->load("mails"); - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEMail")).'">'.$langs->trans('SendMail').'</a></div>'; - } + if (! empty($object->email)) + { + $langs->load("mails"); + print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=presend&mode=init#presend">'.$langs->trans('SendMail').'</a></div>'; + } + else + { + $langs->load("mails"); + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEMail")).'">'.$langs->trans('SendMail').'</a></div>'; + } - if ($caneditfield && (empty($conf->multicompany->enabled) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) - { - if (! empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)) - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("DisabledInMonoUserMode")).'">'.$langs->trans("Modify").'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit">'.$langs->trans("Modify").'</a></div>'; - } - } - elseif ($caneditpassword && ! $object->ldap_sid && - (empty($conf->multicompany->enabled) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) - { - print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit">'.$langs->trans("EditPassword").'</a></div>'; - } + if ($caneditfield && (empty($conf->multicompany->enabled) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) + { + if (! empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)) + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("DisabledInMonoUserMode")).'">'.$langs->trans("Modify").'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit">'.$langs->trans("Modify").'</a></div>'; + } + } + elseif ($caneditpassword && ! $object->ldap_sid && + (empty($conf->multicompany->enabled) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) + { + print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit">'.$langs->trans("EditPassword").'</a></div>'; + } - // Si on a un gestionnaire de generation de mot de passe actif - if ($conf->global->USER_PASSWORD_GENERATED != 'none') - { + // Si on a un gestionnaire de generation de mot de passe actif + if ($conf->global->USER_PASSWORD_GENERATED != 'none') + { if ($object->statut == 0) { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("UserDisabled")).'">'.$langs->trans("ReinitPassword").'</a></div>'; + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("UserDisabled")).'">'.$langs->trans("ReinitPassword").'</a></div>'; + } + elseif (($user->id != $id && $caneditpassword) && $object->login && !$object->ldap_sid && + ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) + { + print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=password">'.$langs->trans("ReinitPassword").'</a></div>'; } - elseif (($user->id != $id && $caneditpassword) && $object->login && !$object->ldap_sid && - ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) - { - print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=password">'.$langs->trans("ReinitPassword").'</a></div>'; - } if ($object->statut == 0) { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("UserDisabled")).'">'.$langs->trans("SendNewPassword").'</a></div>'; + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("UserDisabled")).'">'.$langs->trans("SendNewPassword").'</a></div>'; } - else if (($user->id != $id && $caneditpassword) && $object->login && !$object->ldap_sid && - ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) - { - if ($object->email) print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=passwordsend">'.$langs->trans("SendNewPassword").'</a></div>'; - else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEMail")).'">'.$langs->trans("SendNewPassword").'</a></div>'; - } - } + else if (($user->id != $id && $caneditpassword) && $object->login && !$object->ldap_sid && + ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) + { + if ($object->email) print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=passwordsend">'.$langs->trans("SendNewPassword").'</a></div>'; + else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEMail")).'">'.$langs->trans("SendNewPassword").'</a></div>'; + } + } - // Activer - if ($user->id <> $id && $candisableuser && $object->statut == 0 && - ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) - { - print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=enable">'.$langs->trans("Reactivate").'</a></div>'; - } - // Desactiver - if ($user->id <> $id && $candisableuser && $object->statut == 1 && - ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) - { - print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?action=disable&id='.$object->id.'">'.$langs->trans("DisableUser").'</a></div>'; - } - // Delete - if ($user->id <> $id && $candisableuser && - ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) - { - if ($user->admin || ! $object->admin) // If user edited is admin, delete is possible on for an admin - { - print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?action=delete&id='.$object->id.'">'.$langs->trans("DeleteUser").'</a></div>'; - } - else - { - print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("MustBeAdminToDeleteOtherAdmin")).'">'.$langs->trans("DeleteUser").'</a></div>'; - } - } + // Activer + if ($user->id <> $id && $candisableuser && $object->statut == 0 && + ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) + { + print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=enable">'.$langs->trans("Reactivate").'</a></div>'; + } + // Desactiver + if ($user->id <> $id && $candisableuser && $object->statut == 1 && + ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) + { + print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?action=disable&id='.$object->id.'">'.$langs->trans("DisableUser").'</a></div>'; + } + // Delete + if ($user->id <> $id && $candisableuser && + ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || ! $user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $conf->entity == 1))) + { + if ($user->admin || ! $object->admin) // If user edited is admin, delete is possible on for an admin + { + print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?action=delete&id='.$object->id.'">'.$langs->trans("DeleteUser").'</a></div>'; + } + else + { + print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("MustBeAdminToDeleteOtherAdmin")).'">'.$langs->trans("DeleteUser").'</a></div>'; + } + } - print "</div>\n"; + print "</div>\n"; - //Select mail models is same action as presend - if (GETPOST('modelselected')) { - $action = 'presend'; - } - if ($action == 'presend') - { - // Show email form - - // By default if $action=='presend' - $titreform='SendMail'; - $topicmail=1; - $action='send'; - $modelmail='user'; - - print '<div id="formmailbeforetitle" name="formmailbeforetitle"></div>'; - print '<div id="presend"></div>'; - print load_fiche_titre($langs->trans($titreform)); - - dol_fiche_head(); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - //if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - // $newlang = $object->thirdparty->default_lang; - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='thi'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'thi'.$object->id); - } - $formmail->withfrom=1; - $formmail->withtopic=$topicmail; - $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$object->email; - $formmail->withtofree=1; - $formmail->withtocc=1; - $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->setSubstitFromObject($object, $outputlangs); - $formmail->substit['__LASTNAME__']=$object->lastname; - $formmail->substit['__FIRSTNAME__']=$object->firstname; - - // Tableau des parametres complementaires du post - $formmail->param['action']=$action; - $formmail->param['models']=$modelmail; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['socid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - // Init list of files - if (GETPOST("mode")=='init') - { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); - } - print $formmail->get_form(); - - dol_fiche_end(); - } + //Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + if ($action == 'presend') + { + // Show email form - if (GETPOST('action','aZ09') != 'presend' && GETPOST('action','aZ09') != 'send') - { - /* + // By default if $action=='presend' + $titreform='SendMail'; + $topicmail=1; + $action='send'; + $modelmail='user'; + + print '<div id="formmailbeforetitle" name="formmailbeforetitle"></div>'; + print '<div id="presend"></div>'; + print load_fiche_titre($langs->trans($titreform)); + + dol_fiche_head(); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + //if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + // $newlang = $object->thirdparty->default_lang; + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); + $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); + + if($formmail->fromtype === 'user'){ + $formmail->fromid = $user->id; + + } + $formmail->trackid='thi'.$object->id; + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set + { + include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'thi'.$object->id); + } + $formmail->withfrom=1; + $formmail->withtopic=$topicmail; + $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$object->email; + $formmail->withtofree=1; + $formmail->withtocc=1; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->setSubstitFromObject($object, $outputlangs); + $formmail->substit['__LASTNAME__']=$object->lastname; + $formmail->substit['__FIRSTNAME__']=$object->firstname; + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['models_id']=GETPOST('modelmailselected','int'); + $formmail->param['socid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } + print $formmail->get_form(); + + dol_fiche_end(); + } + + if (GETPOST('action','aZ09') != 'presend' && GETPOST('action','aZ09') != 'send') + { + /* * List of groups of user */ - if ($canreadgroup) - { - print load_fiche_titre($langs->trans("ListOfGroupsForUser"),'',''); - - // On selectionne les groupes auquel fait parti le user - $exclude = array(); - - $usergroup=new UserGroup($db); - $groupslist = $usergroup->listGroupsForUser($object->id); - - if (! empty($groupslist)) - { - if (! (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))) - { - foreach($groupslist as $groupforuser) - { - $exclude[]=$groupforuser->id; - } - } - } - - if ($caneditgroup) - { - print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'."\n"; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />'; - print '<input type="hidden" name="action" value="addgroup" />'; - } - - print '<table class="noborder" width="100%">'."\n"; - print '<tr class="liste_titre"><th class="liste_titre" width="25%">'.$langs->trans("Groups").'</th>'."\n"; - if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - print '<td class="liste_titre" width="25%">'.$langs->trans("Entity").'</td>'; - } - print '<th align="right">'; - if ($caneditgroup) - { - // Users/Groups management only in master entity if transverse mode - if (! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE) - { - // nothing - } - else - { - print $form->select_dolgroups('', 'group', 1, $exclude, 0, '', '', $object->entity); - print ' '; - // Multicompany - if (! empty($conf->multicompany->enabled)) - { - if ($conf->entity == 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE) - { - print '</td><td>'.$langs->trans("Entity").'</td>'; - print "<td>".$mc->select_entities($conf->entity); - } - else - { - print '<input type="hidden" name="entity" value="'.$conf->entity.'" />'; - } - } - else - { - print '<input type="hidden" name="entity" value="'.$conf->entity.'" />'; - } - print '<input type="submit" class="button" value="'.$langs->trans("Add").'" />'; - } - } - print '</th></tr>'."\n"; - - /* + if ($canreadgroup) + { + print load_fiche_titre($langs->trans("ListOfGroupsForUser"),'',''); + + // On selectionne les groupes auquel fait parti le user + $exclude = array(); + + $usergroup=new UserGroup($db); + $groupslist = $usergroup->listGroupsForUser($object->id); + + if (! empty($groupslist)) + { + if (! (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))) + { + foreach($groupslist as $groupforuser) + { + $exclude[]=$groupforuser->id; + } + } + } + + if ($caneditgroup) + { + print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'."\n"; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />'; + print '<input type="hidden" name="action" value="addgroup" />'; + } + + print '<table class="noborder" width="100%">'."\n"; + print '<tr class="liste_titre"><th class="liste_titre" width="25%">'.$langs->trans("Groups").'</th>'."\n"; + if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + print '<td class="liste_titre" width="25%">'.$langs->trans("Entity").'</td>'; + } + print '<th align="right">'; + if ($caneditgroup) + { + // Users/Groups management only in master entity if transverse mode + if (! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE) + { + // nothing + } + else + { + print $form->select_dolgroups('', 'group', 1, $exclude, 0, '', '', $object->entity); + print ' '; + // Multicompany + if (! empty($conf->multicompany->enabled)) + { + if ($conf->entity == 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE) + { + print '</td><td>'.$langs->trans("Entity").'</td>'; + print "<td>".$mc->select_entities($conf->entity); + } + else + { + print '<input type="hidden" name="entity" value="'.$conf->entity.'" />'; + } + } + else + { + print '<input type="hidden" name="entity" value="'.$conf->entity.'" />'; + } + print '<input type="submit" class="button" value="'.$langs->trans("Add").'" />'; + } + } + print '</th></tr>'."\n"; + + /* * Groups assigned to user */ - if (! empty($groupslist)) - { - foreach($groupslist as $group) - { - - - print '<tr class="oddeven">'; - print '<td>'; - if ($caneditgroup) - { - print '<a href="'.DOL_URL_ROOT.'/user/group/card.php?id='.$group->id.'">'.img_object($langs->trans("ShowGroup"),"group").' '.$group->name.'</a>'; - } - else - { - print img_object($langs->trans("ShowGroup"),"group").' '.$group->name; - } - print '</td>'; - if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - print '<td class="valeur">'; - if (! empty($group->usergroup_entity)) - { - $nb=0; - foreach($group->usergroup_entity as $group_entity) - { - $mc->getInfo($group_entity); - print ($nb > 0 ? ', ' : '').$mc->label; - print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=removegroup&group='.$group->id.'&entity='.$group_entity.'">'; - print img_delete($langs->trans("RemoveFromGroup")); - print '</a>'; - $nb++; - } - } - } - print '<td align="right">'; - if ($caneditgroup && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) - { - print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=removegroup&group='.$group->id.'">'; - print img_delete($langs->trans("RemoveFromGroup")); - print '</a>'; - } - else - { - print " "; - } - print "</td></tr>\n"; - } - } - else - { - print '<tr '.$bc[false].'><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>'; - } - - print "</table>"; - - if ($caneditgroup) - { - print '</form>'; - } - print "<br>"; - } - } - } + if (! empty($groupslist)) + { + foreach($groupslist as $group) + { + + + print '<tr class="oddeven">'; + print '<td>'; + if ($caneditgroup) + { + print '<a href="'.DOL_URL_ROOT.'/user/group/card.php?id='.$group->id.'">'.img_object($langs->trans("ShowGroup"),"group").' '.$group->name.'</a>'; + } + else + { + print img_object($langs->trans("ShowGroup"),"group").' '.$group->name; + } + print '</td>'; + if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + print '<td class="valeur">'; + if (! empty($group->usergroup_entity)) + { + $nb=0; + foreach($group->usergroup_entity as $group_entity) + { + $mc->getInfo($group_entity); + print ($nb > 0 ? ', ' : '').$mc->label; + print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=removegroup&group='.$group->id.'&entity='.$group_entity.'">'; + print img_delete($langs->trans("RemoveFromGroup")); + print '</a>'; + $nb++; + } + } + } + print '<td align="right">'; + if ($caneditgroup && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=removegroup&group='.$group->id.'">'; + print img_delete($langs->trans("RemoveFromGroup")); + print '</a>'; + } + else + { + print " "; + } + print "</td></tr>\n"; + } + } + else + { + print '<tr '.$bc[false].'><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>'; + } - /* + print "</table>"; + + if ($caneditgroup) + { + print '</form>'; + } + print "<br>"; + } + } + } + + /* * Fiche en mode edition */ - if ($action == 'edit' && ($canedituser || $caneditfield || $caneditpassword || ($user->id == $object->id))) - { - print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST" name="updateuser" enctype="multipart/form-data">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="update">'; - print '<input type="hidden" name="entity" value="'.$object->entity.'">'; + if ($action == 'edit' && ($canedituser || $caneditfield || $caneditpassword || ($user->id == $object->id))) + { + print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST" name="updateuser" enctype="multipart/form-data">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="update">'; + print '<input type="hidden" name="entity" value="'.$object->entity.'">'; - dol_fiche_head($head, 'user', $title, 0, 'user'); + dol_fiche_head($head, 'user', $title, 0, 'user'); - print '<table width="100%" class="border">'; + print '<table width="100%" class="border">'; - // Ref/ID + // Ref/ID if (! empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) { - print '<tr><td>'.$langs->trans("Ref").'</td>'; - print '<td>'; - print $object->id; - print '</td>'; - print '</tr>'; + print '<tr><td>'.$langs->trans("Ref").'</td>'; + print '<td>'; + print $object->id; + print '</td>'; + print '</tr>'; } - // Lastname - print "<tr>"; - print '<td class="fieldrequired">'.$langs->trans("Lastname").'</td>'; - print '<td>'; - if ($caneditfield && !$object->ldap_sid) - { - print '<input class="minwidth100" type="text" class="flat" name="lastname" value="'.$object->lastname.'">'; - } - else - { - print '<input type="hidden" name="lastname" value="'.$object->lastname.'">'; - print $object->lastname; - } - print '</td>'; - print '</tr>'; + // Lastname + print "<tr>"; + print '<td class="fieldrequired">'.$langs->trans("Lastname").'</td>'; + print '<td>'; + if ($caneditfield && !$object->ldap_sid) + { + print '<input class="minwidth100" type="text" class="flat" name="lastname" value="'.$object->lastname.'">'; + } + else + { + print '<input type="hidden" name="lastname" value="'.$object->lastname.'">'; + print $object->lastname; + } + print '</td>'; + print '</tr>'; - // Firstname - print "<tr>".'<td>'.$langs->trans("Firstname").'</td>'; - print '<td>'; - if ($caneditfield && !$object->ldap_sid) - { - print '<input class="minwidth100" type="text" class="flat" name="firstname" value="'.$object->firstname.'">'; - } - else - { - print '<input type="hidden" name="firstname" value="'.$object->firstname.'">'; - print $object->firstname; - } - print '</td></tr>'; - - // Employee - print '<tr>'; - print '<td>'.fieldLabel('Employee','employee',0).'</td><td>'; - print $form->selectyesno("employee",$object->employee,1); - print '</td></tr>'; - - // Position/Job - print '<tr><td>'.$langs->trans("PostOrFunction").'</td>'; - print '<td>'; - if ($caneditfield) - { - print '<input size="30" type="text" name="job" value="'.$object->job.'">'; - } - else + // Firstname + print "<tr>".'<td>'.$langs->trans("Firstname").'</td>'; + print '<td>'; + if ($caneditfield && !$object->ldap_sid) { - print '<input type="hidden" name="job" value="'.$object->job.'">'; - print $object->job; - } - print '</td></tr>'; - - // Gender - print '<tr><td>'.$langs->trans("Gender").'</td>'; - print '<td>'; - $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); - print $form->selectarray('gender', $arraygender, GETPOST('gender')?GETPOST('gender'):$object->gender, 1); - print '</td></tr>'; - - // Date birth - print '<tr><td>'.$langs->trans("DateToBirth").'</td>'; - print '<td>'; - echo $form->select_date(GETPOST('birth')?GETPOST('birth'):$object->birth,'birth',0,0,1,'updateuser',1,0,1); - print '</td>'; - print "</tr>\n"; - - // Login - print "<tr>".'<td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>'; - print '<td>'; - if ($user->admin && !$object->ldap_sid) - { - print '<input size="12" maxlength="24" type="text" class="flat" name="login" value="'.$object->login.'">'; - } - else - { - print '<input type="hidden" name="login" value="'.$object->login.'">'; - print $object->login; - } - print '</td>'; - print '</tr>'; + print '<input class="minwidth100" type="text" class="flat" name="firstname" value="'.$object->firstname.'">'; + } + else + { + print '<input type="hidden" name="firstname" value="'.$object->firstname.'">'; + print $object->firstname; + } + print '</td></tr>'; + + // Employee + print '<tr>'; + print '<td>'.fieldLabel('Employee','employee',0).'</td><td>'; + print $form->selectyesno("employee",$object->employee,1); + print '</td></tr>'; + + // Position/Job + print '<tr><td>'.$langs->trans("PostOrFunction").'</td>'; + print '<td>'; + if ($caneditfield) + { + print '<input size="30" type="text" name="job" value="'.$object->job.'">'; + } + else + { + print '<input type="hidden" name="job" value="'.$object->job.'">'; + print $object->job; + } + print '</td></tr>'; + + // Gender + print '<tr><td>'.$langs->trans("Gender").'</td>'; + print '<td>'; + $arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman")); + print $form->selectarray('gender', $arraygender, GETPOST('gender')?GETPOST('gender'):$object->gender, 1); + print '</td></tr>'; + + // Date birth + print '<tr><td>'.$langs->trans("DateToBirth").'</td>'; + print '<td>'; + echo $form->select_date(GETPOST('birth')?GETPOST('birth'):$object->birth,'birth',0,0,1,'updateuser',1,0,1); + print '</td>'; + print "</tr>\n"; - // Pass - print '<tr><td>'.$langs->trans("Password").'</td>'; - print '<td>'; - if ($object->ldap_sid) - { - $text=$langs->trans("DomainPassword"); - } - else if ($caneditpassword) - { - $text='<input size="12" maxlength="32" type="password" class="flat" name="password" value="'.$object->pass.'" autocomplete="off">'; - if ($dolibarr_main_authentication && $dolibarr_main_authentication == 'http') - { - $text=$form->textwithpicto($text,$langs->trans("DolibarrInHttpAuthenticationSoPasswordUseless",$dolibarr_main_authentication),1,'warning'); - } - } - else - { - $text=preg_replace('/./i','*',$object->pass); - } - print $text; - print "</td></tr>\n"; + // Login + print "<tr>".'<td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>'; + print '<td>'; + if ($user->admin && !$object->ldap_sid) + { + print '<input size="12" maxlength="24" type="text" class="flat" name="login" value="'.$object->login.'">'; + } + else + { + print '<input type="hidden" name="login" value="'.$object->login.'">'; + print $object->login; + } + print '</td>'; + print '</tr>'; - // API key - if(! empty($conf->api->enabled) && $user->admin) - { - print '<tr><td>'.$langs->trans("ApiKey").'</td>'; - print '<td>'; - print '<input class="minwidth300" maxsize="32" type="text" id="api_key" name="api_key" value="'.$object->api_key.'" autocomplete="off">'; - if (! empty($conf->use_javascript_ajax)) - print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"'); - print '</td></tr>'; - } + // Pass + print '<tr><td>'.$langs->trans("Password").'</td>'; + print '<td>'; + if ($object->ldap_sid) + { + $text=$langs->trans("DomainPassword"); + } + else if ($caneditpassword) + { + $text='<input size="12" maxlength="32" type="password" class="flat" name="password" value="'.$object->pass.'" autocomplete="off">'; + if ($dolibarr_main_authentication && $dolibarr_main_authentication == 'http') + { + $text=$form->textwithpicto($text,$langs->trans("DolibarrInHttpAuthenticationSoPasswordUseless",$dolibarr_main_authentication),1,'warning'); + } + } + else + { + $text=preg_replace('/./i','*',$object->pass); + } + print $text; + print "</td></tr>\n"; - // Administrator - print '<tr><td>'.$langs->trans("Administrator").'</td>'; - if ($object->socid > 0) - { - $langs->load("admin"); - print '<td>'; - print '<input type="hidden" name="admin" value="'.$object->admin.'">'.yn($object->admin); - print ' ('.$langs->trans("ExternalUser").')'; - print '</td></tr>'; - } - else - { - print '<td>'; - $nbAdmin = $user->getNbOfUsers('active','',1); - $nbSuperAdmin = $user->getNbOfUsers('active','superadmin',1); - //var_dump($nbAdmin); - //var_dump($nbSuperAdmin); - if ($user->admin // Need to be admin to allow downgrade of an admin - && ($user->id != $object->id) // Don't downgrade ourself - && ( - (empty($conf->multicompany->enabled) && $nbAdmin >= 1) - || (! empty($conf->multicompany->enabled) && ($object->entity > 0 || $nbSuperAdmin > 1)) // Don't downgrade a superadmin if alone - ) - ) - { - print $form->selectyesno('admin',$object->admin,1); - - if (! empty($conf->multicompany->enabled) && ! $user->entity && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) - { - if ($conf->use_javascript_ajax) - { - print '<script type="text/javascript"> + // API key + if(! empty($conf->api->enabled) && $user->admin) + { + print '<tr><td>'.$langs->trans("ApiKey").'</td>'; + print '<td>'; + print '<input class="minwidth300" maxsize="32" type="text" id="api_key" name="api_key" value="'.$object->api_key.'" autocomplete="off">'; + if (! empty($conf->use_javascript_ajax)) + print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"'); + print '</td></tr>'; + } + + // Administrator + print '<tr><td>'.$langs->trans("Administrator").'</td>'; + if ($object->socid > 0) + { + $langs->load("admin"); + print '<td>'; + print '<input type="hidden" name="admin" value="'.$object->admin.'">'.yn($object->admin); + print ' ('.$langs->trans("ExternalUser").')'; + print '</td></tr>'; + } + else + { + print '<td>'; + $nbAdmin = $user->getNbOfUsers('active','',1); + $nbSuperAdmin = $user->getNbOfUsers('active','superadmin',1); + //var_dump($nbAdmin); + //var_dump($nbSuperAdmin); + if ($user->admin // Need to be admin to allow downgrade of an admin + && ($user->id != $object->id) // Don't downgrade ourself + && ( + (empty($conf->multicompany->enabled) && $nbAdmin >= 1) + || (! empty($conf->multicompany->enabled) && ($object->entity > 0 || $nbSuperAdmin > 1)) // Don't downgrade a superadmin if alone + ) + ) + { + print $form->selectyesno('admin',$object->admin,1); + + if (! empty($conf->multicompany->enabled) && ! $user->entity && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + if ($conf->use_javascript_ajax) + { + print '<script type="text/javascript"> $(function() { var admin = $("select[name=admin]").val(); if (admin == 0) { @@ -2142,331 +2142,331 @@ else }); }); </script>'; - } - - $checked=(($object->admin && ! $object->entity) ? ' checked' : ''); - print '<input type="checkbox" name="superadmin" value="1"'.$checked.' /> '.$langs->trans("SuperAdministrator"); - } - } - else - { - $yn = yn($object->admin); - print '<input type="hidden" name="admin" value="'.$object->admin.'">'; - print '<input type="hidden" name="superadmin" value="'.(empty($object->entity) ? 1 : 0).'">'; - if (! empty($conf->multicompany->enabled) && empty($object->entity)) print $form->textwithpicto($yn,$langs->trans("DontDowngradeSuperAdmin"),1,'warning'); - else print $yn; - } - print '</td></tr>'; - } + } + + $checked=(($object->admin && ! $object->entity) ? ' checked' : ''); + print '<input type="checkbox" name="superadmin" value="1"'.$checked.' /> '.$langs->trans("SuperAdministrator"); + } + } + else + { + $yn = yn($object->admin); + print '<input type="hidden" name="admin" value="'.$object->admin.'">'; + print '<input type="hidden" name="superadmin" value="'.(empty($object->entity) ? 1 : 0).'">'; + if (! empty($conf->multicompany->enabled) && empty($object->entity)) print $form->textwithpicto($yn,$langs->trans("DontDowngradeSuperAdmin"),1,'warning'); + else print $yn; + } + print '</td></tr>'; + } - // Type - print '<tr><td>'.$langs->trans("Type").'</td>'; - print '<td>'; - if ($user->id == $object->id || ! $user->admin) - { - $type=$langs->trans("Internal"); - if ($object->socid) $type=$langs->trans("External"); - print $form->textwithpicto($type,$langs->trans("InternalExternalDesc")); - if ($object->ldap_sid) print ' ('.$langs->trans("DomainUser").')'; - } - else + // Type + print '<tr><td>'.$langs->trans("Type").'</td>'; + print '<td>'; + if ($user->id == $object->id || ! $user->admin) + { + $type=$langs->trans("Internal"); + if ($object->socid) $type=$langs->trans("External"); + print $form->textwithpicto($type,$langs->trans("InternalExternalDesc")); + if ($object->ldap_sid) print ' ('.$langs->trans("DomainUser").')'; + } + else { $type=0; - if ($object->contact_id) $type=$object->contact_id; - print $form->selectcontacts(0,$type,'contactid',2,'','',1,'',false,1); - if ($object->ldap_sid) print ' ('.$langs->trans("DomainUser").')'; - } - print '</td></tr>'; + if ($object->contact_id) $type=$object->contact_id; + print $form->selectcontacts(0,$type,'contactid',2,'','',1,'',false,1); + if ($object->ldap_sid) print ' ('.$langs->trans("DomainUser").')'; + } + print '</td></tr>'; // Address - print '<tr><td class="tdtop">'.fieldLabel('Address','address').'</td>'; - print '<td><textarea name="address" id="address" class="quatrevingtpercent" rows="3" wrap="soft">'; - print $object->address; - print '</textarea></td></tr>'; + print '<tr><td class="tdtop">'.fieldLabel('Address','address').'</td>'; + print '<td><textarea name="address" id="address" class="quatrevingtpercent" rows="3" wrap="soft">'; + print $object->address; + print '</textarea></td></tr>'; - // Zip - print '<tr><td>'.fieldLabel('Zip','zipcode').'</td><td>'; - print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6); - print '</td></tr>'; + // Zip + print '<tr><td>'.fieldLabel('Zip','zipcode').'</td><td>'; + print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6); + print '</td></tr>'; // Town print '<tr><td>'.fieldLabel('Town','town').'</td><td>'; - print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id')); - print '</td></tr>'; + print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id')); + print '</td></tr>'; - // Country - print '<tr><td>'.fieldLabel('Country','selectcounty_id').'</td><td>'; - print $form->select_country((GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id),'country_id'); - if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); - print '</td></tr>'; + // Country + print '<tr><td>'.fieldLabel('Country','selectcounty_id').'</td><td>'; + print $form->select_country((GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id),'country_id'); + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + print '</td></tr>'; - // State - if (empty($conf->global->USER_DISABLE_STATE)) - { - print '<tr><td class="tdoverflow">'.fieldLabel('State','state_id').'</td><td>'; - print $formcompany->select_state($object->state_id,$object->country_code, 'state_id'); - print '</td></tr>'; - } + // State + if (empty($conf->global->USER_DISABLE_STATE)) + { + print '<tr><td class="tdoverflow">'.fieldLabel('State','state_id').'</td><td>'; + print $formcompany->select_state($object->state_id,$object->country_code, 'state_id'); + print '</td></tr>'; + } - // Tel pro - print "<tr>".'<td>'.$langs->trans("PhonePro").'</td>'; - print '<td>'; - if ($caneditfield && empty($object->ldap_sid)) - { - print '<input size="20" type="text" name="office_phone" class="flat" value="'.$object->office_phone.'">'; - } - else - { - print '<input type="hidden" name="office_phone" value="'.$object->office_phone.'">'; - print $object->office_phone; - } - print '</td></tr>'; + // Tel pro + print "<tr>".'<td>'.$langs->trans("PhonePro").'</td>'; + print '<td>'; + if ($caneditfield && empty($object->ldap_sid)) + { + print '<input size="20" type="text" name="office_phone" class="flat" value="'.$object->office_phone.'">'; + } + else + { + print '<input type="hidden" name="office_phone" value="'.$object->office_phone.'">'; + print $object->office_phone; + } + print '</td></tr>'; - // Tel mobile - print "<tr>".'<td>'.$langs->trans("PhoneMobile").'</td>'; - print '<td>'; - if ($caneditfield && empty($object->ldap_sid)) - { - print '<input size="20" type="text" name="user_mobile" class="flat" value="'.$object->user_mobile.'">'; - } - else - { - print '<input type="hidden" name="user_mobile" value="'.$object->user_mobile.'">'; - print $object->user_mobile; - } - print '</td></tr>'; + // Tel mobile + print "<tr>".'<td>'.$langs->trans("PhoneMobile").'</td>'; + print '<td>'; + if ($caneditfield && empty($object->ldap_sid)) + { + print '<input size="20" type="text" name="user_mobile" class="flat" value="'.$object->user_mobile.'">'; + } + else + { + print '<input type="hidden" name="user_mobile" value="'.$object->user_mobile.'">'; + print $object->user_mobile; + } + print '</td></tr>'; - // Fax - print "<tr>".'<td>'.$langs->trans("Fax").'</td>'; - print '<td>'; - if ($caneditfield && empty($object->ldap_sid)) - { - print '<input size="20" type="text" name="office_fax" class="flat" value="'.$object->office_fax.'">'; - } - else - { - print '<input type="hidden" name="office_fax" value="'.$object->office_fax.'">'; - print $object->office_fax; - } - print '</td></tr>'; + // Fax + print "<tr>".'<td>'.$langs->trans("Fax").'</td>'; + print '<td>'; + if ($caneditfield && empty($object->ldap_sid)) + { + print '<input size="20" type="text" name="office_fax" class="flat" value="'.$object->office_fax.'">'; + } + else + { + print '<input type="hidden" name="office_fax" value="'.$object->office_fax.'">'; + print $object->office_fax; + } + print '</td></tr>'; - // Skype - if (! empty($conf->skype->enabled)) - { - print '<tr><td>'.$langs->trans("Skype").'</td>'; - print '<td>'; - if ($caneditfield && empty($object->ldap_sid)) - { - print '<input size="40" type="text" name="skype" class="flat" value="'.$object->skype.'">'; - } - else - { - print '<input type="hidden" name="skype" value="'.$object->skype.'">'; - print $object->skype; - } - print '</td></tr>'; - } + // Skype + if (! empty($conf->skype->enabled)) + { + print '<tr><td>'.$langs->trans("Skype").'</td>'; + print '<td>'; + if ($caneditfield && empty($object->ldap_sid)) + { + print '<input size="40" type="text" name="skype" class="flat" value="'.$object->skype.'">'; + } + else + { + print '<input type="hidden" name="skype" value="'.$object->skype.'">'; + print $object->skype; + } + print '</td></tr>'; + } - // EMail - print "<tr>".'<td'.(! empty($conf->global->USER_MAIL_REQUIRED)?' class="fieldrequired"':'').'>'.$langs->trans("EMail").'</td>'; - print '<td>'; - if ($caneditfield && empty($object->ldap_sid)) - { - print '<input class="minwidth100" type="text" name="email" class="flat" value="'.$object->email.'">'; - } - else - { - print '<input type="hidden" name="email" value="'.$object->email.'">'; - print $object->email; - } - print '</td></tr>'; + // EMail + print "<tr>".'<td'.(! empty($conf->global->USER_MAIL_REQUIRED)?' class="fieldrequired"':'').'>'.$langs->trans("EMail").'</td>'; + print '<td>'; + if ($caneditfield && empty($object->ldap_sid)) + { + print '<input class="minwidth100" type="text" name="email" class="flat" value="'.$object->email.'">'; + } + else + { + print '<input type="hidden" name="email" value="'.$object->email.'">'; + print $object->email; + } + print '</td></tr>'; - // OpenID url - if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file->main_authentication) && ! empty($conf->global->MAIN_OPENIDURL_PERUSER)) - { - print "<tr>".'<td>'.$langs->trans("OpenIDURL").'</td>'; - print '<td>'; - if ($caneditfield) - { - print '<input class="minwidth100" type="url" name="openid" class="flat" value="'.$object->openid.'">'; - } - else - { - print '<input type="hidden" name="openid" value="'.$object->openid.'">'; - print $object->openid; - } - print '</td></tr>'; - } + // OpenID url + if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file->main_authentication) && ! empty($conf->global->MAIN_OPENIDURL_PERUSER)) + { + print "<tr>".'<td>'.$langs->trans("OpenIDURL").'</td>'; + print '<td>'; + if ($caneditfield) + { + print '<input class="minwidth100" type="url" name="openid" class="flat" value="'.$object->openid.'">'; + } + else + { + print '<input type="hidden" name="openid" value="'.$object->openid.'">'; + print $object->openid; + } + print '</td></tr>'; + } - // Accountancy code - if ($conf->accounting->enabled) - { - print "<tr>"; - print '<td>'.$langs->trans("AccountancyCode").'</td>'; - print '<td>'; - if ($caneditfield) - { - print '<input size="30" type="text" class="flat" name="accountancy_code" value="'.$object->accountancy_code.'">'; - } - else - { - print '<input type="hidden" name="accountancy_code" value="'.$object->accountancy_code.'">'; - print $object->accountancy_code; - } - print '</td>'; - print "</tr>"; - } + // Accountancy code + if ($conf->accounting->enabled) + { + print "<tr>"; + print '<td>'.$langs->trans("AccountancyCode").'</td>'; + print '<td>'; + if ($caneditfield) + { + print '<input size="30" type="text" class="flat" name="accountancy_code" value="'.$object->accountancy_code.'">'; + } + else + { + print '<input type="hidden" name="accountancy_code" value="'.$object->accountancy_code.'">'; + print $object->accountancy_code; + } + print '</td>'; + print "</tr>"; + } - // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) + // TODO Move this into tab RH (HierarchicalResponsible must be on both tab) - // Hierarchy - print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>'; - print '<td>'; - if ($caneditfield) - { - print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300'); - } - else - { - print '<input type="hidden" name="fk_user" value="'.$object->fk_user.'">'; - $huser=new User($db); - $huser->fetch($object->fk_user); - print $huser->getNomUrl(1); - } - print '</td>'; - print "</tr>\n"; + // Hierarchy + print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>'; + print '<td>'; + if ($caneditfield) + { + print $form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300'); + } + else + { + print '<input type="hidden" name="fk_user" value="'.$object->fk_user.'">'; + $huser=new User($db); + $huser->fetch($object->fk_user); + print $huser->getNomUrl(1); + } + print '</td>'; + print "</tr>\n"; - if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) - || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) - { - $langs->load("salaries"); - - // THM - print '<tr><td>'; - $text=$langs->trans("THM"); - print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); - print '</td>'; - print '<td>'; - print '<input size="8" type="text" name="thm" value="'.price2num(GETPOST('thm')?GETPOST('thm'):$object->thm).'">'; - print '</td>'; - print "</tr>\n"; - - // TJM - print '<tr><td>'; - $text=$langs->trans("TJM"); - print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classthm'); - print '</td>'; - print '<td>'; - print '<input size="8" type="text" name="tjm" value="'.price2num(GETPOST('tjm')?GETPOST('tjm'):$object->tjm).'">'; - print '</td>'; - print "</tr>\n"; - - // Salary - print '<tr><td>'.$langs->trans("Salary").'</td>'; - print '<td>'; - print '<input size="8" type="text" name="salary" value="'.price2num(GETPOST('salary')?GETPOST('salary'):$object->salary).'">'; - print '</td>'; - print "</tr>\n"; - } + if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) + || (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))) + { + $langs->load("salaries"); + + // THM + print '<tr><td>'; + $text=$langs->trans("THM"); + print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm'); + print '</td>'; + print '<td>'; + print '<input size="8" type="text" name="thm" value="'.price2num(GETPOST('thm')?GETPOST('thm'):$object->thm).'">'; + print '</td>'; + print "</tr>\n"; + + // TJM + print '<tr><td>'; + $text=$langs->trans("TJM"); + print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classthm'); + print '</td>'; + print '<td>'; + print '<input size="8" type="text" name="tjm" value="'.price2num(GETPOST('tjm')?GETPOST('tjm'):$object->tjm).'">'; + print '</td>'; + print "</tr>\n"; + + // Salary + print '<tr><td>'.$langs->trans("Salary").'</td>'; + print '<td>'; + print '<input size="8" type="text" name="salary" value="'.price2num(GETPOST('salary')?GETPOST('salary'):$object->salary).'">'; + print '</td>'; + print "</tr>\n"; + } - // Weeklyhours - print '<tr><td>'.$langs->trans("WeeklyHours").'</td>'; - print '<td>'; - print '<input size="8" type="text" name="weeklyhours" value="'.price2num(GETPOST('weeklyhours')?GETPOST('weeklyhours'):$object->weeklyhours).'">'; - print '</td>'; - print "</tr>\n"; + // Weeklyhours + print '<tr><td>'.$langs->trans("WeeklyHours").'</td>'; + print '<td>'; + print '<input size="8" type="text" name="weeklyhours" value="'.price2num(GETPOST('weeklyhours')?GETPOST('weeklyhours'):$object->weeklyhours).'">'; + print '</td>'; + print "</tr>\n"; - // Date employment - print '<tr><td>'.$langs->trans("DateEmployment").'</td>'; - print '<td>'; + // Date employment + print '<tr><td>'.$langs->trans("DateEmployment").'</td>'; + print '<td>'; echo $form->select_date(GETPOST('dateemployment')?GETPOST('dateemployment'):$object->dateemployment,'dateemployment',0,0,1,'form'.'dateemployment',1,0,1); print '</td>'; - print "</tr>\n"; - - // User color - if (! empty($conf->agenda->enabled)) - { - print '<tr><td>'.$langs->trans("ColorUser").'</td>'; - print '<td>'; - print $formother->selectColor(GETPOST('color')?GETPOST('color'):$object->color, 'color', null, 1, '', 'hideifnotset'); - print '</td></tr>'; - } - - // Photo - print '<tr>'; - print '<td>'.$langs->trans("Photo").'</td>'; - print '<td>'; - print $form->showphoto('userphoto',$object,60,0,$caneditfield,'photowithmargin','small'); - print '</td>'; - print '</tr>'; - - // Categories - if (!empty( $conf->categorie->enabled ) && !empty( $user->rights->categorie->lire )) - { - print '<tr><td>' . fieldLabel( 'Categories', 'usercats' ) . '</td>'; - print '<td>'; - $cate_arbo = $form->select_all_categories( Categorie::TYPE_CONTACT, null, null, null, null, 1 ); - $c = new Categorie( $db ); - $cats = $c->containing($object->id, Categorie::TYPE_USER); - foreach ($cats as $cat) { - $arrayselected[] = $cat->id; - } - print $form->multiselectarray( 'usercats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%' ); - print "</td></tr>"; - } - - // Status - print '<tr><td>'.$langs->trans("Status").'</td>'; - print '<td>'; - print $object->getLibStatut(4); - print '</td></tr>'; - - // Company / Contact - if (! empty($conf->societe->enabled)) - { - print '<tr><td width="25%">'.$langs->trans("LinkToCompanyContact").'</td>'; - print '<td>'; - if ($object->socid > 0) - { - $societe = new Societe($db); - $societe->fetch($object->socid); - print $societe->getNomUrl(1,''); - if ($object->contactid) - { - $contact = new Contact($db); - $contact->fetch($object->contactid); - print ' / <a href="'.DOL_URL_ROOT.'/contact/card.php?id='.$object->contactid.'">'.img_object($langs->trans("ShowContact"),'contact').' '.dol_trunc($contact->getFullName($langs),32).'</a>'; - } - } - else - { - print $langs->trans("ThisUserIsNot"); - } - print ' ('.$langs->trans("UseTypeFieldToChange").')'; - print '</td>'; - print "</tr>\n"; - } + print "</tr>\n"; - // Module Adherent - if (! empty($conf->adherent->enabled)) - { - $langs->load("members"); - print '<tr><td width="25%">'.$langs->trans("LinkedToDolibarrMember").'</td>'; - print '<td>'; - if ($object->fk_member) - { - $adh=new Adherent($db); - $adh->fetch($object->fk_member); - $adh->ref=$adh->login; // Force to show login instead of id - print $adh->getNomUrl(1); - } - else - { - print $langs->trans("UserNotLinkedToMember"); - } - print '</td>'; - print "</tr>\n"; - } + // User color + if (! empty($conf->agenda->enabled)) + { + print '<tr><td>'.$langs->trans("ColorUser").'</td>'; + print '<td>'; + print $formother->selectColor(GETPOST('color')?GETPOST('color'):$object->color, 'color', null, 1, '', 'hideifnotset'); + print '</td></tr>'; + } + + // Photo + print '<tr>'; + print '<td>'.$langs->trans("Photo").'</td>'; + print '<td>'; + print $form->showphoto('userphoto',$object,60,0,$caneditfield,'photowithmargin','small'); + print '</td>'; + print '</tr>'; + + // Categories + if (!empty( $conf->categorie->enabled ) && !empty( $user->rights->categorie->lire )) + { + print '<tr><td>' . fieldLabel( 'Categories', 'usercats' ) . '</td>'; + print '<td>'; + $cate_arbo = $form->select_all_categories( Categorie::TYPE_CONTACT, null, null, null, null, 1 ); + $c = new Categorie( $db ); + $cats = $c->containing($object->id, Categorie::TYPE_USER); + foreach ($cats as $cat) { + $arrayselected[] = $cat->id; + } + print $form->multiselectarray( 'usercats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%' ); + print "</td></tr>"; + } + + // Status + print '<tr><td>'.$langs->trans("Status").'</td>'; + print '<td>'; + print $object->getLibStatut(4); + print '</td></tr>'; + + // Company / Contact + if (! empty($conf->societe->enabled)) + { + print '<tr><td width="25%">'.$langs->trans("LinkToCompanyContact").'</td>'; + print '<td>'; + if ($object->socid > 0) + { + $societe = new Societe($db); + $societe->fetch($object->socid); + print $societe->getNomUrl(1,''); + if ($object->contactid) + { + $contact = new Contact($db); + $contact->fetch($object->contactid); + print ' / <a href="'.DOL_URL_ROOT.'/contact/card.php?id='.$object->contactid.'">'.img_object($langs->trans("ShowContact"),'contact').' '.dol_trunc($contact->getFullName($langs),32).'</a>'; + } + } + else + { + print $langs->trans("ThisUserIsNot"); + } + print ' ('.$langs->trans("UseTypeFieldToChange").')'; + print '</td>'; + print "</tr>\n"; + } + + // Module Adherent + if (! empty($conf->adherent->enabled)) + { + $langs->load("members"); + print '<tr><td width="25%">'.$langs->trans("LinkedToDolibarrMember").'</td>'; + print '<td>'; + if ($object->fk_member) + { + $adh=new Adherent($db); + $adh->fetch($object->fk_member); + $adh->ref=$adh->login; // Force to show login instead of id + print $adh->getNomUrl(1); + } + else + { + print $langs->trans("UserNotLinkedToMember"); + } + print '</td>'; + print "</tr>\n"; + } if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) { @@ -2482,9 +2482,9 @@ else print '</td></tr>'; } - // Multicompany - // This is now done with hook formObjectOptions - /* + // Multicompany + // This is now done with hook formObjectOptions + /* // TODO check if user not linked with the current entity before change entity (thirdparty, invoice, etc.) !! if (! empty($conf->multicompany->enabled) && is_object($mc)) { @@ -2501,82 +2501,82 @@ else } */ - // Other attributes - $parameters=array('colspan' => ' colspan="2"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit'); - } + // Other attributes + $parameters=array('colspan' => ' colspan="2"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit'); + } - // Signature - print "<tr>".'<td class="tdtop">'.$langs->trans("Signature").'</td>'; - print '<td>'; - if ($caneditfield) - { - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('signature',$object->signature,'',138,'dolibarr_mailings','In',false,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); - print $doleditor->Create(1); - } - else - { - print dol_htmlentitiesbr($object->signature); - } - print '</td></tr>'; + // Signature + print "<tr>".'<td class="tdtop">'.$langs->trans("Signature").'</td>'; + print '<td>'; + if ($caneditfield) + { + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('signature',$object->signature,'',138,'dolibarr_mailings','In',false,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,'90%'); + print $doleditor->Create(1); + } + else + { + print dol_htmlentitiesbr($object->signature); + } + print '</td></tr>'; - print '</table>'; + print '</table>'; - dol_fiche_end(); + dol_fiche_end(); - print '<div align="center">'; - print '<input value="'.$langs->trans("Save").'" class="button" type="submit" name="save">'; - print ' '; - print '<input value="'.$langs->trans("Cancel").'" class="button" type="submit" name="cancel">'; - print '</div>'; + print '<div align="center">'; + print '<input value="'.$langs->trans("Save").'" class="button" type="submit" name="save">'; + print ' '; + print '<input value="'.$langs->trans("Cancel").'" class="button" type="submit" name="cancel">'; + print '</div>'; - print '</form>'; - } + print '</form>'; + } - if ($action != 'edit') - { - print '<div class="fichecenter"><div class="fichehalfleft">'; - /* + if ($action != 'edit') + { + print '<div class="fichecenter"><div class="fichehalfleft">'; + /* * Documents generes */ - $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->user->user->creer; - $delallowed = $user->rights->user->user->supprimer; + $filename = dol_sanitizeFileName($object->ref); + $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->user->user->creer; + $delallowed = $user->rights->user->user->supprimer; - print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - $somethingshown = $formfile->numoffiles; + print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + $somethingshown = $formfile->numoffiles; - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object, null, null); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, null); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '</div><div class="fichehalfright"><div class="ficheaddleft">'; + print '</div><div class="fichehalfright"><div class="ficheaddleft">'; - // List of actions on element - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'user', $socid, 1); + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'user', $socid, 1); - print '</div></div></div>'; - } + print '</div></div></div>'; + } if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) $ldap->close(); - } + } } if (! empty($conf->api->enabled) && ! empty($conf->use_javascript_ajax)) { - print "\n".'<script type="text/javascript">'; - print '$(document).ready(function () { + print "\n".'<script type="text/javascript">'; + print '$(document).ready(function () { $("#generate_api_key").click(function() { $.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", { action: \'getrandompassword\', @@ -2587,7 +2587,7 @@ if (! empty($conf->api->enabled) && ! empty($conf->use_javascript_ajax)) }); }); });'; - print '</script>'; + print '</script>'; } llxFooter(); diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index a98cd859dc58fdadbd5f25c192ec97fea96dfb7a..49e95cd40a39abe2b70c7967d31ca8255f02b558 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -53,17 +53,17 @@ class User extends CommonObject public $job; public $signature; public $address; - public $zip; - public $town; - public $state_id; - public $state_code; - public $state; + public $zip; + public $town; + public $state_id; + public $state_code; + public $state; public $office_phone; public $office_fax; public $user_mobile; public $admin; public $login; - public $api_key; + public $api_key; public $entity; //! Clear password in memory @@ -202,22 +202,22 @@ class User extends CommonObject $sql.= " u.dateemployment,"; $sql.= " u.ref_int, u.ref_ext,"; $sql.= " u.default_range, u.default_c_exp_tax_cat,"; - $sql.= " c.code as country_code, c.label as country,"; - $sql.= " d.code_departement as state_code, d.nom as state"; + $sql.= " c.code as country_code, c.label as country,"; + $sql.= " d.code_departement as state_code, d.nom as state"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON u.fk_country = c.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON u.fk_state = d.rowid"; if ($entity < 0) { - if ((empty($conf->multicompany->enabled) || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) && (! empty($user->entity))) - { - $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; - } - else - { - $sql.= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database - } + if ((empty($conf->multicompany->enabled) || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) && (! empty($user->entity))) + { + $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; + } + else + { + $sql.= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database + } } else // The fetch was forced on an entity { @@ -266,19 +266,19 @@ class User extends CommonObject $this->pass_indatabase_crypted = $obj->pass_crypted; $this->pass = $obj->pass; $this->pass_temp = $obj->pass_temp; - $this->api_key = $obj->api_key; + $this->api_key = $obj->api_key; - $this->address = $obj->address; - $this->zip = $obj->zip; - $this->town = $obj->town; + $this->address = $obj->address; + $this->zip = $obj->zip; + $this->town = $obj->town; - $this->country_id = $obj->country_id; - $this->country_code = $obj->country_id?$obj->country_code:''; - //$this->country = $obj->country_id?($langs->trans('Country'.$obj->country_code)!='Country'.$obj->country_code?$langs->transnoentities('Country'.$obj->country_code):$obj->country):''; + $this->country_id = $obj->country_id; + $this->country_code = $obj->country_id?$obj->country_code:''; + //$this->country = $obj->country_id?($langs->trans('Country'.$obj->country_code)!='Country'.$obj->country_code?$langs->transnoentities('Country'.$obj->country_code):$obj->country):''; - $this->state_id = $obj->state_id; - $this->state_code = $obj->state_code; - $this->state = ($obj->state!='-'?$obj->state:''); + $this->state_id = $obj->state_id; + $this->state_code = $obj->state_code; + $this->state = ($obj->state!='-'?$obj->state:''); $this->office_phone = $obj->office_phone; $this->office_fax = $obj->office_fax; @@ -349,7 +349,7 @@ class User extends CommonObject // To get back the global configuration unique to the user if ($loadpersonalconf) { - // Load user->conf for user + // Load user->conf for user $sql = "SELECT param, value FROM ".MAIN_DB_PREFIX."user_param"; $sql.= " WHERE fk_user = ".$this->id; $sql.= " AND entity = ".$conf->entity; @@ -382,35 +382,35 @@ class User extends CommonObject $resql = $this->db->query($sql); if ($resql) { - while ($obj = $this->db->fetch_object($resql)) - { - if (! empty($obj->page) && ! empty($obj->type) && ! empty($obj->param)) - { - // $obj->page is relative URL with or without params - // $obj->type can be 'filters', 'sortorder', 'createform', ... - // $obj->param is key or param - $pagewithoutquerystring=$obj->page; - $pagequeries=''; - if (preg_match('/^([^\?]+)\?(.*)$/', $pagewithoutquerystring, $reg)) // There is query param - { - $pagewithoutquerystring=$reg[1]; - $pagequeries=$reg[2]; - } - $this->default_values[$pagewithoutquerystring][$obj->type][$pagequeries?$pagequeries:'_noquery_'][$obj->param]=$obj->value; - //if ($pagequeries) $this->default_values[$pagewithoutquerystring][$obj->type.'_queries']=$pagequeries; - } - } - // Sort by key, so _noquery_ is last - if(!empty($this->default_values)) { - foreach($this->default_values as $a => $b) - { - foreach($b as $c => $d) - { - krsort($this->default_values[$a][$c]); - } - } - } - $this->db->free($resql); + while ($obj = $this->db->fetch_object($resql)) + { + if (! empty($obj->page) && ! empty($obj->type) && ! empty($obj->param)) + { + // $obj->page is relative URL with or without params + // $obj->type can be 'filters', 'sortorder', 'createform', ... + // $obj->param is key or param + $pagewithoutquerystring=$obj->page; + $pagequeries=''; + if (preg_match('/^([^\?]+)\?(.*)$/', $pagewithoutquerystring, $reg)) // There is query param + { + $pagewithoutquerystring=$reg[1]; + $pagequeries=$reg[2]; + } + $this->default_values[$pagewithoutquerystring][$obj->type][$pagequeries?$pagequeries:'_noquery_'][$obj->param]=$obj->value; + //if ($pagequeries) $this->default_values[$pagewithoutquerystring][$obj->type.'_queries']=$pagequeries; + } + } + // Sort by key, so _noquery_ is last + if(!empty($this->default_values)) { + foreach($this->default_values as $a => $b) + { + foreach($b as $c => $d) + { + krsort($this->default_values[$a][$c]); + } + } + } + $this->db->free($resql); } else { @@ -429,7 +429,7 @@ class User extends CommonObject * @param string $allmodule Ajouter tous les droits du module allmodule * @param string $allperms Ajouter tous les droits du module allmodule, perms allperms * @param int $entity Entity to use - * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers * @return int > 0 if OK, < 0 if KO */ function addrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0) @@ -515,12 +515,12 @@ class User extends CommonObject if (! $error && ! $notrigger) { - $this->context = array('audit'=>$langs->trans("PermissionsAdd")); + $this->context = array('audit'=>$langs->trans("PermissionsAdd")); - // Call trigger - $result=$this->call_trigger('USER_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers } if ($error) { @@ -542,7 +542,7 @@ class User extends CommonObject * @param string $allmodule Retirer tous les droits du module allmodule * @param string $allperms Retirer tous les droits du module allmodule, perms allperms * @param int $entity Entity to use - * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers * @return int > 0 if OK, < 0 if OK */ function delrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0) @@ -625,12 +625,12 @@ class User extends CommonObject if (! $error && ! $notrigger) { - $this->context = array('audit'=>$langs->trans("PermissionsDelete")); + $this->context = array('audit'=>$langs->trans("PermissionsDelete")); - // Call trigger - $result=$this->call_trigger('USER_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers } if ($error) { @@ -840,10 +840,10 @@ class User extends CommonObject dol_syslog(get_class($this)."::setstatus", LOG_DEBUG); if ($result) { - // Call trigger - $result=$this->call_trigger('USER_ENABLEDISABLE',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_ENABLEDISABLE',$user); + if ($result < 0) { $error++; } + // End call triggers } if ($error) @@ -926,7 +926,7 @@ class User extends CommonObject if (! $error && ! $this->db->query($sql)) { $error++; - $this->error = $this->db->lasterror(); + $this->error = $this->db->lasterror(); } // Remove group @@ -934,7 +934,7 @@ class User extends CommonObject if (! $error && ! $this->db->query($sql)) { $error++; - $this->error = $this->db->lasterror(); + $this->error = $this->db->lasterror(); } // If contact, remove link @@ -944,44 +944,44 @@ class User extends CommonObject if (! $error && ! $this->db->query($sql)) { $error++; - $this->error = $this->db->lasterror(); + $this->error = $this->db->lasterror(); } } // Remove extrafields if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used - { + { $result=$this->deleteExtraFields(); if ($result < 0) { - $error++; - dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); - } - } + $error++; + dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); + } + } // Remove user - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->id; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $error++; - $this->error = $this->db->lasterror(); - } - } + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->id; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $error++; + $this->error = $this->db->lasterror(); + } + } if (! $error) { - // Call trigger - $result=$this->call_trigger('USER_DELETE',$user); - if ($result < 0) - { - $error++; - $this->db->rollback(); - return -1; - } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_DELETE',$user); + if ($result < 0) + { + $error++; + $this->db->rollback(); + return -1; + } + // End call triggers $this->db->commit(); return 1; @@ -1089,10 +1089,10 @@ class User extends CommonObject if (! $notrigger) { - // Call trigger - $result=$this->call_trigger('USER_CREATE',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers } if (! $error) @@ -1145,7 +1145,7 @@ class User extends CommonObject $this->firstname = $contact->firstname; $this->gender = $contact->gender; $this->email = $contact->email; - $this->skype = $contact->skype; + $this->skype = $contact->skype; $this->office_phone = $contact->phone_pro; $this->office_fax = $contact->fax; $this->user_mobile = $contact->phone_mobile; @@ -1154,7 +1154,7 @@ class User extends CommonObject $this->town = $contact->town; $this->state_id = $contact->state_id; $this->country_id = $contact->country_id; - $this->employee = 0; + $this->employee = 0; if (empty($login)) $login=strtolower(substr($contact->firstname, 0, 4)) . strtolower(substr($contact->lastname, 0, 4)); $this->login = $login; @@ -1176,10 +1176,10 @@ class User extends CommonObject { $this->context['createfromcontact']='createfromcontact'; - // Call trigger - $result=$this->call_trigger('USER_CREATE',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_CREATE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers $this->db->commit(); return $this->id; @@ -1345,12 +1345,12 @@ class User extends CommonObject $this->gender = trim($this->gender); $this->birth = trim($this->birth); $this->pass = trim($this->pass); - $this->api_key = trim($this->api_key); + $this->api_key = trim($this->api_key); $this->address = $this->address?trim($this->address):trim($this->address); - $this->zip = $this->zip?trim($this->zip):trim($this->zip); - $this->town = $this->town?trim($this->town):trim($this->town); - $this->state_id = trim($this->state_id); - $this->country_id = ($this->country_id > 0)?$this->country_id:0; + $this->zip = $this->zip?trim($this->zip):trim($this->zip); + $this->town = $this->town?trim($this->town):trim($this->town); + $this->state_id = trim($this->state_id); + $this->country_id = ($this->country_id > 0)?$this->country_id:0; $this->office_phone = trim($this->office_phone); $this->office_fax = trim($this->office_fax); $this->user_mobile = trim($this->user_mobile); @@ -1390,7 +1390,7 @@ class User extends CommonObject $sql.= ", firstname = '".$this->db->escape($this->firstname)."'"; $sql.= ", employee = ".$this->employee; $sql.= ", login = '".$this->db->escape($this->login)."'"; - $sql.= ", api_key = ".($this->api_key ? "'".$this->db->escape($this->api_key)."'" : "null"); + $sql.= ", api_key = ".($this->api_key ? "'".$this->db->escape($this->api_key)."'" : "null"); $sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman' $sql.= ", birth=".(strval($this->birth)!='' ? "'".$this->db->idate($this->birth)."'" : 'null'); if (! empty($user->admin)) $sql.= ", admin = ".$this->admin; // admin flag can be set/unset only by an admin user @@ -1445,7 +1445,7 @@ class User extends CommonObject if ($this->fk_member > 0) { dol_syslog(get_class($this)."::update remove link with member. We will recreate it later", LOG_DEBUG); - $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member; + $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member; $resql = $this->db->query($sql); if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; } } @@ -1459,7 +1459,7 @@ class User extends CommonObject { if ($this->fk_member > 0 && ! $nosyncmember) { - dol_syslog(get_class($this)."::update user is linked with a member. We try to update member too.", LOG_DEBUG); + dol_syslog(get_class($this)."::update user is linked with a member. We try to update member too.", LOG_DEBUG); require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; @@ -1491,10 +1491,10 @@ class User extends CommonObject $adh->user_login=$this->login; $result=$adh->update($user,0,1,0); - if ($result < 0) + if ($result < 0) { - $this->error=$adh->error; - $this->errors=$adh->errors; + $this->error=$adh->error; + $this->errors=$adh->errors; dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR); $error++; } @@ -1522,10 +1522,10 @@ class User extends CommonObject if (! $error && ! $notrigger) { - // Call trigger - $result=$this->call_trigger('USER_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers } if (! $error) @@ -1612,11 +1612,11 @@ class User extends CommonObject // Mise a jour if (! $changelater) { - if (! is_object($this->oldcopy)) $this->oldcopy = clone $this; + if (! is_object($this->oldcopy)) $this->oldcopy = clone $this; - $this->db->begin(); + $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."user"; + $sql = "UPDATE ".MAIN_DB_PREFIX."user"; $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."',"; $sql.= " pass_temp = null"; if (! empty($conf->global->DATABASE_PWD_ENCRYPTED)) @@ -1669,10 +1669,10 @@ class User extends CommonObject if (! $error && ! $notrigger) { - // Call trigger - $result=$this->call_trigger('USER_NEW_PASSWORD',$user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_NEW_PASSWORD',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -1; } + // End call triggers } $this->db->commit(); @@ -1680,13 +1680,13 @@ class User extends CommonObject } else { - $this->db->rollback(); + $this->db->rollback(); return 0; } } else { - $this->db->rollback(); + $this->db->rollback(); dol_print_error($this->db); return -1; } @@ -1791,19 +1791,19 @@ class User extends CommonObject dol_syslog(get_class($this)."::send_password changelater is on, url=".$url); } - $mailfile = new CMailFile( - $subject, - $this->email, - $conf->notification->email_from, - $mesg, - array(), - array(), - array(), - '', - '', - 0, - $msgishtml - ); + $mailfile = new CMailFile( + $subject, + $this->email, + $conf->notification->email_from, + $mesg, + array(), + array(), + array(), + '', + '', + 0, + $msgishtml + ); if ($mailfile->sendfile()) { @@ -1934,13 +1934,13 @@ class User extends CommonObject { if (! $error && ! $notrigger) { - $this->newgroupid=$group; // deprecated. Remove this. - $this->context = array('audit'=>$langs->trans("UserSetInGroup"), 'newgroupid'=>$group); + $this->newgroupid=$group; // deprecated. Remove this. + $this->context = array('audit'=>$langs->trans("UserSetInGroup"), 'newgroupid'=>$group); - // Call trigger - $result=$this->call_trigger('USER_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers } if (! $error) @@ -1989,13 +1989,13 @@ class User extends CommonObject { if (! $error && ! $notrigger) { - $this->oldgroupid=$group; // deprecated. Remove this. - $this->context = array('audit'=>$langs->trans("UserRemovedFromGroup"), 'oldgroupid'=>$group); + $this->oldgroupid=$group; // deprecated. Remove this. + $this->context = array('audit'=>$langs->trans("UserRemovedFromGroup"), 'oldgroupid'=>$group); - // Call trigger - $result=$this->call_trigger('USER_MODIFY',$user); - if ($result < 0) { $error++; } - // End call triggers + // Call trigger + $result=$this->call_trigger('USER_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers } if (! $error) @@ -2027,7 +2027,7 @@ class User extends CommonObject * @param int $width Width of image * @param int $height Height of image * @param string $cssclass Force a css class - * @param string $imagesize 'mini', 'small' or '' (original) + * @param string $imagesize 'mini', 'small' or '' (original) * @return string String with URL link */ function getPhotoUrl($width, $height, $cssclass='', $imagesize='') @@ -2035,10 +2035,10 @@ class User extends CommonObject $result=''; $result.='<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">'; - $result.=Form::showphoto('userphoto', $this, $width, $height, 0, $cssclass, $imagesize); - $result.='</a>'; + $result.=Form::showphoto('userphoto', $this, $width, $height, 0, $cssclass, $imagesize); + $result.='</a>'; - return $result; + return $result; } /** @@ -2047,13 +2047,13 @@ class User extends CommonObject * * @param int $withpictoimg Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) * @param string $option On what the link point to - * @param integer $infologin Add complete info tooltip - * @param integer $notooltip 1=Disable tooltip on picto and name - * @param int $maxlen Max length of visible user name - * @param int $hidethirdpartylogo Hide logo of thirdparty if user is external user - * @param string $mode ''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login - * @param string $morecss Add more css on link - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @param integer $infologin Add complete info tooltip + * @param integer $notooltip 1=Disable tooltip on picto and name + * @param int $maxlen Max length of visible user name + * @param int $hidethirdpartylogo Hide logo of thirdparty if user is external user + * @param string $mode ''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @return string String with URL */ function getNomUrl($withpictoimg=0, $option='', $infologin=0, $notooltip=0, $maxlen=24, $hidethirdpartylogo=0, $mode='',$morecss='', $save_lastsearch_value=-1) @@ -2064,14 +2064,14 @@ class User extends CommonObject if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; - $result=''; $label=''; - $link=''; $linkstart=''; $linkend=''; + $result=''; $label=''; + $link=''; $linkstart=''; $linkend=''; if (! empty($this->photo)) { - $label.= '<div class="photointooltip">'; - $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); - $label.= '</div><div style="clear: both;"></div>'; + $label.= '<div class="photointooltip">'; + $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); + $label.= '</div><div style="clear: both;"></div>'; } $label.= '<div class="centpercent">'; @@ -2148,20 +2148,20 @@ class User extends CommonObject $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) $linkclose = $hookmanager->resPrint; - $link.=$linkclose.'>'; + $link.=$linkclose.'>'; $linkend='</a>'; - //if ($withpictoimg == -1) $result.='<div class="nowrap">'; + //if ($withpictoimg == -1) $result.='<div class="nowrap">'; $result.=$link; - if ($withpictoimg) - { - $paddafterimage=''; + if ($withpictoimg) + { + $paddafterimage=''; if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"'; - // Only picto + // Only picto if ($withpictoimg > 0) $picto='<!-- picto user --><div class="inline-block nopadding '.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>'; - // Picto must be a photo + // Picto must be a photo else $picto='<!-- picto photo user --><div class="inline-block nopadding '.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>'; - $result.=$picto; + $result.=$picto; } if ($withpictoimg > -2 && $withpictoimg != 2) { @@ -2421,7 +2421,7 @@ class User extends CommonObject $this->gender='man'; $this->note='This is a note'; $this->email='email@specimen.com'; - $this->skype='tom.hanson'; + $this->skype='tom.hanson'; $this->office_phone='0999999999'; $this->office_fax='0999999998'; $this->user_mobile='0999999997'; @@ -2722,8 +2722,8 @@ class User extends CommonObject $result = $this->build_path_from_id_user($key,0); // Process a branch from the root user key (this user has no parent) if ($result < 0) { - $this->error='ErrorLoopInHierarchy'; - return -1; + $this->error='ErrorLoopInHierarchy'; + return -1; } } @@ -2763,26 +2763,26 @@ class User extends CommonObject */ function getAllChildIds($addcurrentuser=0) { - $childids=array(); - - if (isset($this->cache_childids[$this->id])) - { - $childids = $this->cache_childids[$this->id]; - } - else - { - // Init this->users - $this->get_full_tree(); - - $idtoscan=$this->id; - - dol_syslog("Build childid for id = ".$idtoscan); - foreach($this->users as $id => $val) - { - //var_dump($val['fullpath']); - if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id']; - } - } + $childids=array(); + + if (isset($this->cache_childids[$this->id])) + { + $childids = $this->cache_childids[$this->id]; + } + else + { + // Init this->users + $this->get_full_tree(); + + $idtoscan=$this->id; + + dol_syslog("Build childid for id = ".$idtoscan); + foreach($this->users as $id => $val) + { + //var_dump($val['fullpath']); + if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id']; + } + } $this->cache_childids[$this->id] = $childids; if ($addcurrentuser) $childids[$this->id]=$this->id; @@ -2823,7 +2823,7 @@ class User extends CommonObject return -1; // Should not happen. Protection against looping hierarchy } $useridfound[]=$this->parentof[$cursor_user]; - $this->users[$id_user]['fullpath'] = '_'.$this->parentof[$cursor_user].$this->users[$id_user]['fullpath']; + $this->users[$id_user]['fullpath'] = '_'.$this->parentof[$cursor_user].$this->users[$id_user]['fullpath']; $this->users[$id_user]['fullname'] = $this->users[$this->parentof[$cursor_user]]['lastname'].' >> '.$this->users[$id_user]['fullname']; $i++; $cursor_user=$this->parentof[$cursor_user]; } @@ -2853,39 +2853,39 @@ class User extends CommonObject /** - * Charge indicateurs this->nb pour le tableau de bord - * - * @return int <0 if KO, >0 if OK - */ - function load_state_board() - { - global $conf; - - $this->nb=array(); - - $sql = "SELECT count(u.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; - $sql.= " WHERE u.statut > 0"; - //$sql.= " AND employee != 0"; - $sql.= " AND u.entity IN (".getEntity('user').")"; - - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nb["users"]=$obj->nb; - } - $this->db->free($resql); - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } + * Charge indicateurs this->nb pour le tableau de bord + * + * @return int <0 if KO, >0 if OK + */ + function load_state_board() + { + global $conf; + + $this->nb=array(); + + $sql = "SELECT count(u.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; + $sql.= " WHERE u.statut > 0"; + //$sql.= " AND employee != 0"; + $sql.= " AND u.entity IN (".getEntity('user').")"; + + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["users"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } /** * Create a document onto disk according to template module. diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php index 4e365582bf6c71164b1b3e03d9bdc7e090165e71..250c721f0fbe23549c4e51d20afe85cdea6deedd 100644 --- a/htdocs/user/ldap.php +++ b/htdocs/user/ldap.php @@ -112,25 +112,25 @@ print '<table class="border" width="100%">'; print '<tr><td class="titlefield">'.$langs->trans("Login").'</td>'; if ($object->ldap_sid) { - print '<td class="warning">'.$langs->trans("LoginAccountDisableInDolibarr").'</td>'; + print '<td class="warning">'.$langs->trans("LoginAccountDisableInDolibarr").'</td>'; } else { - print '<td>'.$object->login.'</td>'; + print '<td>'.$object->login.'</td>'; } print '</tr>'; if ($conf->global->LDAP_SERVER_TYPE == "activedirectory") { - $ldap = new Ldap(); - $result = $ldap->connect_bind(); - if ($result > 0) - { - $userSID = $ldap->getObjectSid($object->login); - } - print '<tr><td class="valigntop">'.$langs->trans("SID").'</td>'; - print '<td>'.$userSID.'</td>'; - print "</tr>\n"; + $ldap = new Ldap(); + $result = $ldap->connect_bind(); + if ($result > 0) + { + $userSID = $ldap->getObjectSid($object->login); + } + print '<tr><td class="valigntop">'.$langs->trans("SID").'</td>'; + print '<td>'.$userSID.'</td>'; + print "</tr>\n"; } // LDAP DN @@ -160,7 +160,7 @@ print '<div class="tabsAction">'; if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { - print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=dolibarr2ldap">'.$langs->trans("ForceSynchronize").'</a>'; + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=dolibarr2ldap">'.$langs->trans("ForceSynchronize").'</a>'; } print "</div>\n"; @@ -184,32 +184,32 @@ $ldap=new Ldap(); $result=$ldap->connect_bind(); if ($result > 0) { - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info,1); - $search = "(".$object->_load_ldap_dn($info,2).")"; - $records = $ldap->getAttribute($dn,$search); - - //print_r($records); - - // Affichage arbre - if ((! is_numeric($records) || $records != 0) && (! isset($records['count']) || $records['count'] > 0)) - { - if (! is_array($records)) - { - print '<tr '.$bc[false].'><td colspan="2"><font class="error">'.$langs->trans("ErrorFailedToReadLDAP").'</font></td></tr>'; - } - else - { - $result=show_ldap_content($records,0,$records['count'],true); - } - } - else - { - print '<tr '.$bc[false].'><td colspan="2">'.$langs->trans("LDAPRecordNotFound").' (dn='.$dn.' - search='.$search.')</td></tr>'; - } - - $ldap->unbind(); - $ldap->close(); + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info,1); + $search = "(".$object->_load_ldap_dn($info,2).")"; + $records = $ldap->getAttribute($dn,$search); + + //print_r($records); + + // Affichage arbre + if ((! is_numeric($records) || $records != 0) && (! isset($records['count']) || $records['count'] > 0)) + { + if (! is_array($records)) + { + print '<tr '.$bc[false].'><td colspan="2"><font class="error">'.$langs->trans("ErrorFailedToReadLDAP").'</font></td></tr>'; + } + else + { + $result=show_ldap_content($records,0,$records['count'],true); + } + } + else + { + print '<tr '.$bc[false].'><td colspan="2">'.$langs->trans("LDAPRecordNotFound").' (dn='.$dn.' - search='.$search.')</td></tr>'; + } + + $ldap->unbind(); + $ldap->close(); } else { diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 4cbf0c7df5fa156ad011ee62d3b0249818bd0b5f..fdddb0edbe7fd15095aa2972be45a1bc0a61f0b6 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -43,26 +43,26 @@ define('NOSTYLECHECK',1); */ function llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='') { - global $conf; - - // html header - top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); - - print '<body id="mainbody">'; - - // top menu and left menu area - if (empty($conf->dol_hide_topmenu)) - { - top_menu($head, $title, $target, $disablejs, $disablehead, $arrayofjs, $arrayofcss, $morequerystring, $help_url); - } - if (empty($conf->dol_hide_leftmenu)) - { - left_menu('', $help_url, '', '', 1, $title, 1); - } - - // main area - //main_area($title); - print '<!-- Begin div class="fiche" -->'."\n".'<div class="fichebutwithotherclass">'."\n"; + global $conf; + + // html header + top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); + + print '<body id="mainbody">'; + + // top menu and left menu area + if (empty($conf->dol_hide_topmenu)) + { + top_menu($head, $title, $target, $disablejs, $disablehead, $arrayofjs, $arrayofcss, $morequerystring, $help_url); + } + if (empty($conf->dol_hide_leftmenu)) + { + left_menu('', $help_url, '', '', 1, $title, 1); + } + + // main area + //main_area($title); + print '<!-- Begin div class="fiche" -->'."\n".'<div class="fichebutwithotherclass">'."\n"; } @@ -84,7 +84,7 @@ if (! $user->admin) accessforbidden(); if (! ((GETPOST('testmenuhider','int') || ! empty($conf->global->MAIN_TESTMENUHIDER)) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))) { - $conf->dol_hide_leftmenu = 1; // Force hide of left menu. + $conf->dol_hide_leftmenu = 1; // Force hide of left menu. } $error=0; @@ -119,22 +119,22 @@ $object->fetchAll(); // Init $object->records // If website not defined, we take first found if (empty($website)) { - foreach($object->records as $key => $valwebsite) - { - $website=$valwebsite->ref; - break; - } + foreach($object->records as $key => $valwebsite) + { + $website=$valwebsite->ref; + break; + } } if ($website) { - $res = $object->fetch(0, $website); + $res = $object->fetch(0, $website); } if ($pageid < 0) $pageid = 0; if (($pageid > 0 || $pageref) && $action != 'add') { $res = $objectpage->fetch($pageid, ($object->id > 0 ? $object->id : null), $pageref); - $pageid = $objectpage->id; + $pageid = $objectpage->id; } global $dolibarr_main_data_root; @@ -222,39 +222,39 @@ if ($action == 'addsite') // Add page if ($action == 'add') { - $db->begin(); - - $objectpage->fk_website = $object->id; - if (GETPOST('fetchexternalurl','alpha')) - { - $urltograb=GETPOST('externalurl','alpha'); - } - - if ($urltograb) - { - // Clean url to grab, so url can be - // http://www.example.com/ or http://www.example.com/dir1/ or http://www.example.com/dir1/aaa - $urltograbwithoutdomainandparam = preg_replace('/^https?:\/\/[^\/]+\/?/i', '', $urltograb); - $urltograbwithoutdomainandparam = preg_replace('/\?.*$/', '', $urltograbwithoutdomainandparam); + $db->begin(); + + $objectpage->fk_website = $object->id; + if (GETPOST('fetchexternalurl','alpha')) + { + $urltograb=GETPOST('externalurl','alpha'); + } + + if ($urltograb) + { + // Clean url to grab, so url can be + // http://www.example.com/ or http://www.example.com/dir1/ or http://www.example.com/dir1/aaa + $urltograbwithoutdomainandparam = preg_replace('/^https?:\/\/[^\/]+\/?/i', '', $urltograb); + $urltograbwithoutdomainandparam = preg_replace('/\?.*$/', '', $urltograbwithoutdomainandparam); if (empty($urltograbwithoutdomainandparam) && ! preg_match('/\/$/', $urltograb)) { $urltograb.='/'; } $urltograbdirwithoutslash = dirname($urltograb.'.'); - include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; - $tmp = getURLContent($urltograb); - if ($tmp['curl_error_no']) - { - $error++; - setEventMessages($tmp['curl_error_msg'], null, 'errors'); - $action='create'; - } - else - { - preg_match('/<head>(.*)<\/head>/is', $tmp['content'], $reg); - $head = $reg[1]; + $tmp = getURLContent($urltograb); + if ($tmp['curl_error_no']) + { + $error++; + setEventMessages($tmp['curl_error_msg'], null, 'errors'); + $action='create'; + } + else + { + preg_match('/<head>(.*)<\/head>/is', $tmp['content'], $reg); + $head = $reg[1]; $objectpage->pageurl = dol_sanitizeFileName(preg_replace('/[\/\.]/','-',$urltograbwithoutdomainandparam)); if (empty($objectpage->pageurl)) @@ -263,60 +263,60 @@ if ($action == 'add') $objectpage->pageurl=$tmpdomain.'-home'; } - if (preg_match('/<title>(.*)<\/title>/ims', $head, $regtmp)) - { - $objectpage->title = $regtmp[1]; - } - if (preg_match('/<meta name="description"[^"]+content="([^"]+)"/ims', $head, $regtmp)) - { - $objectpage->description = $regtmp[1]; - } - if (preg_match('/<meta name="keywords"[^"]+content="([^"]+)"/ims', $head, $regtmp)) - { - $objectpage->keywords = $regtmp[1]; - } - if (preg_match('/<html\s+lang="([^"]+)"/ims', $tmp['content'], $regtmp)) - { - $tmplang=explode('-', $regtmp[1]); - $objectpage->lang = $tmplang[0].($tmplang[1] ? '_'.strtoupper($tmplang[1]) : ''); - } - - $objectpage->content = $tmp['content']; - $objectpage->content = preg_replace('/^.*<body[^>]*>/ims', '', $objectpage->content); - $objectpage->content = preg_replace('/<\/body[^>]*>.*$/ims', '', $objectpage->content); - - - // Now loop to fetch all css files. Include them inline into header of page - $objectpage->htmlheader = $tmp['content']; - $objectpage->htmlheader = preg_replace('/^.*<head[^>]*>/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<\/head[^>]*>.*$/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<base[^>]*>\n*/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<meta name="robot[^>]*>\n*/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<meta name="keywords[^>]*>\n*/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<meta name="title[^>]*>\n*/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<meta name="description[^>]*>\n*/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<meta name="generator[^>]*>\n*/ims', '', $objectpage->htmlheader); - //$objectpage->htmlheader = preg_replace('/<meta name="verify-v1[^>]*>\n*/ims', '', $objectpage->htmlheader); - //$objectpage->htmlheader = preg_replace('/<meta name="msvalidate.01[^>]*>\n*/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<title>[^<]*<\/title>\n*/ims', '', $objectpage->htmlheader); - $objectpage->htmlheader = preg_replace('/<link[^>]*rel="shortcut[^>]*>\n/ims', '', $objectpage->htmlheader); - - // Now loop to fetch JS - $tmp = $objectpage->htmlheader; - - preg_match_all('/<script([^\.]+)src="([^>"]+)"([^>]*)><\/script>/i', $objectpage->htmlheader, $regs); - foreach ($regs[0] as $key => $val) - { - $urltograbbis = $urltograbdirwithoutslash.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; - - $linkwithoutdomain = $regs[2][$key]; - //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; - if (preg_match('/^http/', $regs[2][$key])) - { - $urltograbbis = $regs[2][$key]; - $linkwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\//i', '', $regs[2][$key]); - //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; - } + if (preg_match('/<title>(.*)<\/title>/ims', $head, $regtmp)) + { + $objectpage->title = $regtmp[1]; + } + if (preg_match('/<meta name="description"[^"]+content="([^"]+)"/ims', $head, $regtmp)) + { + $objectpage->description = $regtmp[1]; + } + if (preg_match('/<meta name="keywords"[^"]+content="([^"]+)"/ims', $head, $regtmp)) + { + $objectpage->keywords = $regtmp[1]; + } + if (preg_match('/<html\s+lang="([^"]+)"/ims', $tmp['content'], $regtmp)) + { + $tmplang=explode('-', $regtmp[1]); + $objectpage->lang = $tmplang[0].($tmplang[1] ? '_'.strtoupper($tmplang[1]) : ''); + } + + $objectpage->content = $tmp['content']; + $objectpage->content = preg_replace('/^.*<body[^>]*>/ims', '', $objectpage->content); + $objectpage->content = preg_replace('/<\/body[^>]*>.*$/ims', '', $objectpage->content); + + + // Now loop to fetch all css files. Include them inline into header of page + $objectpage->htmlheader = $tmp['content']; + $objectpage->htmlheader = preg_replace('/^.*<head[^>]*>/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<\/head[^>]*>.*$/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<base[^>]*>\n*/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<meta name="robot[^>]*>\n*/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<meta name="keywords[^>]*>\n*/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<meta name="title[^>]*>\n*/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<meta name="description[^>]*>\n*/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<meta name="generator[^>]*>\n*/ims', '', $objectpage->htmlheader); + //$objectpage->htmlheader = preg_replace('/<meta name="verify-v1[^>]*>\n*/ims', '', $objectpage->htmlheader); + //$objectpage->htmlheader = preg_replace('/<meta name="msvalidate.01[^>]*>\n*/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<title>[^<]*<\/title>\n*/ims', '', $objectpage->htmlheader); + $objectpage->htmlheader = preg_replace('/<link[^>]*rel="shortcut[^>]*>\n/ims', '', $objectpage->htmlheader); + + // Now loop to fetch JS + $tmp = $objectpage->htmlheader; + + preg_match_all('/<script([^\.]+)src="([^>"]+)"([^>]*)><\/script>/i', $objectpage->htmlheader, $regs); + foreach ($regs[0] as $key => $val) + { + $urltograbbis = $urltograbdirwithoutslash.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + + $linkwithoutdomain = $regs[2][$key]; + //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + if (preg_match('/^http/', $regs[2][$key])) + { + $urltograbbis = $regs[2][$key]; + $linkwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\//i', '', $regs[2][$key]); + //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; + } /* $tmpgeturl = getURLContent($urltograbbis); if ($tmpgeturl['curl_error_no']) @@ -338,146 +338,146 @@ if ($action == 'add') $filename = 'image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; */ - $tmp = preg_replace('/'.preg_quote($regs[0][$key],'/').'/i', '', $tmp); - } - $objectpage->htmlheader = trim($tmp); + $tmp = preg_replace('/'.preg_quote($regs[0][$key],'/').'/i', '', $tmp); + } + $objectpage->htmlheader = trim($tmp); - // Now loop to fetch CSS - $pagecsscontent = "\n".'<style>'."\n"; + // Now loop to fetch CSS + $pagecsscontent = "\n".'<style>'."\n"; - preg_match_all('/<link([^\.]+)href="([^>"]+\.css)"([^>]*)>/i', $objectpage->htmlheader, $regs); + preg_match_all('/<link([^\.]+)href="([^>"]+\.css)"([^>]*)>/i', $objectpage->htmlheader, $regs); foreach ($regs[0] as $key => $val) - { - $urltograbbis = $urltograbdirwithoutslash.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; - $linkwithoutdomain = $regs[2][$key]; - //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; - if (preg_match('/^http/', $regs[2][$key])) - { - $urltograbbis = $regs[2][$key]; - $linkwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\//i', '', $regs[2][$key]); - //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; - } - - $tmpgeturl = getURLContent($urltograbbis); - if ($tmpgeturl['curl_error_no']) - { - $error++; - setEventMessages($tmpgeturl['curl_error_msg'], null, 'errors'); - $action='create'; - } - else - { - //dol_mkdir(dirname($filetosave)); - - //$fp = fopen($filetosave, "w"); - //fputs($fp, $tmpgeturl['content']); - //fclose($fp); - //if (! empty($conf->global->MAIN_UMASK)) - // @chmod($file, octdec($conf->global->MAIN_UMASK)); - } - - // $filename = 'image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; - $pagecsscontent.='/* Content of file '.$urltograbbis.' */'."\n"; - - getAllImages($object, $objectpage, $urltograbbis, $tmpgeturl['content'], $action, 1); - - $pagecsscontent.=$tmpgeturl['content']."\n"; - - $objectpage->htmlheader = preg_replace('/'.preg_quote($regs[0][$key],'/').'\n*/ims', '', $objectpage->htmlheader); - } + { + $urltograbbis = $urltograbdirwithoutslash.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + $linkwithoutdomain = $regs[2][$key]; + //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + if (preg_match('/^http/', $regs[2][$key])) + { + $urltograbbis = $regs[2][$key]; + $linkwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\//i', '', $regs[2][$key]); + //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; + } + + $tmpgeturl = getURLContent($urltograbbis); + if ($tmpgeturl['curl_error_no']) + { + $error++; + setEventMessages($tmpgeturl['curl_error_msg'], null, 'errors'); + $action='create'; + } + else + { + //dol_mkdir(dirname($filetosave)); + + //$fp = fopen($filetosave, "w"); + //fputs($fp, $tmpgeturl['content']); + //fclose($fp); + //if (! empty($conf->global->MAIN_UMASK)) + // @chmod($file, octdec($conf->global->MAIN_UMASK)); + } + + // $filename = 'image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; + $pagecsscontent.='/* Content of file '.$urltograbbis.' */'."\n"; + + getAllImages($object, $objectpage, $urltograbbis, $tmpgeturl['content'], $action, 1); + + $pagecsscontent.=$tmpgeturl['content']."\n"; + + $objectpage->htmlheader = preg_replace('/'.preg_quote($regs[0][$key],'/').'\n*/ims', '', $objectpage->htmlheader); + } - $pagecsscontent.='</style>'."\n"; + $pagecsscontent.='</style>'."\n"; //var_dump($pagecsscontent); - //print dol_escape_htmltag($tmp);exit; - $objectpage->htmlheader .= $pagecsscontent; + //print dol_escape_htmltag($tmp);exit; + $objectpage->htmlheader .= $pagecsscontent; - // Now loop to fetch all images - $tmp = $objectpage->content; + // Now loop to fetch all images + $tmp = $objectpage->content; - getAllImages($object, $objectpage, $urltograb, $tmp, $action, 1); + getAllImages($object, $objectpage, $urltograb, $tmp, $action, 1); //print dol_escape_htmltag($tmp);exit; $objectpage->content = $tmp; - $objectpage->grabbed_from = $urltograb; - } - } - else - { - $objectpage->title = GETPOST('WEBSITE_TITLE','alpha'); - $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME','alpha'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION','alpha'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS','alpha'); - $objectpage->lang = GETPOST('WEBSITE_LANG','aZ09'); - $objectpage->htmlheader = GETPOST('htmlheader','none'); - } - - if (! $error) - { - if (empty($objectpage->pageurl)) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WEBSITE_PAGENAME")), null, 'errors'); - $error++; - $action='create'; - } - else if (! preg_match('/^[a-z0-9\-\_]+$/i', $objectpage->pageurl)) - { - setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors'); - $error++; - $action='create'; - } - if (empty($objectpage->title)) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WEBSITE_TITLE")), null, 'errors'); - $error++; - $action='create'; - } - } - - if (! $error) - { - $res = $objectpage->create($user); - if ($res <= 0) - { - $error++; - setEventMessages($objectpage->error, $objectpage->errors, 'errors'); - } - } - if (! $error) - { - if (! empty($objectpage->content)) - { + $objectpage->grabbed_from = $urltograb; + } + } + else + { + $objectpage->title = GETPOST('WEBSITE_TITLE','alpha'); + $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME','alpha'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION','alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS','alpha'); + $objectpage->lang = GETPOST('WEBSITE_LANG','aZ09'); + $objectpage->htmlheader = GETPOST('htmlheader','none'); + } + + if (! $error) + { + if (empty($objectpage->pageurl)) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WEBSITE_PAGENAME")), null, 'errors'); + $error++; + $action='create'; + } + else if (! preg_match('/^[a-z0-9\-\_]+$/i', $objectpage->pageurl)) + { + setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors'); + $error++; + $action='create'; + } + if (empty($objectpage->title)) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WEBSITE_TITLE")), null, 'errors'); + $error++; + $action='create'; + } + } + + if (! $error) + { + $res = $objectpage->create($user); + if ($res <= 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } + } + if (! $error) + { + if (! empty($objectpage->content)) + { $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; $filetpl=$pathofwebsite.'/page'.$objectpage->id.'.tpl.php'; - // Save page alias - $result=dolSavePageAlias($filealias, $object, $objectpage); - if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); - - // Save page of content - $result=dolSavePageContent($filetpl, $object, $objectpage); - if ($result) - { - setEventMessages($langs->trans("Saved"), null, 'mesgs'); - //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - //exit; - } - else - { - setEventMessages('Failed to write file '.$filetpl, null, 'errors'); - //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - //exit; - } - } - } + // Save page alias + $result=dolSavePageAlias($filealias, $object, $objectpage); + if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + + // Save page of content + $result=dolSavePageContent($filetpl, $object, $objectpage); + if ($result) + { + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + //exit; + } + else + { + setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + //exit; + } + } + } if (! $error) { $db->commit(); - setEventMessages($langs->trans("PageAdded", $objectpage->pageurl), null, 'mesgs'); - $action=''; + setEventMessages($langs->trans("PageAdded", $objectpage->pageurl), null, 'mesgs'); + $action=''; } else { @@ -527,38 +527,38 @@ if ($action == 'add') // Delete page if ($action == 'delete') { - $db->begin(); + $db->begin(); - $res = $object->fetch(0, $website); + $res = $object->fetch(0, $website); - $res = $objectpage->fetch($pageid, $object->fk_website); + $res = $objectpage->fetch($pageid, $object->fk_website); - if ($res > 0) - { - $res = $objectpage->delete($user); - if (! $res > 0) - { - $error++; - setEventMessages($objectpage->error, $objectpage->errors, 'errors'); - } + if ($res > 0) + { + $res = $objectpage->delete($user); + if (! $res > 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $website), null, 'mesgs'); + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $website), null, 'mesgs'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website); - exit; - } - else - { - $db->rollback(); - } - } - else - { - dol_print_error($db); - } + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website); + exit; + } + else + { + $db->rollback(); + } + } + else + { + dol_print_error($db); + } } // Update css @@ -570,12 +570,12 @@ if ($action == 'updatecss') } else { - $res = $object->fetch(0, $website); + $res = $object->fetch(0, $website); - // Html header file - $htmlheadercontent =''; + // Html header file + $htmlheadercontent =''; - /* We disable php code since htmlheader is never executed as an include but only read by fgets_content. + /* We disable php code since htmlheader is never executed as an include but only read by fgets_content. $htmlheadercontent.= "<?php // BEGIN PHP\n"; $htmlheadercontent.= '$websitekey=basename(dirname(__FILE__));'."\n"; $htmlheadercontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Not already loaded"."\n"; @@ -585,85 +585,85 @@ if ($action == 'updatecss') // $htmlheadercontent.= "header('Content-type: text/html');\n"; // Not required. htmlheader.html is never call as a standalone page $htmlheadercontent.= "// END PHP ?>\n";*/ - $htmlheadercontent.= preg_replace(array('/<html>\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER', 'none')); + $htmlheadercontent.= preg_replace(array('/<html>\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER', 'none')); - /*$htmlheadercontent.= "\n".'<?php // BEGIN PHP'."\n"; + /*$htmlheadercontent.= "\n".'<?php // BEGIN PHP'."\n"; $htmlheadercontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; $htmlheadercontent.= "// END PHP ?>"."\n";*/ - $htmlheadercontent = trim($htmlheadercontent)."\n"; + $htmlheadercontent = trim($htmlheadercontent)."\n"; - dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent); + dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent); - // Css file - $csscontent =''; + // Css file + $csscontent =''; - $csscontent.= "<?php // BEGIN PHP\n"; - $csscontent.= '$websitekey=basename(dirname(__FILE__));'."\n"; - $csscontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n"; // For the css, we need to set path of master using the dirname of css file. - $csscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; - $csscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n"; - $csscontent.= "ob_start();\n"; - $csscontent.= "header('Content-type: text/css');\n"; - $csscontent.= "// END PHP ?>\n"; + $csscontent.= "<?php // BEGIN PHP\n"; + $csscontent.= '$websitekey=basename(dirname(__FILE__));'."\n"; + $csscontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n"; // For the css, we need to set path of master using the dirname of css file. + $csscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; + $csscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n"; + $csscontent.= "ob_start();\n"; + $csscontent.= "header('Content-type: text/css');\n"; + $csscontent.= "// END PHP ?>\n"; - $csscontent.= GETPOST('WEBSITE_CSS_INLINE', 'none'); + $csscontent.= GETPOST('WEBSITE_CSS_INLINE', 'none'); - $csscontent.= "\n".'<?php // BEGIN PHP'."\n"; - $csscontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; - $csscontent.= "// END PHP ?>"."\n"; + $csscontent.= "\n".'<?php // BEGIN PHP'."\n"; + $csscontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; + $csscontent.= "// END PHP ?>"."\n"; - dol_syslog("Save css content into ".$filecss); + dol_syslog("Save css content into ".$filecss); - dol_mkdir($pathofwebsite); - $result = file_put_contents($filecss, $csscontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filecss, octdec($conf->global->MAIN_UMASK)); + dol_mkdir($pathofwebsite); + $result = file_put_contents($filecss, $csscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filecss, octdec($conf->global->MAIN_UMASK)); - if (! $result) - { - $error++; - setEventMessages('Failed to write file '.$filecss, null, 'errors'); - } + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filecss, null, 'errors'); + } // Js file - $jscontent =''; + $jscontent =''; - $jscontent.= "<?php // BEGIN PHP\n"; - $jscontent.= '$websitekey=basename(dirname(__FILE__));'."\n"; - $jscontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n"; // For the css, we need to set path of master using the dirname of css file. - $jscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; - $jscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n"; - $jscontent.= "ob_start();\n"; - $jscontent.= "header('Content-type: application/javascript');\n"; - $jscontent.= "// END PHP ?>\n"; + $jscontent.= "<?php // BEGIN PHP\n"; + $jscontent.= '$websitekey=basename(dirname(__FILE__));'."\n"; + $jscontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n"; // For the css, we need to set path of master using the dirname of css file. + $jscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; + $jscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n"; + $jscontent.= "ob_start();\n"; + $jscontent.= "header('Content-type: application/javascript');\n"; + $jscontent.= "// END PHP ?>\n"; - $jscontent.= GETPOST('WEBSITE_JS_INLINE', 'none'); + $jscontent.= GETPOST('WEBSITE_JS_INLINE', 'none'); - $jscontent.= "\n".'<?php // BEGIN PHP'."\n"; - $jscontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; - $jscontent.= "// END PHP ?>"."\n"; + $jscontent.= "\n".'<?php // BEGIN PHP'."\n"; + $jscontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; + $jscontent.= "// END PHP ?>"."\n"; - dol_syslog("Save js content into ".$filejs); + dol_syslog("Save js content into ".$filejs); - dol_mkdir($pathofwebsite); - $result = file_put_contents($filejs, $jscontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filejs, octdec($conf->global->MAIN_UMASK)); + dol_mkdir($pathofwebsite); + $result = file_put_contents($filejs, $jscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filejs, octdec($conf->global->MAIN_UMASK)); - if (! $result) - { - $error++; - setEventMessages('Failed to write file '.$filejs, null, 'errors'); - } + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filejs, null, 'errors'); + } - // Robot file - $robotcontent =''; + // Robot file + $robotcontent =''; - /*$robotcontent.= "<?php // BEGIN PHP\n"; + /*$robotcontent.= "<?php // BEGIN PHP\n"; $robotcontent.= '$websitekey=basename(dirname(__FILE__));'."\n"; $robotcontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Not already loaded"."\n"; $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; @@ -672,30 +672,30 @@ if ($action == 'updatecss') $robotcontent.= "header('Content-type: text/css');\n"; $robotcontent.= "// END PHP ?>\n";*/ - $robotcontent.= GETPOST('WEBSITE_ROBOT', 'none'); + $robotcontent.= GETPOST('WEBSITE_ROBOT', 'none'); - /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n"; + /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n"; $robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; $robotcontent.= "// END PHP ?>"."\n";*/ - dol_syslog("Save file robot into ".$filerobot); + dol_syslog("Save file robot into ".$filerobot); - dol_mkdir($pathofwebsite); - $result = file_put_contents($filerobot, $robotcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filerobot, octdec($conf->global->MAIN_UMASK)); + dol_mkdir($pathofwebsite); + $result = file_put_contents($filerobot, $robotcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filerobot, octdec($conf->global->MAIN_UMASK)); - if (! $result) - { - $error++; - setEventMessages('Failed to write file '.$filerobot, null, 'errors'); - } + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filerobot, null, 'errors'); + } - // Css file - $htaccesscontent =''; + // Css file + $htaccesscontent =''; - /*$robotcontent.= "<?php // BEGIN PHP\n"; + /*$robotcontent.= "<?php // BEGIN PHP\n"; $robotcontent.= '$websitekey=basename(dirname(__FILE__));'."\n"; $robotcontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Not already loaded"."\n"; $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; @@ -704,18 +704,18 @@ if ($action == 'updatecss') $robotcontent.= "header('Content-type: text/css');\n"; $robotcontent.= "// END PHP ?>\n";*/ - $htaccesscontent.= GETPOST('WEBSITE_HTACCESS', 'none'); + $htaccesscontent.= GETPOST('WEBSITE_HTACCESS', 'none'); - /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n"; + /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n"; $robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; $robotcontent.= "// END PHP ?>"."\n";*/ - dol_syslog("Save file htaccess into ".$filehtaccess); + dol_syslog("Save file htaccess into ".$filehtaccess); - dol_mkdir($pathofwebsite); - $result = file_put_contents($filehtaccess, $htaccesscontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filehtaccess, octdec($conf->global->MAIN_UMASK)); + dol_mkdir($pathofwebsite); + $result = file_put_contents($filehtaccess, $htaccesscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filehtaccess, octdec($conf->global->MAIN_UMASK)); if (! $result) { @@ -724,166 +724,166 @@ if ($action == 'updatecss') } // Message if no error - if (! $error) - { - setEventMessages($langs->trans("Saved"), null, 'mesgs'); - } + if (! $error) + { + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + } - $action='preview'; + $action='preview'; } } // Update page if ($action == 'setashome') { - $db->begin(); - $object->fetch(0, $website); - - $object->fk_default_home = $pageid; - $res = $object->update($user); - if (! $res > 0) - { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); - } - - if (! $error) - { - $db->commit(); - - // Generate the index.php page to be the home page - //------------------------------------------------- - dol_mkdir($pathofwebsite); - dol_delete_file($fileindex); - - $indexcontent = '<?php'."\n"; - $indexcontent.= '// File generated to provide a shortcut to the Home Page - DO NOT MODIFY - It is just an include.'."\n"; - $indexcontent.= "include_once './".basename($filetpl)."'\n"; - $indexcontent.= '?>'."\n"; - $result = file_put_contents($fileindex, $indexcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($fileindex, octdec($conf->global->MAIN_UMASK)); + $db->begin(); + $object->fetch(0, $website); + + $object->fk_default_home = $pageid; + $res = $object->update($user); + if (! $res > 0) + { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + + if (! $error) + { + $db->commit(); + + // Generate the index.php page to be the home page + //------------------------------------------------- + dol_mkdir($pathofwebsite); + dol_delete_file($fileindex); + + $indexcontent = '<?php'."\n"; + $indexcontent.= '// File generated to provide a shortcut to the Home Page - DO NOT MODIFY - It is just an include.'."\n"; + $indexcontent.= "include_once './".basename($filetpl)."'\n"; + $indexcontent.= '?>'."\n"; + $result = file_put_contents($fileindex, $indexcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($fileindex, octdec($conf->global->MAIN_UMASK)); - if ($result) setEventMessages($langs->trans("Saved"), null, 'mesgs'); - else setEventMessages('Failed to write file '.$fileindex, null, 'errors'); + if ($result) setEventMessages($langs->trans("Saved"), null, 'mesgs'); + else setEventMessages('Failed to write file '.$fileindex, null, 'errors'); - $action='preview'; - } - else - { - $db->rollback(); - } + $action='preview'; + } + else + { + $db->rollback(); + } } // Update page (meta) if ($action == 'updatemeta') { - $db->begin(); - $object->fetch(0, $website); + $db->begin(); + $object->fetch(0, $website); - $objectpage->fk_website = $object->id; + $objectpage->fk_website = $object->id; // Check parameters - if (! preg_match('/^[a-z0-9\-\_]+$/i', $objectpage->pageurl)) - { - $error++; - setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors'); - $action='editmeta'; - } - - $res = $objectpage->fetch($pageid, $object->fk_website); - if ($res <= 0) - { - $error++; - dol_print_error($db, 'Page not found'); - } - - if (! $error) - { - $objectpage->old_object = clone $objectpage; - - $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); - $objectpage->title = GETPOST('WEBSITE_TITLE', 'alpha'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alpha'); - $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09'); - $objectpage->htmlheader = GETPOST('htmlheader', 'none'); - - $res = $objectpage->update($user); - if (! $res > 0) - { - $error++; - setEventMessages($objectpage->error, $objectpage->errors, 'errors'); - } + if (! preg_match('/^[a-z0-9\-\_]+$/i', $objectpage->pageurl)) + { + $error++; + setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors'); + $action='editmeta'; + } - if (! $error) - { - $db->commit(); + $res = $objectpage->fetch($pageid, $object->fk_website); + if ($res <= 0) + { + $error++; + dol_print_error($db, 'Page not found'); + } - $filemaster=$pathofwebsite.'/master.inc.php'; - $fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; - $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; + if (! $error) + { + $objectpage->old_object = clone $objectpage; - dol_mkdir($pathofwebsite); + $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); + $objectpage->title = GETPOST('WEBSITE_TITLE', 'alpha'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alpha'); + $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09'); + $objectpage->htmlheader = GETPOST('htmlheader', 'none'); + $res = $objectpage->update($user); + if (! $res > 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } - // Now generate the master.inc.php page - dol_syslog("We regenerate the master file (because we update meta)"); - dol_delete_file($filemaster); + if (! $error) + { + $db->commit(); + + $filemaster=$pathofwebsite.'/master.inc.php'; + $fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; + $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; + + dol_mkdir($pathofwebsite); - $mastercontent = '<?php'."\n"; - $mastercontent.= '// File generated to link to the master file - DO NOT MODIFY - It is just an include'."\n"; - $mastercontent.= "if (! defined('USEDOLIBARRSERVER')) require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n"; - //$mastercontent.= "include_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php';"."\n"; - //$mastercontent.= '$website = new WebSite($db)'."\n"; - $mastercontent.= '?>'."\n"; - $result = file_put_contents($filemaster, $mastercontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); - if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); + // Now generate the master.inc.php page + dol_syslog("We regenerate the master file (because we update meta)"); + dol_delete_file($filemaster); + $mastercontent = '<?php'."\n"; + $mastercontent.= '// File generated to link to the master file - DO NOT MODIFY - It is just an include'."\n"; + $mastercontent.= "if (! defined('USEDOLIBARRSERVER')) require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n"; + //$mastercontent.= "include_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php';"."\n"; + //$mastercontent.= '$website = new WebSite($db)'."\n"; + $mastercontent.= '?>'."\n"; + $result = file_put_contents($filemaster, $mastercontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); - // Now generate the alias.php page - if (! empty($fileoldalias)) - { - dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); - dol_delete_file($fileoldalias); - } + if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); - // Save page alias - $result=dolSavePageAlias($filealias, $object, $objectpage); - if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + + // Now generate the alias.php page + if (! empty($fileoldalias)) + { + dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); + dol_delete_file($fileoldalias); + } + + // Save page alias + $result=dolSavePageAlias($filealias, $object, $objectpage); + if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); // Save page of content - $result=dolSavePageContent($filetpl, $object, $objectpage); - if ($result) - { - setEventMessages($langs->trans("Saved"), null, 'mesgs'); - //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - //exit; - } - else - { - setEventMessages('Failed to write file '.$filetpl, null, 'errors'); - //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - //exit; - } - - $action='preview'; - } - else - { - $db->rollback(); - } - } + $result=dolSavePageContent($filetpl, $object, $objectpage); + if ($result) + { + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + //exit; + } + else + { + setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + //exit; + } + + $action='preview'; + } + else + { + $db->rollback(); + } + } } // Update page if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'confirm_createfromclone' || $action == 'confirm_createpagefromclone') || ($action == 'preview' && (GETPOST('refreshsite') || GETPOST('refreshpage') || GETPOST('preview')))) { - $object->fetch(0, $website); + $object->fetch(0, $website); if ($action == 'confirm_createfromclone') { @@ -918,7 +918,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf if (! $error) { - $objectpage = new WebsitePage($db); + $objectpage = new WebsitePage($db); $result = $objectpage->createFromClone($user, $pageid, GETPOST('pageurl','aZ09'), (GETPOST('newlang','aZ09')?GETPOST('newlang','aZ09'):''), $istranslation, GETPOST('newwebsite','int')); if ($result < 0) { @@ -927,135 +927,135 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf $action='createpagefromclone'; } } - } + } - $res = 0; + $res = 0; - if (! $error) - { - // Check symlink to medias and restore it if ko - $pathtomedias=DOL_DATA_ROOT.'/medias'; - $pathtomediasinwebsite=$pathofwebsite.'/medias'; - if (! is_link(dol_osencode($pathtomediasinwebsite))) - { - dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite); - dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists - $result = symlink($pathtomedias, $pathtomediasinwebsite); - } + if (! $error) + { + // Check symlink to medias and restore it if ko + $pathtomedias=DOL_DATA_ROOT.'/medias'; + $pathtomediasinwebsite=$pathofwebsite.'/medias'; + if (! is_link(dol_osencode($pathtomediasinwebsite))) + { + dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite); + dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists + $result = symlink($pathtomedias, $pathtomediasinwebsite); + } - /*if (GETPOST('savevirtualhost') && $object->virtualhost != GETPOST('previewsite')) + /*if (GETPOST('savevirtualhost') && $object->virtualhost != GETPOST('previewsite')) { $object->virtualhost = GETPOST('previewsite', 'alpha'); $object->update($user); }*/ - $objectpage->fk_website = $object->id; + $objectpage->fk_website = $object->id; - if ($pageid > 0) - { - $res = $objectpage->fetch($pageid); - } - else - { - $res=0; - if ($object->fk_default_home > 0) - { - $res = $objectpage->fetch($object->fk_default_home); - } - if (! ($res > 0)) - { - $res = $objectpage->fetch(0, $object->id); - } - } - } - - if (! $error && $res > 0) - { - if ($action == 'updatesource' || $action == 'updatecontent') - { - $db->begin(); + if ($pageid > 0) + { + $res = $objectpage->fetch($pageid); + } + else + { + $res=0; + if ($object->fk_default_home > 0) + { + $res = $objectpage->fetch($object->fk_default_home); + } + if (! ($res > 0)) + { + $res = $objectpage->fetch(0, $object->id); + } + } + } - $objectpage->content = GETPOST('PAGE_CONTENT','none'); + if (! $error && $res > 0) + { + if ($action == 'updatesource' || $action == 'updatecontent') + { + $db->begin(); - // Clean data. We remove all the head section. - $objectpage->content = preg_replace('/<head>.*<\/head>/s', '', $objectpage->content); - /* $objectpage->content = preg_replace('/<base\s+href=[\'"][^\'"]+[\'"]\s/?>/s', '', $objectpage->content); */ + $objectpage->content = GETPOST('PAGE_CONTENT','none'); + // Clean data. We remove all the head section. + $objectpage->content = preg_replace('/<head>.*<\/head>/s', '', $objectpage->content); + /* $objectpage->content = preg_replace('/<base\s+href=[\'"][^\'"]+[\'"]\s/?>/s', '', $objectpage->content); */ - $res = $objectpage->update($user); - if ($res < 0) - { - $error++; - setEventMessages($objectpage->error, $objectpage->errors, 'errors'); - } - if (! $error) - { - $db->commit(); + $res = $objectpage->update($user); + if ($res < 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } - $filemaster=$pathofwebsite.'/master.inc.php'; - //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; - $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; + if (! $error) + { + $db->commit(); + + $filemaster=$pathofwebsite.'/master.inc.php'; + //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; + $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; - dol_mkdir($pathofwebsite); + dol_mkdir($pathofwebsite); - // Now generate the master.inc.php page - dol_syslog("We regenerate the master file"); - dol_delete_file($filemaster); + // Now generate the master.inc.php page + dol_syslog("We regenerate the master file"); + dol_delete_file($filemaster); - $mastercontent = '<?php'."\n"; - $mastercontent.= '// File generated to link to the master file'."\n"; - $mastercontent.= "if (! defined('USEDOLIBARRSERVER')) require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n"; - $mastercontent.= '?>'."\n"; - $result = file_put_contents($filemaster, $mastercontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); + $mastercontent = '<?php'."\n"; + $mastercontent.= '// File generated to link to the master file'."\n"; + $mastercontent.= "if (! defined('USEDOLIBARRSERVER')) require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n"; + $mastercontent.= '?>'."\n"; + $result = file_put_contents($filemaster, $mastercontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); - if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); + if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); - // Now generate the alias.php page - if (! empty($fileoldalias)) - { - dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); - dol_delete_file($fileoldalias); - } + // Now generate the alias.php page + if (! empty($fileoldalias)) + { + dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); + dol_delete_file($fileoldalias); + } - // Save page alias - $result=dolSavePageAlias($filealias, $object, $objectpage); - if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + // Save page alias + $result=dolSavePageAlias($filealias, $object, $objectpage); + if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); // Save page content - $result=dolSavePageContent($filetpl, $object, $objectpage); - if ($result) - { - setEventMessages($langs->trans("Saved"), null, 'mesgs'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - exit; - } - else - { - setEventMessages('Failed to write file '.$filetpl, null, 'errors'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - exit; - } - } - else - { - $db->rollback(); - } - } - else - { - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - exit; - } - } - else - { - if (! $error) setEventMessages($langs->trans("NoPageYet"), null, 'warnings'); - } + $result=dolSavePageContent($filetpl, $object, $objectpage); + if ($result) + { + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } + else + { + setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } + } + else + { + $db->rollback(); + } + } + else + { + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } + } + else + { + if (! $error) setEventMessages($langs->trans("NoPageYet"), null, 'warnings'); + } } // Export site @@ -1097,39 +1097,39 @@ print "\n".'<form action="'.$_SERVER["PHP_SELF"].'" method="POST"><div>'; print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; if ($action == 'createsite') { - print '<input type="hidden" name="action" value="addsite">'; + print '<input type="hidden" name="action" value="addsite">'; } if ($action == 'create') { - print '<input type="hidden" name="action" value="add">'; + print '<input type="hidden" name="action" value="add">'; } if ($action == 'editcss') { - print '<input type="hidden" name="action" value="updatecss">'; + print '<input type="hidden" name="action" value="updatecss">'; } if ($action == 'editmenu') { - print '<input type="hidden" name="action" value="updatemenu">'; + print '<input type="hidden" name="action" value="updatemenu">'; } if ($action == 'setashome') { - print '<input type="hidden" name="action" value="updateashome">'; + print '<input type="hidden" name="action" value="updateashome">'; } if ($action == 'editmeta') { - print '<input type="hidden" name="action" value="updatemeta">'; + print '<input type="hidden" name="action" value="updatemeta">'; } if ($action == 'editsource') { - print '<input type="hidden" name="action" value="updatesource">'; + print '<input type="hidden" name="action" value="updatesource">'; } if ($action == 'editcontent') { - print '<input type="hidden" name="action" value="updatecontent">'; + print '<input type="hidden" name="action" value="updatecontent">'; } if ($action == 'edit') { - print '<input type="hidden" name="action" value="update">'; + print '<input type="hidden" name="action" value="update">'; } @@ -1142,183 +1142,183 @@ print '<div class="centpercent websitebar">'; if (count($object->records) > 0) { - // ***** Part for web sites + // ***** Part for web sites print '<div class="websiteselection hideonsmartphoneimp minwwidth100">'; print '<input type="submit"'.$disabled.' class="button" value="'.dol_escape_htmltag($langs->trans("AddWebsite")).'" name="createsite">'; print '</div>'; - print '<div class="websiteselection hideonsmartphoneimp">'; - print $langs->trans("Website").': '; - print '</div>'; - - // List of websites - print '<div class="websiteselection">'; - $out=''; - $out.='<select name="website" class="minwidth100" id="website">'; - if (empty($object->records)) $out.='<option value="-1"> </option>'; - // Loop on each sites - $i=0; - foreach($object->records as $key => $valwebsite) - { - if (empty($website)) $website=$valwebsite->ref; - - $out.='<option value="'.$valwebsite->ref.'"'; - if ($website == $valwebsite->ref) $out.=' selected'; // To preselect a value - $out.='>'; - $out.=$valwebsite->ref; - $out.='</option>'; - $i++; - } - $out.='</select>'; - $out.=ajax_combobox('website'); - print $out; - print '<input type="submit" class="button" name="refreshsite" value="'.$langs->trans("Load").'">'; - - if ($website) - { - $virtualurl=''; - $dataroot=DOL_DATA_ROOT.'/websites/'.$website; - if (! empty($object->virtualhost)) $virtualurl=$object->virtualhost; - } - - if ($website && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')) - { - $disabled=''; - if (empty($user->rights->websites->write)) $disabled=' disabled="disabled"'; - - print ' '; - - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditCss")).'" name="editcss">'; - //print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditMenu")).'" name="editmenu">'; - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("CloneSite")).'" name="createfromclone">'; - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ExportSite")).'" name="exportsite">'; + print '<div class="websiteselection hideonsmartphoneimp">'; + print $langs->trans("Website").': '; + print '</div>'; + + // List of websites + print '<div class="websiteselection">'; + $out=''; + $out.='<select name="website" class="minwidth100" id="website">'; + if (empty($object->records)) $out.='<option value="-1"> </option>'; + // Loop on each sites + $i=0; + foreach($object->records as $key => $valwebsite) + { + if (empty($website)) $website=$valwebsite->ref; + + $out.='<option value="'.$valwebsite->ref.'"'; + if ($website == $valwebsite->ref) $out.=' selected'; // To preselect a value + $out.='>'; + $out.=$valwebsite->ref; + $out.='</option>'; + $i++; + } + $out.='</select>'; + $out.=ajax_combobox('website'); + print $out; + print '<input type="submit" class="button" name="refreshsite" value="'.$langs->trans("Load").'">'; + + if ($website) + { + $virtualurl=''; + $dataroot=DOL_DATA_ROOT.'/websites/'.$website; + if (! empty($object->virtualhost)) $virtualurl=$object->virtualhost; + } + + if ($website && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')) + { + $disabled=''; + if (empty($user->rights->websites->write)) $disabled=' disabled="disabled"'; print ' '; - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("MediaFiles")).'" name="editmedias">'; - } + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditCss")).'" name="editcss">'; + //print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditMenu")).'" name="editmenu">'; + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("CloneSite")).'" name="createfromclone">'; + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ExportSite")).'" name="exportsite">'; - print '</div>'; + print ' '; - // Button for websites - print '<div class="websitetools">'; + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("MediaFiles")).'" name="editmedias">'; + } + + print '</div>'; - if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') - { - print '<a class="websitebuttonsitepreview" id="previewsite" href="'.$urlwithroot.'/public/websites/index.php?website='.$website.'" target="tab'.$website.'" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $urlint)).'">'; - print $form->textwithpicto('', $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $urlint, $dataroot), 1, 'preview'); - print '</a>'; + // Button for websites + print '<div class="websitetools">'; - print '<div class="websiteinputurl" id="websiteinputurl">'; - print '<input type="text" id="previewsiteurl" class="minwidth200imp" name="previewsite" placeholder="'.$langs->trans("http://myvirtualhost").'" value="'.$virtualurl.'">'; - //print '<input type="submit" class="button" name="previewwebsite" target="tab'.$website.'" value="'.$langs->trans("ViewSiteInNewTab").'">'; - $htmltext=$langs->trans("SetHereVirtualHost", $dataroot); - print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helpvirtualhost'); - print '</div>'; + if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') + { + print '<a class="websitebuttonsitepreview" id="previewsite" href="'.$urlwithroot.'/public/websites/index.php?website='.$website.'" target="tab'.$website.'" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $urlint)).'">'; + print $form->textwithpicto('', $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $urlint, $dataroot), 1, 'preview'); + print '</a>'; + + print '<div class="websiteinputurl" id="websiteinputurl">'; + print '<input type="text" id="previewsiteurl" class="minwidth200imp" name="previewsite" placeholder="'.$langs->trans("http://myvirtualhost").'" value="'.$virtualurl.'">'; + //print '<input type="submit" class="button" name="previewwebsite" target="tab'.$website.'" value="'.$langs->trans("ViewSiteInNewTab").'">'; + $htmltext=$langs->trans("SetHereVirtualHost", $dataroot); + print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helpvirtualhost'); + print '</div>'; + + $urlext=$virtualurl; + $urlint=$urlwithroot.'/public/websites/index.php?website='.$website; + print '<a class="websitebuttonsitepreview'.($urlext?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewsiteext" href="'.$urlext.'" target="tab'.$website.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext)).'">'; + print $form->textwithpicto('', $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext?$urlext:'<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>'), 1, 'preview_ext'); + print '</a>'; + } - $urlext=$virtualurl; - $urlint=$urlwithroot.'/public/websites/index.php?website='.$website; - print '<a class="websitebuttonsitepreview'.($urlext?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewsiteext" href="'.$urlext.'" target="tab'.$website.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext)).'">'; - print $form->textwithpicto('', $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext?$urlext:'<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>'), 1, 'preview_ext'); - print '</a>'; - } + if (in_array($action, array('editcss','editmenu','editmedias'))) + { + if (preg_match('/^create/',$action) && $action != 'editmedias') print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; + if (preg_match('/^edit/',$action) && $action != 'editmedias') print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; + if ($action != 'preview') print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">'; + } - if (in_array($action, array('editcss','editmenu','editmedias'))) - { - if (preg_match('/^create/',$action) && $action != 'editmedias') print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; - if (preg_match('/^edit/',$action) && $action != 'editmedias') print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; - if ($action != 'preview') print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">'; - } + print '</div>'; - print '</div>'; + // ***** Part for pages - // ***** Part for pages + if ($website && ! in_array($action, array('editcss','editmenu','editmedias'))) + { + print '</div>'; // Close current websitebar to open a new one - if ($website && ! in_array($action, array('editcss','editmenu','editmedias'))) - { - print '</div>'; // Close current websitebar to open a new one + $array=$objectpage->fetchAll($object->id); + if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors); + $atleastonepage=(is_array($array) && count($array) > 0); - $array=$objectpage->fetchAll($object->id); - if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors); - $atleastonepage=(is_array($array) && count($array) > 0); + print '<div class="centpercent websitebar"'.($style?' style="'.$style.'"':'').'">'; - print '<div class="centpercent websitebar"'.($style?' style="'.$style.'"':'').'">'; + print '<div class="websiteselection hideonsmartphoneimp minwidth100">'; + print '<input type="submit"'.$disabled.' class="button" value="'.dol_escape_htmltag($langs->trans("AddPage")).'" name="create">'; + print '</div>'; - print '<div class="websiteselection hideonsmartphoneimp minwidth100">'; - print '<input type="submit"'.$disabled.' class="button" value="'.dol_escape_htmltag($langs->trans("AddPage")).'" name="create">'; - print '</div>'; + print '<div class="websiteselection hideonsmartphoneimp">'; + print $langs->trans("Page").': '; + print '</div>'; + print '<div class="websiteselection">'; - print '<div class="websiteselection hideonsmartphoneimp">'; - print $langs->trans("Page").': '; - print '</div>'; - print '<div class="websiteselection">'; + if ($action != 'add') + { + $out=''; + $out.='<select name="pageid" id="pageid" class="minwidth200 maxwidth300">'; + if ($atleastonepage) + { + if (empty($pageid) && $action != 'create') // Page id is not defined, we try to take one + { + $firstpageid=0;$homepageid=0; + foreach($array as $key => $valpage) + { + if (empty($firstpageid)) $firstpageid=$valpage->id; + if ($object->fk_default_home && $key == $object->fk_default_home) $homepageid=$valpage->id; + } + $pageid=$homepageid?$homepageid:$firstpageid; // We choose home page and if not defined yet, we take first page + } + + foreach($array as $key => $valpage) + { + $out.='<option value="'.$key.'"'; + if ($pageid > 0 && $pageid == $key) $out.=' selected'; // To preselect a value + $out.='>'; + $out.=$valpage->pageurl.' - '.$valpage->title; + if ($object->fk_default_home && $key == $object->fk_default_home) $out.=' ('.$langs->trans("HomePage").')'; + $out.='</option>'; + } + } + else $out.='<option value="-1"> </option>'; + $out.='</select>'; + $out.=ajax_combobox('pageid'); + print $out; + } + else + { + print $langs->trans("New"); + } - if ($action != 'add') - { - $out=''; - $out.='<select name="pageid" id="pageid" class="minwidth200 maxwidth300">'; - if ($atleastonepage) - { - if (empty($pageid) && $action != 'create') // Page id is not defined, we try to take one - { - $firstpageid=0;$homepageid=0; - foreach($array as $key => $valpage) - { - if (empty($firstpageid)) $firstpageid=$valpage->id; - if ($object->fk_default_home && $key == $object->fk_default_home) $homepageid=$valpage->id; - } - $pageid=$homepageid?$homepageid:$firstpageid; // We choose home page and if not defined yet, we take first page - } - - foreach($array as $key => $valpage) - { - $out.='<option value="'.$key.'"'; - if ($pageid > 0 && $pageid == $key) $out.=' selected'; // To preselect a value - $out.='>'; - $out.=$valpage->pageurl.' - '.$valpage->title; - if ($object->fk_default_home && $key == $object->fk_default_home) $out.=' ('.$langs->trans("HomePage").')'; - $out.='</option>'; - } - } - else $out.='<option value="-1"> </option>'; - $out.='</select>'; - $out.=ajax_combobox('pageid'); - print $out; - } - else - { - print $langs->trans("New"); - } + print '<input type="submit" class="button" name="refreshpage" value="'.$langs->trans("Load").'"'.($atleastonepage?'':' disabled="disabled"').'>'; - print '<input type="submit" class="button" name="refreshpage" value="'.$langs->trans("Load").'"'.($atleastonepage?'':' disabled="disabled"').'>'; + if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') + { + $disabled=''; + if (empty($user->rights->websites->write)) $disabled=' disabled="disabled"'; + + // Confirmation to clone + if ($action == 'createfromclone') { + // Create an array for form + $formquestion = array( + array('type' => 'text', 'name' => 'siteref', 'label'=> $langs->trans("Website") ,'value'=> 'copy_of_'.$object->ref), + //array('type' => 'checkbox', 'name' => 'is_a_translation', 'label' => $langs->trans("SiteIsANewTranslation"), 'value' => 0), + //array('type' => 'other','name' => 'newlang','label' => $langs->trans("Language"), 'value' => $formadmin->select_language(GETPOST('newlang', 'az09')?GETPOST('newlang', 'az09'):$langs->defaultlang, 'newlang', 0, null, '', 0, 0, 'minwidth200')), + //array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("Website"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)) + ); + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id='.$object->id, $langs->trans('CloneSite'), '', 'confirm_createfromclone', $formquestion, 0, 1, 200); + + print $formconfirm; + } - if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') - { - $disabled=''; - if (empty($user->rights->websites->write)) $disabled=' disabled="disabled"'; - - // Confirmation to clone - if ($action == 'createfromclone') { - // Create an array for form - $formquestion = array( - array('type' => 'text', 'name' => 'siteref', 'label'=> $langs->trans("Website") ,'value'=> 'copy_of_'.$object->ref), - //array('type' => 'checkbox', 'name' => 'is_a_translation', 'label' => $langs->trans("SiteIsANewTranslation"), 'value' => 0), - //array('type' => 'other','name' => 'newlang','label' => $langs->trans("Language"), 'value' => $formadmin->select_language(GETPOST('newlang', 'az09')?GETPOST('newlang', 'az09'):$langs->defaultlang, 'newlang', 0, null, '', 0, 0, 'minwidth200')), - //array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("Website"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)) - ); - - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id='.$object->id, $langs->trans('CloneSite'), '', 'confirm_createfromclone', $formquestion, 0, 1, 200); - - print $formconfirm; - } - - if ($pageid > 0) - { - // Confirmation to clone - if ($action == 'createpagefromclone') { - // Create an array for form + if ($pageid > 0) + { + // Confirmation to clone + if ($action == 'createpagefromclone') { + // Create an array for form $formquestion = array( array('type' => 'text', 'name' => 'pageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME") ,'value'=> 'copy_of_'.$objectpage->pageurl), array('type' => 'checkbox', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0), @@ -1326,79 +1326,79 @@ if (count($object->records) > 0) array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("Website"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)) ); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?pageid=' . $pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 250); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?pageid=' . $pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 250); print $formconfirm; - } - - print ' '; - - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditPageMeta")).'" name="editmeta">'; - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">'; - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditHTMLSource")).'" name="editsource">'; - if ($object->fk_default_home > 0 && $pageid == $object->fk_default_home) print '<input type="submit" class="button" disabled="disabled" value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">'; - else print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">'; - print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ClonePage")).'" name="createpagefromclone">'; - print '<input type="submit" class="buttonDelete" name="delete" value="'.$langs->trans("Delete").'"'.($atleastonepage?'':' disabled="disabled"').'>'; - } - } + } - print '</div>'; // end website selection + print ' '; - print '<div class="websitetools">'; + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditPageMeta")).'" name="editmeta">'; + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">'; + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditHTMLSource")).'" name="editsource">'; + if ($object->fk_default_home > 0 && $pageid == $object->fk_default_home) print '<input type="submit" class="button" disabled="disabled" value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">'; + else print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">'; + print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ClonePage")).'" name="createpagefromclone">'; + print '<input type="submit" class="buttonDelete" name="delete" value="'.$langs->trans("Delete").'"'.($atleastonepage?'':' disabled="disabled"').'>'; + } + } - if ($website && $pageid > 0 && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')) - { - $websitepage = new WebSitePage($db); - $websitepage->fetch($pageid); - - $realpage=$urlwithroot.'/public/websites/index.php?website='.$website.'&pageref='.$websitepage->pageurl; - $pagealias = $websitepage->pageurl; - - print '<a class="websitebuttonsitepreview" id="previewpage" href="'.$realpage.'&nocache='.dol_now().'" class="button" target="tab'.$website.'" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage)).'">'; - print $form->textwithpicto('', $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage, $dataroot), 1, 'preview'); - print '</a>'; // View page in new Tab - - print '<div class="websiteinputurl" id="websiteinputpage">'; - print '<input type="text" id="previewpageurl" class="minwidth200imp" name="previewsite" value="'.$pagealias.'" disabled="disabled">'; - $htmltext=$langs->trans("PageNameAliasHelp", $langs->transnoentitiesnoconv("EditPageMeta")); - print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helppagealias'); - print '</div>'; - - $urlext=$virtualurl.'/'.$pagealias.'.php'; - $urlint=$urlwithroot.'/public/websites/index.php?website='.$website; - print '<a class="websitebuttonsitepreview'.($virtualurl?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewpageext" href="'.$urlext.'" target="tab'.$website.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $dataroot, $urlext)).'">'; - print $form->textwithpicto('', $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $dataroot, $virtualurl?$urlext:'<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>'), 1, 'preview_ext'); - print '</a>'; - //print '<input type="submit" class="button" name="previewpage" target="tab'.$website.'"value="'.$langs->trans("ViewPageInNewTab").'">'; - - // TODO Add js to save alias like we save virtual host name and use dynamic virtual host for url of id=previewpageext - } - if (! in_array($action, array('editcss','editmenu','editmedias','createsite','create','createpagefromclone'))) - { - if (preg_match('/^create/',$action)) print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; - if (preg_match('/^edit/',$action)) print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; - if ($action != 'preview') print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">'; - } + print '</div>'; // end website selection - print '</div>'; // end websitetools + print '<div class="websitetools">'; - print '<div class="websitehelp">'; - if (GETPOST('editsource', 'alpha') || GETPOST('editcontent', 'alpha')) - { - $htmltext=$langs->transnoentitiesnoconv("YouCanEditHtmlSource"); - print $form->textwithpicto($langs->trans("SyntaxHelp"), $htmltext, 1, 'help', 'inline-block', 0, 2, 'tooltipsubstitution'); - } - print '</div>'; // end websitehelp + if ($website && $pageid > 0 && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')) + { + $websitepage = new WebSitePage($db); + $websitepage->fetch($pageid); + + $realpage=$urlwithroot.'/public/websites/index.php?website='.$website.'&pageref='.$websitepage->pageurl; + $pagealias = $websitepage->pageurl; + + print '<a class="websitebuttonsitepreview" id="previewpage" href="'.$realpage.'&nocache='.dol_now().'" class="button" target="tab'.$website.'" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage)).'">'; + print $form->textwithpicto('', $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage, $dataroot), 1, 'preview'); + print '</a>'; // View page in new Tab + + print '<div class="websiteinputurl" id="websiteinputpage">'; + print '<input type="text" id="previewpageurl" class="minwidth200imp" name="previewsite" value="'.$pagealias.'" disabled="disabled">'; + $htmltext=$langs->trans("PageNameAliasHelp", $langs->transnoentitiesnoconv("EditPageMeta")); + print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helppagealias'); + print '</div>'; + + $urlext=$virtualurl.'/'.$pagealias.'.php'; + $urlint=$urlwithroot.'/public/websites/index.php?website='.$website; + print '<a class="websitebuttonsitepreview'.($virtualurl?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewpageext" href="'.$urlext.'" target="tab'.$website.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $dataroot, $urlext)).'">'; + print $form->textwithpicto('', $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $dataroot, $virtualurl?$urlext:'<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>'), 1, 'preview_ext'); + print '</a>'; + //print '<input type="submit" class="button" name="previewpage" target="tab'.$website.'"value="'.$langs->trans("ViewPageInNewTab").'">'; + + // TODO Add js to save alias like we save virtual host name and use dynamic virtual host for url of id=previewpageext + } + if (! in_array($action, array('editcss','editmenu','editmedias','createsite','create','createpagefromclone'))) + { + if (preg_match('/^create/',$action)) print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; + if (preg_match('/^edit/',$action)) print '<input type="submit" id="savefile" class="button buttonforacesave" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">'; + if ($action != 'preview') print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">'; + } + print '</div>'; // end websitetools + print '<div class="websitehelp">'; + if (GETPOST('editsource', 'alpha') || GETPOST('editcontent', 'alpha')) + { + $htmltext=$langs->transnoentitiesnoconv("YouCanEditHtmlSource"); + print $form->textwithpicto($langs->trans("SyntaxHelp"), $htmltext, 1, 'help', 'inline-block', 0, 2, 'tooltipsubstitution'); + } + print '</div>'; // end websitehelp - if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') - { - // Adding jquery code to change on the fly url of preview ext - if (! empty($conf->use_javascript_ajax)) - { - print '<script type="text/javascript" language="javascript"> + + + if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') + { + // Adding jquery code to change on the fly url of preview ext + if (! empty($conf->use_javascript_ajax)) + { + print '<script type="text/javascript" language="javascript"> jQuery(document).ready(function() { jQuery("#websiteinputurl").keyup(function() { console.log("Website external url modified "+jQuery("#previewsiteurl").val()); @@ -1428,17 +1428,17 @@ if (count($object->records) > 0) }); }); </script>'; - } - } - } + } + } + } } else { - print '<div class="websiteselection">'; - $langs->load("errors"); - print $langs->trans("ErrorModuleSetupNotComplete"); - print '<div>'; - $action=''; + print '<div class="websiteselection">'; + $langs->load("errors"); + print $langs->trans("ErrorModuleSetupNotComplete"); + print '<div>'; + $action=''; } @@ -1453,125 +1453,125 @@ $head = array(); if ($action == 'editcss') { - print '<div class="fiche">'; - - print '<br>'; - - $csscontent = @file_get_contents($filecss); - // Clean the php css file to remove php code and get only css part - $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $csscontent); - $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); - if (! trim($csscontent)) $csscontent='/* CSS content (all pages) */'."\n".'body.bodywebsite { margin: 0; }'; - - $jscontent = @file_get_contents($filejs); - // Clean the php js file to remove php code and get only js part - $jscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $jscontent); - $jscontent.= GETPOST('WEBSITE_JS_INLINE'); - if (! trim($jscontent)) $jscontent='/* JS content (all pages) */'."\n"; - - $htmlheader = @file_get_contents($filehtmlheader); - // Clean the php htmlheader file to remove php code and get only html part - $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htmlheader); - if (! trim($htmlheader)) $htmlheader='<!-- HTML header content (common for all pages) -->'; - else $htmlheader='<html>'."\n".trim($htmlheader)."\n".'</html>'; - - $robotcontent = @file_get_contents($filerobot); - // Clean the php htmlheader file to remove php code and get only html part - $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $robotcontent); - if (! trim($robotcontent)) - { - $robotcontent.="# Robot file. Generated with ".DOL_APPLICATION_TITLE."\n"; - $robotcontent.="User-agent: *\n"; - $robotcontent.="Allow: /public/\n"; - $robotcontent.="Disallow: /administrator/\n"; - } - - $htaccesscontent = @file_get_contents($filehtaccess); - // Clean the php htaccesscontent file to remove php code and get only html part - $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htaccesscontent); - if (! trim($htaccesscontent)) - { - $htaccesscontent.="# Order allow,deny\n"; + print '<div class="fiche">'; + + print '<br>'; + + $csscontent = @file_get_contents($filecss); + // Clean the php css file to remove php code and get only css part + $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $csscontent); + $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); + if (! trim($csscontent)) $csscontent='/* CSS content (all pages) */'."\n".'body.bodywebsite { margin: 0; }'; + + $jscontent = @file_get_contents($filejs); + // Clean the php js file to remove php code and get only js part + $jscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $jscontent); + $jscontent.= GETPOST('WEBSITE_JS_INLINE'); + if (! trim($jscontent)) $jscontent='/* JS content (all pages) */'."\n"; + + $htmlheader = @file_get_contents($filehtmlheader); + // Clean the php htmlheader file to remove php code and get only html part + $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htmlheader); + if (! trim($htmlheader)) $htmlheader='<!-- HTML header content (common for all pages) -->'; + else $htmlheader='<html>'."\n".trim($htmlheader)."\n".'</html>'; + + $robotcontent = @file_get_contents($filerobot); + // Clean the php htmlheader file to remove php code and get only html part + $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $robotcontent); + if (! trim($robotcontent)) + { + $robotcontent.="# Robot file. Generated with ".DOL_APPLICATION_TITLE."\n"; + $robotcontent.="User-agent: *\n"; + $robotcontent.="Allow: /public/\n"; + $robotcontent.="Disallow: /administrator/\n"; + } + + $htaccesscontent = @file_get_contents($filehtaccess); + // Clean the php htaccesscontent file to remove php code and get only html part + $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htaccesscontent); + if (! trim($htaccesscontent)) + { + $htaccesscontent.="# Order allow,deny\n"; $htaccesscontent.="# Deny from all\n"; - } - //else $htaccesscontent='<html>'."\n".$htaccesscontent."\n".'</html>';*/ + } + //else $htaccesscontent='<html>'."\n".$htaccesscontent."\n".'</html>';*/ - dol_fiche_head(); + dol_fiche_head(); - print '<!-- Edit CSS -->'."\n"; - print '<table class="border" width="100%">'; + print '<!-- Edit CSS -->'."\n"; + print '<table class="border" width="100%">'; - // Website - print '<tr><td class="titlefieldcreate">'; - print $langs->trans('WebSite'); - print '</td><td>'; - print $website; - print '</td></tr>'; + // Website + print '<tr><td class="titlefieldcreate">'; + print $langs->trans('WebSite'); + print '</td><td>'; + print $website; + print '</td></tr>'; - // CSS file - print '<tr><td class="tdtop">'; - print $langs->trans('WEBSITE_CSS_INLINE'); - print '</td><td>'; + // CSS file + print '<tr><td class="tdtop">'; + print $langs->trans('WEBSITE_CSS_INLINE'); + print '</td><td>'; - $doleditor=new DolEditor('WEBSITE_CSS_INLINE', $csscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + $doleditor=new DolEditor('WEBSITE_CSS_INLINE', $csscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'CSS', 'css'); - print '</td></tr>'; + print '</td></tr>'; - // JS file - print '<tr><td class="tdtop">'; - print $langs->trans('WEBSITE_JS_INLINE'); - print '</td><td>'; + // JS file + print '<tr><td class="tdtop">'; + print $langs->trans('WEBSITE_JS_INLINE'); + print '</td><td>'; - $doleditor=new DolEditor('WEBSITE_JS_INLINE', $jscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + $doleditor=new DolEditor('WEBSITE_JS_INLINE', $jscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'JS', 'javascript'); - print '</td></tr>'; + print '</td></tr>'; - // Common HTML header + // Common HTML header print '<tr><td class="tdtop">'; - print $langs->trans('WEBSITE_HTML_HEADER'); - print '</td><td>'; + print $langs->trans('WEBSITE_HTML_HEADER'); + print '</td><td>'; - $doleditor=new DolEditor('WEBSITE_HTML_HEADER', $htmlheader, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + $doleditor=new DolEditor('WEBSITE_HTML_HEADER', $htmlheader, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'HTML Header', 'html'); - print '</td></tr>'; + print '</td></tr>'; - // Robot file + // Robot file print '<tr><td class="tdtop">'; - print $langs->trans('WEBSITE_ROBOT'); - print '</td><td>'; + print $langs->trans('WEBSITE_ROBOT'); + print '</td><td>'; - $doleditor=new DolEditor('WEBSITE_ROBOT', $robotcontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + $doleditor=new DolEditor('WEBSITE_ROBOT', $robotcontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'Robot file', 'txt'); - print '</td></tr>'; + print '</td></tr>'; - // .htaccess + // .htaccess print '<tr><td class="tdtop">'; - print $langs->trans('WEBSITE_HTACCESS'); - print '</td><td>'; + print $langs->trans('WEBSITE_HTACCESS'); + print '</td><td>'; - $doleditor=new DolEditor('WEBSITE_HTACCESS', $htaccesscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + $doleditor=new DolEditor('WEBSITE_HTACCESS', $htaccesscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, $langs->trans("File").' .htaccess', 'txt'); - print '</td></tr>'; + print '</td></tr>'; - print '</table>'; + print '</table>'; - dol_fiche_end(); + dol_fiche_end(); - print '</div>'; + print '</div>'; - print '<br>'; + print '<br>'; } if ($action == 'createsite') { - print '<div class="fiche">'; + print '<div class="fiche">'; - print '<br>'; + print '<br>'; /*$h = 0; $head = array(); @@ -1585,60 +1585,60 @@ if ($action == 'createsite') */ if ($action == 'create') print_fiche_titre($langs->trans("AddSite")); - print '<!-- Add site -->'."\n"; - //print '<div class="fichecenter">'; + print '<!-- Add site -->'."\n"; + //print '<div class="fichecenter">'; - print '<table class="border" width="100%">'; + print '<table class="border" width="100%">'; - if (GETPOST('WEBSITE_REF')) $siteref=GETPOST('WEBSITE_REF','alpha'); - if (GETPOST('WEBSITE_DESCRIPTION')) $sitedesc=GETPOST('WEBSITE_DESCRIPTION','alpha'); + if (GETPOST('WEBSITE_REF')) $siteref=GETPOST('WEBSITE_REF','alpha'); + if (GETPOST('WEBSITE_DESCRIPTION')) $sitedesc=GETPOST('WEBSITE_DESCRIPTION','alpha'); - print '<tr><td class="titlefieldcreate fieldrequired">'; - print $langs->trans('Ref'); - print '</td><td>'; - print '<input type="text" class="flat maxwidth300" name="WEBSITE_REF" value="'.dol_escape_htmltag($siteref).'">'; - print '</td></tr>'; + print '<tr><td class="titlefieldcreate fieldrequired">'; + print $langs->trans('Ref'); + print '</td><td>'; + print '<input type="text" class="flat maxwidth300" name="WEBSITE_REF" value="'.dol_escape_htmltag($siteref).'">'; + print '</td></tr>'; - print '<tr><td>'; - print $langs->trans('Description'); - print '</td><td>'; - print '<input type="text" class="flat minwidth300" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($sitedesc).'">'; - print '</td></tr>'; + print '<tr><td>'; + print $langs->trans('Description'); + print '</td><td>'; + print '<input type="text" class="flat minwidth300" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($sitedesc).'">'; + print '</td></tr>'; - print '<tr><td>'; - print $form->textwithpicto($langs->trans('Virtualhost'), $langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.'/websites/<i>websiteref</i>'), 1, 'help', '', 0, 2, 'tooltipvirtual'); - print '</td><td>'; - print '<input type="text" class="flat minwidth300" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($sitedesc).'">'; - print '</td></tr>'; + print '<tr><td>'; + print $form->textwithpicto($langs->trans('Virtualhost'), $langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.'/websites/<i>websiteref</i>'), 1, 'help', '', 0, 2, 'tooltipvirtual'); + print '</td><td>'; + print '<input type="text" class="flat minwidth300" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($sitedesc).'">'; + print '</td></tr>'; - print '</table>'; + print '</table>'; - if ($action == 'createsite') - { - print '<div class="center">'; + if ($action == 'createsite') + { + print '<div class="center">'; - print '<input class="button" type="submit" name="add" value="'.$langs->trans("Create").'">'; - print '<input class="button" type="submit" name="preview" value="'.$langs->trans("Cancel").'">'; + print '<input class="button" type="submit" name="add" value="'.$langs->trans("Create").'">'; + print '<input class="button" type="submit" name="preview" value="'.$langs->trans("Cancel").'">'; - print '</div>'; - } + print '</div>'; + } //print '</div>'; - //dol_fiche_end(); + //dol_fiche_end(); - print '</div>'; + print '</div>'; - print '<br>'; + print '<br>'; } if ($action == 'editmeta' || $action == 'create') { - print '<div class="fiche">'; + print '<div class="fiche">'; - print '<br>'; + print '<br>'; /*$h = 0; $head = array(); @@ -1652,45 +1652,45 @@ if ($action == 'editmeta' || $action == 'create') */ if ($action == 'create') print_fiche_titre($langs->trans("AddPage")); - print '<!-- Edit or create page -->'."\n"; - //print '<div class="fichecenter">'; + print '<!-- Edit or create page -->'."\n"; + //print '<div class="fichecenter">'; - if ($action == 'create') - { - print '<br>'; - - print ' * '.$langs->trans("CreateByFetchingExternalPage").'<br><hr>'; - print '<table class="border" width="100%">'; - print '<tr><td class="titlefieldcreate">'; - print $langs->trans("URL"); - print '</td><td>'; - print '<input class="flat minwidth300" type="text" name="externalurl" value="'.dol_escape_htmltag(GETPOST('externalurl','alpha')).'" placeholder="http://externalsite/pagetofetch"> '; + if ($action == 'create') + { + print '<br>'; + + print ' * '.$langs->trans("CreateByFetchingExternalPage").'<br><hr>'; + print '<table class="border" width="100%">'; + print '<tr><td class="titlefieldcreate">'; + print $langs->trans("URL"); + print '</td><td>'; + print '<input class="flat minwidth300" type="text" name="externalurl" value="'.dol_escape_htmltag(GETPOST('externalurl','alpha')).'" placeholder="http://externalsite/pagetofetch"> '; print '<input class="button" type="submit" name="fetchexternalurl" value="'.dol_escape_htmltag($langs->trans("FetchAndCreate")).'">'; - print '</td></tr>'; - print '</table>'; + print '</td></tr>'; + print '</table>'; - print '<br>'; + print '<br>'; - print ' * '.$langs->trans("OrEnterPageInfoManually").'<br><hr>'; - } - - print '<table class="border" width="100%">'; - - if ($action != 'create') - { - print '<tr><td class="titlefield">'; - print $langs->trans('IDOfPage'); - print '</td><td>'; - print $pageid; - print '</td></tr>'; + print ' * '.$langs->trans("OrEnterPageInfoManually").'<br><hr>'; + } - print '<tr><td class="titlefield">'; - print $langs->trans('WEBSITE_PAGEURL'); - print '</td><td>'; - print '/public/websites/index.php?website='.urlencode($website).'&pageid='.urlencode($pageid); - print '</td></tr>'; + print '<table class="border" width="100%">'; - /* + if ($action != 'create') + { + print '<tr><td class="titlefield">'; + print $langs->trans('IDOfPage'); + print '</td><td>'; + print $pageid; + print '</td></tr>'; + + print '<tr><td class="titlefield">'; + print $langs->trans('WEBSITE_PAGEURL'); + print '</td><td>'; + print '/public/websites/index.php?website='.urlencode($website).'&pageid='.urlencode($pageid); + print '</td></tr>'; + + /* print '<tr><td class="titlefield">'; print $langs->trans('InitiallyGrabbedFrom'); print '</td><td>'; @@ -1698,89 +1698,89 @@ if ($action == 'editmeta' || $action == 'create') print '</td></tr>'; */ - $pageurl=$objectpage->pageurl; - $pagetitle=$objectpage->title; - $pagedescription=$objectpage->description; - $pagekeywords=$objectpage->keywords; - $pagelang=$objectpage->lang; - $pagehtmlheader=$objectpage->htmlheader; - } - if (GETPOST('WEBSITE_PAGENAME','alpha')) $pageurl=GETPOST('WEBSITE_PAGENAME','alpha'); - if (GETPOST('WEBSITE_TITLE','alpha')) $pagetitle=GETPOST('WEBSITE_TITLE','alpha'); - if (GETPOST('WEBSITE_DESCRIPTION','alpha')) $pagedescription=GETPOST('WEBSITE_DESCRIPTION','alpha'); - if (GETPOST('WEBSITE_KEYWORDS','alpha')) $pagekeywords=GETPOST('WEBSITE_KEYWORDS','alpha'); - if (GETPOST('WEBSITE_LANG','aZ09')) $pagelang=GETPOST('WEBSITE_LANG','aZ09'); + $pageurl=$objectpage->pageurl; + $pagetitle=$objectpage->title; + $pagedescription=$objectpage->description; + $pagekeywords=$objectpage->keywords; + $pagelang=$objectpage->lang; + $pagehtmlheader=$objectpage->htmlheader; + } + if (GETPOST('WEBSITE_PAGENAME','alpha')) $pageurl=GETPOST('WEBSITE_PAGENAME','alpha'); + if (GETPOST('WEBSITE_TITLE','alpha')) $pagetitle=GETPOST('WEBSITE_TITLE','alpha'); + if (GETPOST('WEBSITE_DESCRIPTION','alpha')) $pagedescription=GETPOST('WEBSITE_DESCRIPTION','alpha'); + if (GETPOST('WEBSITE_KEYWORDS','alpha')) $pagekeywords=GETPOST('WEBSITE_KEYWORDS','alpha'); + if (GETPOST('WEBSITE_LANG','aZ09')) $pagelang=GETPOST('WEBSITE_LANG','aZ09'); if (GETPOST('htmlheader','none')) $pagehtmlheader=GETPOST('htmlheader','none'); - print '<tr><td class="titlefieldcreate fieldrequired">'; - print $langs->trans('WEBSITE_PAGENAME'); - print '</td><td>'; - print '<input type="text" class="flat maxwidth300" name="WEBSITE_PAGENAME" value="'.dol_escape_htmltag($pageurl).'">'; - print '</td></tr>'; - - print '<tr><td class="fieldrequired">'; - print $langs->trans('WEBSITE_TITLE'); - print '</td><td>'; - print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_TITLE" value="'.dol_escape_htmltag($pagetitle).'">'; - print '</td></tr>'; - - print '<tr><td>'; - print $langs->trans('WEBSITE_DESCRIPTION'); - print '</td><td>'; - print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($pagedescription).'">'; - print '</td></tr>'; - - print '<tr><td>'; - print $langs->trans('WEBSITE_KEYWORDS'); - print '</td><td>'; - print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_KEYWORDS" value="'.dol_escape_htmltag($pagekeywords).'">'; - print '</td></tr>'; - - print '<tr><td>'; - print $langs->trans('Language'); - print '</td><td>'; - print $formadmin->select_language($pagelang?$pagelang:$langs->defaultlang, 'WEBSITE_LANG'); - print '</td></tr>'; - - print '<tr><td>'; - print $langs->trans('HtmlHeaderPage'); - print '</td><td>'; - $doleditor=new DolEditor('htmlheader', $pagehtmlheader, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); - print $doleditor->Create(1, '', true, 'HTML Header', 'html'); - print '</td></tr>'; + print '<tr><td class="titlefieldcreate fieldrequired">'; + print $langs->trans('WEBSITE_PAGENAME'); + print '</td><td>'; + print '<input type="text" class="flat maxwidth300" name="WEBSITE_PAGENAME" value="'.dol_escape_htmltag($pageurl).'">'; + print '</td></tr>'; + + print '<tr><td class="fieldrequired">'; + print $langs->trans('WEBSITE_TITLE'); + print '</td><td>'; + print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_TITLE" value="'.dol_escape_htmltag($pagetitle).'">'; + print '</td></tr>'; + + print '<tr><td>'; + print $langs->trans('WEBSITE_DESCRIPTION'); + print '</td><td>'; + print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($pagedescription).'">'; + print '</td></tr>'; + + print '<tr><td>'; + print $langs->trans('WEBSITE_KEYWORDS'); + print '</td><td>'; + print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_KEYWORDS" value="'.dol_escape_htmltag($pagekeywords).'">'; + print '</td></tr>'; + + print '<tr><td>'; + print $langs->trans('Language'); + print '</td><td>'; + print $formadmin->select_language($pagelang?$pagelang:$langs->defaultlang, 'WEBSITE_LANG'); + print '</td></tr>'; + + print '<tr><td>'; + print $langs->trans('HtmlHeaderPage'); + print '</td><td>'; + $doleditor=new DolEditor('htmlheader', $pagehtmlheader, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + print $doleditor->Create(1, '', true, 'HTML Header', 'html'); + print '</td></tr>'; - print '</table>'; + print '</table>'; - if ($action == 'create') - { - print '<div class="center">'; + if ($action == 'create') + { + print '<div class="center">'; - print '<input class="button" type="submit" name="add" value="'.$langs->trans("Create").'">'; - print '<input class="button" type="submit" name="preview" value="'.$langs->trans("Cancel").'">'; + print '<input class="button" type="submit" name="add" value="'.$langs->trans("Create").'">'; + print '<input class="button" type="submit" name="preview" value="'.$langs->trans("Cancel").'">'; - print '</div>'; - } + print '</div>'; + } //print '</div>'; - //dol_fiche_end(); + //dol_fiche_end(); - print '</div>'; + print '</div>'; - print '<br>'; + print '<br>'; } if ($action == 'editmedias') { - print '<!-- Edit Media -->'."\n"; - print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>'; + print '<!-- Edit Media -->'."\n"; + print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>'; } if ($action == 'editmenu') { - print '<!-- Edit Menu -->'."\n"; - print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>'; + print '<!-- Edit Menu -->'."\n"; + print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>'; } if ($action == 'editsource') @@ -1802,21 +1802,21 @@ if ($action == 'editsource') if ($action == 'editcontent') { - /* + /* * Editing with default ckeditor */ - $contentforedit = ''; - /*$contentforedit.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers + $contentforedit = ''; + /*$contentforedit.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers $contentforedit.=$csscontent; $contentforedit.='</style>'."\n";*/ - $contentforedit .= $objectpage->content; + $contentforedit .= $objectpage->content; - $contentforedit = preg_replace('/(<img.*src=")(?!http)/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $contentforedit, -1, $nbrep); + $contentforedit = preg_replace('/(<img.*src=")(?!http)/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $contentforedit, -1, $nbrep); - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('PAGE_CONTENT',$contentforedit,'',500,'Full','',true,true,true,ROWS_5,'90%'); - $doleditor->Create(0, '', false); + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('PAGE_CONTENT',$contentforedit,'',500,'Full','',true,true,true,ROWS_5,'90%'); + $doleditor->Create(0, '', false); } print "</div>\n</form>\n"; @@ -1825,40 +1825,40 @@ print "</div>\n</form>\n"; if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') { - if ($pageid > 0) - { - // Ouput page under the Dolibarr top menu - $objectpage->fetch($pageid); - $csscontent = @file_get_contents($filecss); - $jscontent = @file_get_contents($filejs); + if ($pageid > 0) + { + // Ouput page under the Dolibarr top menu + $objectpage->fetch($pageid); + $csscontent = @file_get_contents($filecss); + $jscontent = @file_get_contents($filejs); - $out = '<!-- Page content '.$filetpl.' : Div with (CSS Of website from file + Style/htmlheader of page from database + Page content from database) -->'."\n"; + $out = '<!-- Page content '.$filetpl.' : Div with (CSS Of website from file + Style/htmlheader of page from database + Page content from database) -->'."\n"; - $out.='<div id="websitecontentundertopmenu" class="websitecontentundertopmenu">'."\n"; + $out.='<div id="websitecontentundertopmenu" class="websitecontentundertopmenu">'."\n"; - // REPLACEMENT OF LINKS When page called by website editor + // REPLACEMENT OF LINKS When page called by website editor - $out.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers - $out.= '<!-- Include website CSS file -->'."\n"; - $out.=dolWebsiteReplacementOfLinks($object, $csscontent); - $out.= '<!-- Include HTML header from page inline block -->'."\n"; - $out.= $objectpage->htmlheader."\n"; - $out.='</style>'."\n"; + $out.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers + $out.= '<!-- Include website CSS file -->'."\n"; + $out.=dolWebsiteReplacementOfLinks($object, $csscontent); + $out.= '<!-- Include HTML header from page inline block -->'."\n"; + $out.= $objectpage->htmlheader."\n"; + $out.='</style>'."\n"; $out.='<div id="bodywebsite" class="bodywebsite">'."\n"; - $out.=dolWebsiteReplacementOfLinks($object, $objectpage->content)."\n"; + $out.=dolWebsiteReplacementOfLinks($object, $objectpage->content)."\n"; - $out.='</div>'; + $out.='</div>'; - $out.='</div>'; + $out.='</div>'; - $out.= "\n".'<!-- End page content '.$filetpl.' -->'."\n\n"; + $out.= "\n".'<!-- End page content '.$filetpl.' -->'."\n\n"; - print $out; + print $out; - /*file_put_contents($filetpl, $out); + /*file_put_contents($filetpl, $out); if (! empty($conf->global->MAIN_UMASK)) @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); @@ -1876,14 +1876,14 @@ if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpa //include_once $original_file_osencoded; */ - /*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website.'&pageid='.$pageid.'"/>'; + /*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website.'&pageid='.$pageid.'"/>'; print '</iframe>';*/ - } - else - { - print '<br><br><div class="center">'.$langs->trans("PreviewOfSiteNotYetAvailable", $website).'</center><br><br><br>'; - print '<div class="center"><div class="logo_setup"></div></div>'; - } + } + else + { + print '<br><br><div class="center">'.$langs->trans("PreviewOfSiteNotYetAvailable", $website).'</center><br><br><br>'; + print '<div class="center"><div class="logo_setup"></div></div>'; + } }