28 include_once
'inc.php';
29 if (file_exists($conffile)) {
30 include_once $conffile;
32 require_once $dolibarr_main_document_root.
'/core/lib/admin.lib.php';
33 include_once $dolibarr_main_document_root.
'/core/lib/images.lib.php';
34 require_once $dolibarr_main_document_root.
'/core/class/extrafields.class.php';
35 require_once
'lib/repair.lib.php';
43 $err = error_reporting();
46 error_reporting($err);
48 $setuplang =
GETPOST(
"selectlang",
'aZ09', 3) ?
GETPOST(
"selectlang",
'aZ09', 3) :
'auto';
49 $langs->setDefaultLang($setuplang);
51 $langs->loadLangs(array(
"admin",
"install",
"other"));
53 if ($dolibarr_main_db_type ==
"mysqli") {
56 if ($dolibarr_main_db_type ==
"pgsql") {
59 if ($dolibarr_main_db_type ==
"mssql") {
65 if (!is_object($conf)) {
79 print
'<h3>'.$langs->trans(
"Repair").
'</h3>';
81 print
'Option standard (\'test\' or \'confirmed\') is '.(GETPOST(
'standard',
'alpha') ?
GETPOST(
'standard',
'alpha') :
'undefined').
'<br>'.
"\n";
83 print
'Option force_disable_of_modules_not_found (\'test\' or \'confirmed\') is '.(GETPOST(
'force_disable_of_modules_not_found',
'alpha') ?
GETPOST(
'force_disable_of_modules_not_found',
'alpha') :
'undefined').
'<br>'.
"\n";
85 print
'Option restore_thirdparties_logos (\'test\' or \'confirmed\') is '.(GETPOST(
'restore_thirdparties_logos',
'alpha') ?
GETPOST(
'restore_thirdparties_logos',
'alpha') :
'undefined').
'<br>'.
"\n";
86 print
'Option restore_user_pictures (\'test\' or \'confirmed\') is '.(GETPOST(
'restore_user_pictures',
'alpha') ?
GETPOST(
'restore_user_pictures',
'alpha') :
'undefined').
'<br>'.
"\n";
87 print
'Option rebuild_product_thumbs (\'test\' or \'confirmed\') is '.(GETPOST(
'rebuild_product_thumbs',
'alpha') ?
GETPOST(
'rebuild_product_thumbs',
'alpha') :
'undefined').
'<br>'.
"\n";
89 print
'Option clean_linked_elements (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_linked_elements',
'alpha') ?
GETPOST(
'clean_linked_elements',
'alpha') :
'undefined').
'<br>'.
"\n";
90 print
'Option clean_menus (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_menus',
'alpha') ?
GETPOST(
'clean_menus',
'alpha') :
'undefined').
'<br>'.
"\n";
91 print
'Option clean_orphelin_dir (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_orphelin_dir',
'alpha') ?
GETPOST(
'clean_orphelin_dir',
'alpha') :
'undefined').
'<br>'.
"\n";
92 print
'Option clean_product_stock_batch (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_product_stock_batch',
'alpha') ?
GETPOST(
'clean_product_stock_batch',
'alpha') :
'undefined').
'<br>'.
"\n";
93 print
'Option clean_perm_table (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_perm_table',
'alpha') ?
GETPOST(
'clean_perm_table',
'alpha') :
'undefined').
'<br>'.
"\n";
94 print
'Option repair_link_dispatch_lines_supplier_order_lines, (\'test\' or \'confirmed\') is '.(GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha') ?
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha') :
'undefined').
'<br>'.
"\n";
96 print
'Option set_empty_time_spent_amount (\'test\' or \'confirmed\') is '.(GETPOST(
'set_empty_time_spent_amount',
'alpha') ?
GETPOST(
'set_empty_time_spent_amount',
'alpha') :
'undefined').
'<br>'.
"\n";
98 print
'Option force_utf8_on_tables (force utf8 + row=dynamic), for mysql/mariadb only (\'test\' or \'confirmed\') is '.(GETPOST(
'force_utf8_on_tables',
'alpha') ?
GETPOST(
'force_utf8_on_tables',
'alpha') :
'undefined').
'<br>'.
"\n";
99 print
"Option force_utf8mb4_on_tables (force utf8mb4 + row=dynamic, EXPERIMENTAL!), for mysql/mariadb only ('test' or 'confirmed') is ".(GETPOST(
'force_utf8mb4_on_tables',
'alpha') ?
GETPOST(
'force_utf8mb4_on_tables',
'alpha') :
'undefined').
"<br>\n";
101 print
'Option rebuild_sequences, for postgresql only (\'test\' or \'confirmed\') is '.(GETPOST(
'rebuild_sequences',
'alpha') ?
GETPOST(
'rebuild_sequences',
'alpha') :
'undefined').
'<br>'.
"\n";
104 print
'<table cellspacing="0" cellpadding="1" border="0" width="100%">';
108 if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass) || !empty($dolibarr_main_db_encrypted_pass)) {
109 require_once $dolibarr_main_document_root.
'/core/lib/security.lib.php';
110 if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass)) {
111 $dolibarr_main_db_pass = preg_replace(
'/crypted:/i',
'', $dolibarr_main_db_pass);
112 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_pass);
113 $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass;
115 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_encrypted_pass);
120 $conf->db->type = $dolibarr_main_db_type;
121 $conf->db->host = $dolibarr_main_db_host;
122 $conf->db->port = $dolibarr_main_db_port;
123 $conf->db->name = $dolibarr_main_db_name;
124 $conf->db->user = $dolibarr_main_db_user;
125 $conf->db->pass = $dolibarr_main_db_pass;
128 $conf->db->dolibarr_main_db_encryption = isset($dolibarr_main_db_encryption) ? $dolibarr_main_db_encryption :
'';
129 $conf->db->dolibarr_main_db_cryptkey = isset($dolibarr_main_db_cryptkey) ? $dolibarr_main_db_cryptkey :
'';
131 $db =
getDoliDBInstance($conf->db->type, $conf->db->host, $conf->db->user, $conf->db->pass, $conf->db->name, (
int) $conf->db->port);
133 if ($db->connected) {
134 print
'<tr><td class="nowrap">';
135 print $langs->trans(
"ServerConnection").
" : $dolibarr_main_db_host</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
136 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ServerConnection").
": ".$dolibarr_main_db_host.$langs->transnoentities(
"OK"));
139 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->transnoentities(
"Error").
"</td></tr>";
140 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
145 if ($db->database_selected) {
146 print
'<tr><td class="nowrap">';
147 print $langs->trans(
"DatabaseConnection").
" : ".$dolibarr_main_db_name.
"</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
151 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->trans(
"Error").
"</td></tr>";
152 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
159 $version = $db->getVersion();
160 $versionarray = $db->getVersionArray();
161 print
'<tr><td>'.$langs->trans(
"ServerVersion").
'</td>';
162 print
'<td class="right">'.$version.
'</td></tr>';
167 $conf->setValues($db);
169 if (defined(
'SYSLOG_FILE')) {
170 $conf->global->SYSLOG_FILE = constant(
'SYSLOG_FILE');
172 $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
177 $oneoptionset = (
GETPOST(
'standard',
'alpha') ||
GETPOST(
'restore_thirdparties_logos',
'alpha') ||
GETPOST(
'clean_linked_elements',
'alpha') ||
GETPOST(
'clean_menus',
'alpha')
178 ||
GETPOST(
'clean_orphelin_dir',
'alpha') ||
GETPOST(
'clean_product_stock_batch',
'alpha') ||
GETPOST(
'set_empty_time_spent_amount',
'alpha') ||
GETPOST(
'rebuild_product_thumbs',
'alpha')
179 ||
GETPOST(
'clean_perm_table',
'alpha')
180 ||
GETPOST(
'force_disable_of_modules_not_found',
'alpha')
181 ||
GETPOST(
'force_utf8_on_tables',
'alpha') ||
GETPOST(
'force_utf8mb4_on_tables',
'alpha')
182 ||
GETPOST(
'rebuild_sequences',
'alpha'));
184 if ($ok && $oneoptionset) {
186 print
'<tr><td colspan="2">'.$langs->trans(
"PleaseBePatient").
'<br><br></td></tr>';
192 if ($ok &&
GETPOST(
'standard',
'alpha')) {
193 $dir =
"mysql/migration/";
200 $filesindir = array();
201 $handle = opendir($dir);
202 if (is_resource($handle)) {
203 while (($file = readdir($handle)) !==
false) {
204 if (preg_match(
'/\.sql$/i', $file)) {
205 $filesindir[] = $file;
211 foreach ($filesindir as $file) {
212 if (preg_match(
'/repair/i', $file)) {
218 foreach ($filelist as $file) {
219 print
'<tr><td class="nowrap">*** ';
220 print $langs->trans(
"Script").
'</td><td class="right">'.$file.
'</td></tr>';
222 $name = substr($file, 0,
dol_strlen($file) - 4);
225 $ok =
run_sql($dir.$file, 0,
'', 1);
232 if ($ok &&
GETPOST(
'standard',
'alpha')) {
234 $listofmodulesextra = array(
'societe'=>
'societe',
'adherent'=>
'adherent',
'product'=>
'product',
235 'socpeople'=>
'socpeople',
'propal'=>
'propal',
'commande'=>
'commande',
'facture'=>
'facture',
236 'supplier_proposal'=>
'supplier_proposal',
'commande_fournisseur'=>
'commande_fournisseur',
'facture_fourn'=>
'facture_fourn',
237 'actioncomm'=>
'actioncomm',
'bom_bom'=>
'bom_bom',
'mrp_mo'=>
'mrp_mo',
238 'adherent_type'=>
'adherent_type',
'user'=>
'user',
'projet'=>
'projet',
'projet_task'=>
'projet_task');
239 print
'<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
240 foreach ($listofmodulesextra as $tablename => $elementtype) {
242 $tableextra = MAIN_DB_PREFIX.$tablename.
'_extrafields';
245 $arrayoffieldsdesc = $extrafields->fetch_name_optionals_label($elementtype);
248 $arrayoffieldsfound = array();
249 $resql = $db->DDLDescTable($tableextra);
251 print
'<tr><td>Check availability of extra field for '.$tableextra.
"<br>\n";
253 while ($obj = $db->fetch_object($resql)) {
254 $fieldname = $fieldtype =
'';
255 if (preg_match(
'/mysql/', $db->type)) {
256 $fieldname = $obj->Field;
257 $fieldtype = $obj->Type;
259 $fieldname = isset($obj->Key) ? $obj->Key : $obj->attname;
260 $fieldtype = isset($obj->Type) ? $obj->Type :
'varchar';
263 if (empty($fieldname)) {
266 if (in_array($fieldname, array(
'rowid',
'tms',
'fk_object',
'import_key'))) {
269 $arrayoffieldsfound[$fieldname] = array(
'type'=>$fieldtype);
273 foreach ($arrayoffieldsdesc as $code => $label) {
274 if (!in_array($code, array_keys($arrayoffieldsfound))) {
275 print
'Found field '.$code.
' declared into '.MAIN_DB_PREFIX.
'extrafields table but not found into desc of table '.$tableextra.
" -> ";
276 $type = $extrafields->attributes[$elementtype][
'type'][$code]; $length = $extrafields->attributes[$elementtype][
'size'][$code]; $attribute =
''; $default =
''; $extra =
''; $null =
'null';
278 if ($type ==
'boolean') {
281 } elseif ($type ==
'price') {
284 } elseif ($type ==
'phone') {
287 } elseif ($type ==
'mail') {
290 } elseif (($type ==
'select') || ($type ==
'sellist') || ($type ==
'radio') || ($type ==
'checkbox') || ($type ==
'chkbxlst')) {
293 } elseif ($type ==
'link') {
304 'attribute'=>$attribute,
312 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
313 $result = $db->DDLAddField($tableextra, $code, $field_desc,
"");
316 print
"KO ".$db->lasterror.
"<br>\n";
321 print
' - Mode test, no column added.';
326 print
"</td><td> </td></tr>\n";
335 if ($ok &&
GETPOST(
'standard',
'alpha')) {
341 if ($ok &&
GETPOST(
'standard',
'alpha')) {
342 print
'<tr><td colspan="2"><br>*** Clean constant record of modules not enabled</td></tr>';
344 $sql =
"SELECT name, entity, value";
345 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
346 $sql .=
" WHERE name LIKE 'MAIN_MODULE_%_TPL' OR name LIKE 'MAIN_MODULE_%_CSS' OR name LIKE 'MAIN_MODULE_%_JS' OR name LIKE 'MAIN_MODULE_%_HOOKS'";
347 $sql .=
" OR name LIKE 'MAIN_MODULE_%_TRIGGERS' OR name LIKE 'MAIN_MODULE_%_THEME' OR name LIKE 'MAIN_MODULE_%_SUBSTITUTIONS' OR name LIKE 'MAIN_MODULE_%_MODELS'";
348 $sql .=
" OR name LIKE 'MAIN_MODULE_%_MENUS' OR name LIKE 'MAIN_MODULE_%_LOGIN' OR name LIKE 'MAIN_MODULE_%_BARCODE' OR name LIKE 'MAIN_MODULE_%_TABS_%'";
349 $sql .=
" OR name LIKE 'MAIN_MODULE_%_MODULEFOREXTERNAL'";
350 $sql .=
" ORDER BY name, entity";
352 $resql = $db->query(
$sql);
354 $num = $db->num_rows($resql);
361 $obj = $db->fetch_object($resql);
364 if (preg_match(
'/MAIN_MODULE_([^_]+)_(.+)/i', $obj->name, $reg)) {
368 $sql2 =
"SELECT COUNT(*) as nb";
369 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
370 $sql2 .=
" WHERE name = 'MAIN_MODULE_".$name.
"'";
371 $sql2 .=
" AND entity = ".((int) $obj->entity);
372 $resql2 = $db->query($sql2);
374 $obj2 = $db->fetch_object($resql2);
375 if ($obj2 && $obj2->nb == 0) {
377 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = '".$db->escape($obj->name).
"' AND entity = ".((int) $obj->entity);
379 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
380 $db->query($sqldelete);
382 print
'<tr><td>Widget '.$obj->name.
' set in entity '.$obj->entity.
' with value '.$obj->value.
' -> Module '.$name.
' not enabled in entity '.((int) $obj->entity).
', we delete record</td></tr>';
384 print
'<tr><td>Widget '.$obj->name.
' set in entity '.$obj->entity.
' with value '.$obj->value.
' -> Module '.$name.
' not enabled in entity '.((int) $obj->entity).
', we should delete record (not done, mode test)</td></tr>';
404 if ($ok &&
GETPOST(
'standard',
'alpha')) {
405 print
'<tr><td colspan="2"><br>*** Clean definition of boxes of modules not enabled</td></tr>';
407 $sql =
"SELECT file, entity FROM ".MAIN_DB_PREFIX.
"boxes_def";
408 $sql .=
" WHERE file like '%@%'";
410 $resql = $db->query(
$sql);
412 $num = $db->num_rows($resql);
419 $obj = $db->fetch_object($resql);
422 if (preg_match(
'/^(.+)@(.+)$/i', $obj->file, $reg)) {
426 $sql2 =
"SELECT COUNT(*) as nb";
427 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
428 $sql2 .=
" WHERE name = 'MAIN_MODULE_".strtoupper($module).
"'";
429 $sql2 .=
" AND entity = ".((int) $obj->entity);
430 $sql2 .=
" AND value <> 0";
431 $resql2 = $db->query($sql2);
433 $obj2 = $db->fetch_object($resql2);
434 if ($obj2 && $obj2->nb == 0) {
436 $sqldeletea =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes WHERE entity = ".((int) $obj->entity).
" AND box_id IN (SELECT rowid FROM ".MAIN_DB_PREFIX.
"boxes_def WHERE file = '".$db->escape($obj->file).
"' AND entity = ".((int) $obj->entity).
")";
437 $sqldeleteb =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def WHERE file = '".$db->escape($obj->file).
"' AND entity = ".((int) $obj->entity);
439 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
440 $db->query($sqldeletea);
441 $db->query($sqldeleteb);
443 print
'<tr><td>Constant '.$obj->file.
' set in boxes_def for entity '.$obj->entity.
' but MAIN_MODULE_'.strtoupper($module).
' not defined in entity '.((int) $obj->entity).
', we delete record</td></tr>';
445 print
'<tr><td>Constant '.$obj->file.
' set in boxes_def for entity '.$obj->entity.
' but MAIN_MODULE_'.strtoupper($module).
' not defined in entity '.((int) $obj->entity).
', we should delete record (not done, mode test)</td></tr>';
463 if ($ok &&
GETPOST(
'restore_thirdparties_logos')) {
468 print
'<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
470 $sql =
"SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX.
"societe as s ORDER BY s.nom";
471 $resql = $db->query(
$sql);
473 $num = $db->num_rows($resql);
477 $obj = $db->fetch_object($resql);
485 $tmp = explode(
'.', $obj->logo);
487 if (isset($tmp[1])) {
492 $filetotest = $dolibarr_main_data_root.
'/societe/logos/'.$name.$ext;
493 $filetotestsmall = $dolibarr_main_data_root.
'/societe/logos/thumbs/'.$name.
'_small'.$ext;
495 print
'Check thirdparty '.$obj->rowid.
' name='.$obj->name.
' logo='.$obj->logo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
497 $filetarget = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/'.$name.$ext;
498 $filetargetsmall = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs/'.$name.
'_small'.$ext;
501 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
502 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos');
505 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
506 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
507 dol_copy($filetotest, $filetarget,
'', 0);
513 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
514 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs');
516 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
517 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
518 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
537 if ($ok &&
GETPOST(
'restore_user_pictures',
'alpha')) {
542 print
'<tr><td colspan="2"><br>*** Restore user pictures<br>';
544 $sql =
"SELECT s.rowid, s.firstname, s.lastname, s.login, s.photo FROM ".MAIN_DB_PREFIX.
"user as s ORDER BY s.rowid";
545 $resql = $db->query(
$sql);
547 $num = $db->num_rows($resql);
551 $obj = $db->fetch_object($resql);
559 $tmp = explode(
'.', $obj->photo);
561 if (isset($tmp[1])) {
566 $filetotest = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/'.$name.$ext;
567 $filetotestsmall = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_small'.$ext;
568 $filetotestmini = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_mini'.$ext;
570 print
'Check user '.$obj->rowid.
' lastname='.$obj->lastname.
' firstname='.$obj->firstname.
' photo='.$obj->photo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
572 $filetarget = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/'.$name.$ext;
573 $filetargetsmall = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_small'.$ext;
574 $filetargetmini = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_mini'.$ext;
578 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
579 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid);
582 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
583 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
584 dol_copy($filetotest, $filetarget,
'', 0);
590 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
591 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
594 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
595 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
596 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
602 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
603 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
606 print
" -> Copy file ".$filetotestmini.
" -> ".$filetargetmini.
"<br>\n";
607 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
608 dol_copy($filetotestmini, $filetargetmini,
'', 0);
626 if ($ok &&
GETPOST(
'rebuild_product_thumbs',
'alpha')) {
628 global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
630 print
'<tr><td colspan="2"><br>*** Rebuild product thumbs<br>';
632 $sql =
"SELECT s.rowid, s.ref FROM ".MAIN_DB_PREFIX.
"product as s ORDER BY s.ref";
633 $resql = $db->query(
$sql);
635 $num = $db->num_rows($resql);
639 $obj = $db->fetch_object($resql);
641 if (!empty($obj->ref)) {
642 $files =
dol_dir_list($dolibarr_main_data_root.
'/produit/'.$obj->ref,
'files', 0);
643 foreach ($files as $file) {
646 $imgThumbSmall =
'notbuild';
647 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
649 $imgThumbSmall =
vignette($file[
'fullname'], $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
651 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbSmall.
" maxwidthsmall=".$maxwidthsmall.
" maxheightsmall=".$maxheightsmall.
"<br>\n";
652 $imgThumbMini =
'notbuild';
653 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
656 $imgThumbMini =
vignette($file[
'fullname'], $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
658 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbMini.
" maxwidthmini=".$maxwidthmini.
" maxheightmini=".$maxheightmini.
"<br>\n";
674 if ($ok &&
GETPOST(
'clean_linked_elements',
'alpha')) {
675 print
'<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
677 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'commande').
"</td></tr>\n";
680 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'facture').
"</td></tr>\n";
683 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'facture').
"</td></tr>\n";
686 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'shipping').
"</td></tr>\n";
689 print
'<tr><td colspan="2">'.checkLinkedElements(
'shipping',
'delivery').
"</td></tr>\n";
692 print
'<tr><td colspan="2">'.checkLinkedElements(
'order_supplier',
'invoice_supplier').
"</td></tr>\n";
697 if ($ok &&
GETPOST(
'clean_menus',
'alpha')) {
698 print
'<tr><td colspan="2"><br>*** Clean menu entries coming from disabled modules</td></tr>';
700 $sql =
"SELECT rowid, module";
701 $sql .=
" FROM ".MAIN_DB_PREFIX.
"menu as c";
702 $sql .=
" WHERE module IS NOT NULL AND module <> ''";
703 $sql .=
" ORDER BY module";
705 $resql = $db->query(
$sql);
707 $num = $db->num_rows($resql);
711 $obj = $db->fetch_object($resql);
713 $modulecond = $obj->module;
714 $modulecondarray = explode(
'|', $obj->module);
723 foreach ($modulecondarray as $tmpname) {
724 if ($tmpname ==
'margins') {
729 if (!empty($conf->$tmpname)) {
730 $result = $conf->$tmpname->enabled;
737 if (!$moduleok && $modulecond) {
738 print
' - Module condition '.$modulecond.
' seems ko, we delete menu entry.';
739 if (
GETPOST(
'clean_menus') ==
'confirmed') {
740 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"menu WHERE module = '".$db->escape($modulecond).
"'";
741 $resql2 = $db->query($sql2);
746 print
' - <span class="warning">Cleaned</span>';
749 print
' - <span class="warning">Canceled (test mode)</span>';
752 print
' - Module condition '.$modulecond.
' is ok, we do nothing.';
771 print
'<tr><td>No menu entries of disabled menus found</td></tr>';
781 if ($ok &&
GETPOST(
'clean_orphelin_dir',
'alpha')) {
782 $listmodulepart = array(
'company',
'invoice',
'invoice_supplier',
'propal',
'order',
'order_supplier',
'contract',
'tax');
783 foreach ($listmodulepart as $modulepart) {
784 $filearray = array();
785 $upload_dir = isset($conf->$modulepart->dir_output) ? $conf->$modulepart->dir_output :
'';
786 if ($modulepart ==
'company') {
787 $upload_dir = $conf->societe->dir_output;
789 if ($modulepart ==
'invoice') {
790 $upload_dir = $conf->facture->dir_output;
792 if ($modulepart ==
'invoice_supplier') {
793 $upload_dir = $conf->fournisseur->facture->dir_output;
795 if ($modulepart ==
'order') {
796 $upload_dir = $conf->commande->dir_output;
798 if ($modulepart ==
'order_supplier') {
799 $upload_dir = $conf->fournisseur->commande->dir_output;
801 if ($modulepart ==
'contract') {
802 $upload_dir = $conf->contrat->dir_output;
805 if (empty($upload_dir)) {
809 print
'<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.
'</td></tr>';
811 $filearray =
dol_dir_list($upload_dir,
"files", 1,
'', array(
'^SPECIMEN\.pdf$',
'^\.',
'(\.meta|_preview.*\.png)$',
'^temp$',
'^payments$',
'^CVS$',
'^thumbs$'),
'', SORT_DESC, 1,
true);
814 if ($modulepart ==
'company') {
815 include_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
816 $object_instance =
new Societe($db);
818 if ($modulepart ==
'invoice') {
819 include_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
820 $object_instance =
new Facture($db);
821 } elseif ($modulepart ==
'invoice_supplier') {
822 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.facture.class.php';
824 } elseif ($modulepart ==
'propal') {
825 include_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
826 $object_instance =
new Propal($db);
827 } elseif ($modulepart ==
'order') {
828 include_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
829 $object_instance =
new Commande($db);
830 } elseif ($modulepart ==
'order_supplier') {
831 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
833 } elseif ($modulepart ==
'contract') {
834 include_once DOL_DOCUMENT_ROOT.
'/contrat/class/contrat.class.php';
835 $object_instance =
new Contrat($db);
836 } elseif ($modulepart ==
'tax') {
837 include_once DOL_DOCUMENT_ROOT.
'/compta/sociales/class/chargesociales.class.php';
841 foreach ($filearray as $key => $file) {
842 if (!is_dir($file[
'name'])
843 && $file[
'name'] !=
'.'
844 && $file[
'name'] !=
'..'
845 && $file[
'name'] !=
'CVS'
848 $relativefile = preg_replace(
'/'.preg_quote($upload_dir.
'/',
'/').
'/',
'', $file[
'fullname']);
851 $id = 0; $ref =
''; $object_instance->id = 0; $object_instance->ref =
''; $label =
'';
854 if ($modulepart ==
'invoice') {
855 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
857 if ($modulepart ==
'invoice_supplier') {
858 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg); $id = empty($reg[1]) ?
'' : $reg[1];
860 if ($modulepart ==
'propal') {
861 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
863 if ($modulepart ==
'order') {
864 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
866 if ($modulepart ==
'order_supplier') {
867 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
869 if ($modulepart ==
'contract') {
870 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
872 if ($modulepart ==
'tax') {
873 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg); $id = $reg[1];
878 $result = $object_instance->fetch($id, $ref);
882 print
'<tr><td colspan="2">';
883 print
'Delete orphelins file '.$file[
'fullname'].
'<br>';
884 if (
GETPOST(
'clean_orphelin_dir',
'alpha') ==
'confirmed') {
889 } elseif ($result < 0) {
890 print
'Error in '.get_class($object_instance).
'.fetch of id'.$id.
' ref='.$ref.
', result='.$result.
'<br>';
899 if ($ok &&
GETPOST(
'clean_product_stock_batch',
'alpha')) {
900 $methodtofix =
GETPOST(
'methodtofix',
'alpha') ?
GETPOST(
'methodtofix',
'alpha') :
'updatestock';
902 print
'<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
904 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
905 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product as p, ".MAIN_DB_PREFIX.
"product_stock as ps LEFT JOIN ".MAIN_DB_PREFIX.
"product_batch as pb ON ps.rowid = pb.fk_product_stock";
906 $sql .=
" WHERE p.rowid = ps.fk_product";
907 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
908 $sql .=
" HAVING (SUM(pb.qty) IS NOT NULL AND reel != SUM(pb.qty)) OR (SUM(pb.qty) IS NULL AND p.tobatch > 0)";
910 $resql = $db->query(
$sql);
912 $num = $db->num_rows($resql);
917 $obj = $db->fetch_object($resql);
918 print
'<tr><td>Product '.$obj->rowid.
'-'.$obj->ref.
' in warehouse id='.$obj->fk_entrepot.
' (product_stock.id='.$obj->psrowid.
'): '.$obj->reel.
' (Stock product_stock.reel) != '.($obj->reelbatch ? $obj->reelbatch :
'0').
' (Stock batch sum product_batch)';
921 if ($obj->reel != $obj->reelbatch) {
922 if (empty($obj->tobatch)) {
924 print
' -> Delete qty '.$obj->reelbatch.
' for any lot linked to fk_product_stock='.$obj->psrowid;
925 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_batch";
926 $sql2 .=
" WHERE fk_product_stock = ".((int) $obj->psrowid);
929 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
930 $resql2 = $db->query($sql2);
937 if ($methodtofix ==
'updatebatch') {
939 print
' -> Insert qty '.($obj->reel - $obj->reelbatch).
' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
940 $sql2 =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_batch(fk_product_stock, batch, qty)";
941 $sql2 .=
"VALUES(".((int) $obj->psrowid).
", '000000', ".((
float) ($obj->reel - $obj->reelbatch)).
")";
944 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
945 $resql2 = $db->query($sql2);
954 if ($methodtofix ==
'updatestock') {
956 print
' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((
float) $obj->reelbatch) :
'0').
' for ps.rowid = '.((
int) $obj->psrowid);
957 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"product_stock";
958 $sql2 .=
" SET reel = ".($obj->reelbatch ? ((
float) $obj->reelbatch) :
'0').
" WHERE rowid = ".((
int) $obj->psrowid);
961 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
966 $resql2 = $db->query($sql2);
969 $sql3 =
'UPDATE '.MAIN_DB_PREFIX.
'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.
'product_stock ps WHERE ps.fk_product = p.rowid)';
970 $resql3 = $db->query($sql3);
995 print
'<tr><td colspan="2">Nothing to do</td></tr>';
1004 if ($ok &&
GETPOST(
'clean_product_stock_negative_if_batch',
'alpha')) {
1005 print
'<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
1007 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
1008 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product as p, ".MAIN_DB_PREFIX.
"product_stock as ps, ".MAIN_DB_PREFIX.
"product_batch as pb";
1009 $sql .=
" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
1010 $sql .=
" AND p.tobatch > 0";
1011 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
1012 $sql .=
" HAVING reel != SUM(pb.qty)";
1013 $resql = $db->query(
$sql);
1015 $num = $db->num_rows($resql);
1020 $obj = $db->fetch_object($resql);
1021 print
'<tr><td>'.$obj->rowid.
'-'.$obj->ref.
'-'.$obj->fk_entrepot.
' -> '.$obj->psrowid.
': '.$obj->reel.
' != '.$obj->reelbatch;
1030 if ($ok &&
GETPOST(
'set_empty_time_spent_amount',
'alpha')) {
1031 print
'<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
1033 $sql =
"SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
1034 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"user as u";
1035 $sql .=
" WHERE ptt.fk_user = u.rowid";
1036 $sql .=
" AND ptt.thm IS NULL and u.thm > 0";
1037 $sql .=
" GROUP BY u.rowid, u.login, u.thm";
1039 $resql = $db->query(
$sql);
1041 $num = $db->num_rows($resql);
1046 $obj = $db->fetch_object($resql);
1047 print
'<tr><td>'.$obj->login.
'-'.$obj->user_id.
' ('.$obj->nb.
' lines to fix) -> '.$obj->user_thm;
1051 if (
GETPOST(
'set_empty_time_spent_amount') ==
'confirmed') {
1052 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"element_time";
1053 $sql2 .=
" SET thm = ".$obj->user_thm.
" WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id);
1054 $resql2 = $db->query($sql2);
1076 print
'<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
1085 if ($ok &&
GETPOST(
'force_disable_of_modules_not_found',
'alpha')) {
1086 print
'<tr><td colspan="2"><br>*** Force modules not found physicaly to be disabled (only modules adding js, css or hooks can be detected as removed physicaly)</td></tr>';
1088 $arraylistofkey = array(
'hooks',
'js',
'css');
1090 foreach ($arraylistofkey as $key) {
1091 $sql =
"SELECT DISTINCT name, value";
1092 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
1093 $sql .=
" WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($key).
"'";
1094 $sql .=
" ORDER BY name";
1096 $resql = $db->query(
$sql);
1098 $num = $db->num_rows($resql);
1102 $obj = $db->fetch_object($resql);
1103 $constantname = $obj->name;
1111 if (preg_match(
'/MAIN_MODULE_(.*)_'.strtoupper($key).
'/i', $constantname, $reg)) {
1112 $name = strtolower($reg[1]);
1118 if ($key ==
'hooks') {
1119 $reloffile = $name.
'/class/actions_'.$name.
'.class.php';
1122 $value = $obj->value;
1123 $valuearray = json_decode($value);
1124 $reloffile = $valuearray[0];
1125 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1127 if ($key ==
'css') {
1128 $value = $obj->value;
1129 $valuearray = json_decode($value);
1130 if ($value && (!is_array($valuearray) || count($valuearray) == 0)) {
1131 $valuearray = array();
1132 $valuearray[0] = $value;
1134 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1149 print
' - File of '.$key.
' ('.$reloffile.
') NOT found, we disable the module.';
1150 if (
GETPOST(
'force_disable_of_modules_not_found') ==
'confirmed') {
1151 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"_".strtoupper($key).
"'";
1152 $resql2 = $db->query($sql2);
1157 $sql3 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"'";
1158 $resql3 = $db->query($sql3);
1163 print
' - <span class="warning">Cleaned</span>';
1166 print
' - <span class="warning">Canceled (test mode)</span>';
1169 print
' - File of '.$key.
' ('.$reloffile.
') found, we do nothing.';
1189 print
'<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).
'</td></tr>';
1199 if ($ok &&
GETPOST(
'clean_perm_table',
'alpha')) {
1200 print
'<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1203 foreach ($conf->modules as $key => $val) {
1204 $listofmods .= ($listofmods ?
',' :
'').
"'".$db->escape($val).
"'";
1207 $sql =
"SELECT id, libelle as label, module from ".MAIN_DB_PREFIX.
"rights_def WHERE module NOT IN (".$db->sanitize($listofmods, 1).
") AND id > 100000";
1209 $resql = $db->query(
$sql);
1211 $num = $db->num_rows($resql);
1215 $obj = $db->fetch_object($resql);
1217 print
'<tr><td>Found line with id '.$obj->id.
', label "'.$obj->label.
'" of module "'.$obj->module.
'" to delete';
1218 if (
GETPOST(
'clean_perm_table',
'alpha') ==
'confirmed') {
1219 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def WHERE id = ".((int) $obj->id);
1220 $resqldelete = $db->query($sqldelete);
1221 if (!$resqldelete) {
1231 print
'<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1241 if ($ok &&
GETPOST(
'force_utf8_on_tables',
'alpha')) {
1242 print
'<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8/utf8_unicode_ci and row_format=dynamic (for mysql/mariadb only)</td></tr>';
1244 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1245 $force_utf8_on_tables =
GETPOST(
'force_utf8_on_tables',
'alpha');
1247 $listoftables = $db->DDLListTablesFull($db->database_name);
1250 if ($force_utf8_on_tables ==
'confirmed') {
1251 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1252 print
'<!-- '.$sql.
' -->';
1253 $resql = $db->query(
$sql);
1256 foreach ($listoftables as $table) {
1258 if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1261 if ($table[1] ==
'VIEW') {
1262 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' (Skipped)</td></tr>';
1266 print
'<tr><td colspan="2">';
1268 $sql1 =
"ALTER TABLE ".$table[0].
" ROW_FORMAT=dynamic";
1269 $sql2 =
"ALTER TABLE ".$table[0].
" CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci";
1270 print
'<!-- '.$sql1.
' -->';
1271 print
'<!-- '.$sql2.
' -->';
1272 if ($force_utf8_on_tables ==
'confirmed') {
1273 $resql1 = $db->query($sql1);
1275 $resql2 = $db->query($sql2);
1279 print
' - Done ('.(($resql1 && $resql2) ?
'OK' :
'KO').
')';
1281 print
' - Disabled';
1287 if ($force_utf8_on_tables ==
'confirmed') {
1288 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1289 print
'<!-- '.$sql.
' -->';
1290 $resql = $db->query(
$sql);
1293 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1298 if ($ok &&
GETPOST(
'force_utf8mb4_on_tables',
'alpha')) {
1299 print
'<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8mb4/utf8mb4_unicode_ci (for mysql/mariadb only)</td></tr>';
1301 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1302 $force_utf8mb4_on_tables =
GETPOST(
'force_utf8mb4_on_tables',
'alpha');
1304 $listoftables = $db->DDLListTablesFull($db->database_name);
1307 if ($force_utf8mb4_on_tables ==
'confirmed') {
1308 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1309 print
'<!-- '.$sql.
' -->';
1310 $resql = $db->query(
$sql);
1313 foreach ($listoftables as $table) {
1315 if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1318 if ($table[1] ==
'VIEW') {
1319 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' (Skipped)</td></tr>';
1323 print
'<tr><td colspan="2">';
1325 $sql1 =
"ALTER TABLE ".$table[0].
" ROW_FORMAT=dynamic";
1326 $sql2 =
"ALTER TABLE ".$table[0].
" CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
1327 print
'<!-- '.$sql1.
' -->';
1328 print
'<!-- '.$sql2.
' -->';
1329 if ($force_utf8mb4_on_tables ==
'confirmed') {
1330 $resql1 = $db->query($sql1);
1332 $resql2 = $db->query($sql2);
1336 print
' - Done ('.(($resql1 && $resql2) ?
'OK' :
'KO').
')';
1338 print
' - Disabled';
1346 if ($force_utf8mb4_on_tables ==
'confirmed') {
1347 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1348 print
'<!-- '.$sql.
' -->';
1349 $resql = $db->query(
$sql);
1352 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1357 if ($ok &&
GETPOST(
'rebuild_sequences',
'alpha')) {
1358 print
'<tr><td colspan="2"><br>*** Force to rebuild sequences (for postgresql only)</td></tr>';
1360 if ($db->type ==
"pgsql") {
1361 $rebuild_sequence =
GETPOST(
'rebuild_sequences',
'alpha');
1363 if ($rebuild_sequence ==
'confirmed') {
1364 $sql =
"SELECT dol_util_rebuild_sequences();";
1365 print
'<!-- '.$sql.
' -->';
1366 $resql = $db->query(
$sql);
1369 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1374 if ($ok &&
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines')) {
1398 $repair_link_dispatch_lines_supplier_order_lines =
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha');
1401 echo
'<tr><th>Repair llx_commande_fournisseur_dispatch.fk_commandefourndet</th></tr>';
1402 echo
'<tr><td>Repair in progress. This may take a while.</td></tr>';
1404 $sql_dispatch =
'SELECT * FROM '.MAIN_DB_PREFIX.
'commande_fournisseur_dispatch WHERE COALESCE(fk_commandefourndet, 0) = 0';
1406 $resql_dispatch = $db->query($sql_dispatch);
1407 $n_processed_rows = 0;
1409 if ($resql_dispatch) {
1410 if ($db->num_rows($resql_dispatch) == 0) {
1411 echo
'<tr><td>Nothing to do.</td></tr>';
1414 while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
1415 $sql_line =
'SELECT line.rowid, line.qty FROM '.MAIN_DB_PREFIX.
'commande_fournisseurdet AS line';
1416 $sql_line .=
' WHERE line.fk_commande = '.((int) $obj_dispatch->fk_commande);
1417 $sql_line .=
' AND line.fk_product = '.((int) $obj_dispatch->fk_product);
1418 $resql_line = $db->query($sql_line);
1424 $remaining_qty = $obj_dispatch->qty;
1425 $first_iteration =
true;
1427 echo
'<tr><td>Unable to find a matching supplier order line for dispatch #'.$obj_dispatch->rowid.
'</td></tr>';
1428 $errors[] = $sql_line;
1429 $n_processed_rows++;
1432 if ($db->num_rows($resql_line) == 0) {
1435 while ($obj_line = $db->fetch_object($resql_line)) {
1436 if (!$remaining_qty) {
1439 if (!$obj_line->rowid) {
1442 $qty_for_line = min($remaining_qty, $obj_line->qty);
1443 if ($first_iteration) {
1444 $sql_attach =
'UPDATE '.MAIN_DB_PREFIX.
'commande_fournisseur_dispatch';
1445 $sql_attach .=
' SET fk_commandefourndet = '.((int) $obj_line->rowid).
', qty = '.((
float) $qty_for_line);
1446 $sql_attach .=
' WHERE rowid = '.((int) $obj_dispatch->rowid);
1447 $first_iteration =
false;
1449 $sql_attach_values = array(
1450 ((
int) $obj_dispatch->fk_commande),
1451 ((
int) $obj_dispatch->fk_product),
1452 ((
int) $obj_line->rowid),
1453 ((
float) $qty_for_line),
1454 ((
int) $obj_dispatch->fk_entrepot),
1455 ((
int) $obj_dispatch->fk_user),
1456 $obj_dispatch->datec ?
"'".$db->idate($db->jdate($obj_dispatch->datec)).
"'" :
'NULL',
1457 $obj_dispatch->comment ?
"'".$db->escape($obj_dispatch->comment).
"'" :
'NULL',
1458 $obj_dispatch->status ? ((
int) $obj_dispatch->status) :
'NULL',
1459 $obj_dispatch->tms ?
"'".$db->idate($db->jdate($obj_dispatch->tms)).
"'" :
'NULL',
1460 $obj_dispatch->batch ?
"'".$db->escape($obj_dispatch->batch).
"'" :
'NULL',
1461 $obj_dispatch->eatby ?
"'".$db->escape($obj_dispatch->eatby).
"'" :
'NULL',
1462 $obj_dispatch->sellby ?
"'".$db->escape($obj_dispatch->sellby).
"'" :
'NULL'
1464 $sql_attach_values = join(
', ', $sql_attach_values);
1466 $sql_attach =
'INSERT INTO '.MAIN_DB_PREFIX.
'commande_fournisseur_dispatch';
1467 $sql_attach .=
' (fk_commande, fk_product, fk_commandefourndet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)';
1468 $sql_attach .=
" VALUES (".$sql_attach_values.
")";
1471 if ($repair_link_dispatch_lines_supplier_order_lines ==
'confirmed') {
1472 $resql_attach = $db->query($sql_attach);
1474 $resql_attach =
true;
1477 if ($resql_attach) {
1478 $remaining_qty -= $qty_for_line;
1480 $errors[] = $sql_attach;
1483 $first_iteration =
false;
1485 $n_processed_rows++;
1488 if (!($n_processed_rows & 0xff)) {
1489 echo
'<tr><td>Processed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1495 echo
'<tr><td>Unable to find any dispatch without an fk_commandefourndet.'.
"</td></tr>\n";
1496 echo $sql_dispatch.
"\n";
1498 echo
'<tr><td>Fixed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1499 echo
'<tr><td>DONE.'.
"</td></tr>\n";
1501 if (count($errors)) {
1503 echo
'<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
1509 echo
'<tr><td><h3>SQL queries with errors:</h3></tr></td>';
1510 echo
'<tr><td>'.join(
'</td></tr><tr><td>', $errors).
'</td></tr>';
1514 if ($ok &&
GETPOST(
'repair_supplier_order_duplicate_ref')) {
1515 require_once DOL_DOCUMENT_ROOT .
'/fourn/class/fournisseur.commande.class.php';
1516 include_once DOL_DOCUMENT_ROOT .
'/societe/class/societe.class.php';
1523 $sql =
"SELECT * FROM " . MAIN_DB_PREFIX .
"commande_fournisseur";
1524 $sql .=
" WHERE ref IN (SELECT cf.ref FROM " . MAIN_DB_PREFIX .
"commande_fournisseur cf GROUP BY cf.ref, cf.entity HAVING COUNT(cf.rowid) > 1)";
1527 $duplicateSupplierOrders = [];
1528 $resql = $db->query(
$sql);
1530 while ($rawSupplierOrder = $db->fetch_object($resql)) {
1532 $supplierOrder->setVarsFromFetchObj($rawSupplierOrder);
1534 $duplicateSupplierOrders[$rawSupplierOrder->ref] [] = $supplierOrder;
1541 foreach ($duplicateSupplierOrders as $ref => $supplierOrders) {
1543 foreach (array_slice($supplierOrders, 1) as $supplierOrder) {
1546 $soc->fetch($supplierOrder->fourn_id);
1548 $newRef = $supplierOrder->getNextNumRef($soc);
1550 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"commande_fournisseur cf SET cf.ref = '" . $db->escape($newRef) .
"' WHERE cf.rowid = " . (int) $supplierOrder->id;
1568 if (empty($actiondone)) {
1569 print
'<div class="error">'.$langs->trans(
"ErrorWrongParameters").
'</div>';
1572 if ($oneoptionset) {
1573 print
'<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(GETPOSTISSET(
"login") ?
'&username='.urlencode(
GETPOST(
"login")) :
'').
'">';
1574 print $langs->trans(
"GoToDolibarr");
1577 print
'<div class="center warning" style="padding-top: 10px">';
1578 print $langs->trans(
"SetAtLeastOneOptionAsUrlParameter");
1585 if ($db->connected) {
1590 if (!$ok && isset($argv[1])) {
run_sql($sqlfile, $silent=1, $entity=0, $usesavepoint=1, $handler='', $okerror='default', $linelengthlimit=32768, $nocommentremoval=0, $offsetforchartofaccount=0, $colspan=0, $onlysqltoimportwebsite=0, $database='')
Launch a sql file.
Classe permettant la gestion des paiements des charges La tva collectee n'est calculee que sur les fa...
Class to manage predefined suppliers products.
Class to manage customers orders.
Class to manage contracts.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
dol_is_file($pathoffile)
Return if path is a file.
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=0)
Copy a file to another file.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
getDoliDBInstance($type, $host, $user, $pass, $name, $port)
Return a DoliDB instance (database handler).
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
vignette($file, $maxWidth=160, $maxHeight=120, $extName='_small', $quality=50, $outdir='thumbs', $targetformat=0)
Create a thumbnail from an image file (Supported extensions are gif, jpg, png and bmp).
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
pHeader($subtitle, $next, $action='set', $param='', $forcejqueryurl='', $csstable='main-inside')
Show HTML header of install pages.
pFooter($nonext=0, $setuplang='', $jscheckfunction='', $withpleasewait=0, $morehtml='')
Print HTML footer of install pages.
dolibarr_install_syslog($message, $level=LOG_DEBUG)
Log function for install pages.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
div float
Buy price without taxes.
clean_data_ecm_directories()
Clean data into ecm_directories table.
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.