27 include_once
'inc.php';
28 if (file_exists($conffile)) {
29 include_once $conffile;
31 require_once $dolibarr_main_document_root.
'/core/lib/admin.lib.php';
32 include_once $dolibarr_main_document_root.
'/core/lib/images.lib.php';
33 require_once $dolibarr_main_document_root.
'/core/class/extrafields.class.php';
34 require_once
'lib/repair.lib.php';
42 $err = error_reporting();
45 error_reporting($err);
47 $setuplang =
GETPOST(
"selectlang",
'aZ09', 3) ?
GETPOST(
"selectlang",
'aZ09', 3) :
'auto';
48 $langs->setDefaultLang($setuplang);
50 $langs->loadLangs(array(
"admin",
"install",
"other"));
52 if ($dolibarr_main_db_type ==
"mysqli") {
55 if ($dolibarr_main_db_type ==
"pgsql") {
58 if ($dolibarr_main_db_type ==
"mssql") {
64 if (!is_object($conf)) {
78 print
'<h3>'.$langs->trans(
"Repair").
'</h3>';
80 print
'Option standard (\'test\' or \'confirmed\') is '.(GETPOST(
'standard',
'alpha') ?
GETPOST(
'standard',
'alpha') :
'undefined').
'<br>'.
"\n";
82 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";
84 print
'Option restore_thirdparties_logos (\'test\' or \'confirmed\') is '.(GETPOST(
'restore_thirdparties_logos',
'alpha') ?
GETPOST(
'restore_thirdparties_logos',
'alpha') :
'undefined').
'<br>'.
"\n";
85 print
'Option restore_user_pictures (\'test\' or \'confirmed\') is '.(GETPOST(
'restore_user_pictures',
'alpha') ?
GETPOST(
'restore_user_pictures',
'alpha') :
'undefined').
'<br>'.
"\n";
86 print
'Option rebuild_product_thumbs (\'test\' or \'confirmed\') is '.(GETPOST(
'rebuild_product_thumbs',
'alpha') ?
GETPOST(
'rebuild_product_thumbs',
'alpha') :
'undefined').
'<br>'.
"\n";
88 print
'Option clean_linked_elements (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_linked_elements',
'alpha') ?
GETPOST(
'clean_linked_elements',
'alpha') :
'undefined').
'<br>'.
"\n";
89 print
'Option clean_menus (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_menus',
'alpha') ?
GETPOST(
'clean_menus',
'alpha') :
'undefined').
'<br>'.
"\n";
90 print
'Option clean_orphelin_dir (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_orphelin_dir',
'alpha') ?
GETPOST(
'clean_orphelin_dir',
'alpha') :
'undefined').
'<br>'.
"\n";
91 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";
92 print
'Option clean_perm_table (\'test\' or \'confirmed\') is '.(GETPOST(
'clean_perm_table',
'alpha') ?
GETPOST(
'clean_perm_table',
'alpha') :
'undefined').
'<br>'.
"\n";
93 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";
95 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";
97 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";
98 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";
100 print
'Option rebuild_sequences, for postgresql only (\'test\' or \'confirmed\') is '.(GETPOST(
'rebuild_sequences',
'alpha') ?
GETPOST(
'rebuild_sequences',
'alpha') :
'undefined').
'<br>'.
"\n";
103 print
'<table cellspacing="0" cellpadding="1" border="0" width="100%">';
107 if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass) || !empty($dolibarr_main_db_encrypted_pass)) {
108 require_once $dolibarr_main_document_root.
'/core/lib/security.lib.php';
109 if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass)) {
110 $dolibarr_main_db_pass = preg_replace(
'/crypted:/i',
'', $dolibarr_main_db_pass);
111 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_pass);
112 $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass;
114 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_encrypted_pass);
119 $conf->db->type = $dolibarr_main_db_type;
120 $conf->db->host = $dolibarr_main_db_host;
121 $conf->db->port = $dolibarr_main_db_port;
122 $conf->db->name = $dolibarr_main_db_name;
123 $conf->db->user = $dolibarr_main_db_user;
124 $conf->db->pass = $dolibarr_main_db_pass;
127 $conf->db->dolibarr_main_db_encryption = isset($dolibarr_main_db_encryption) ? $dolibarr_main_db_encryption :
'';
128 $conf->db->dolibarr_main_db_cryptkey = isset($dolibarr_main_db_cryptkey) ? $dolibarr_main_db_cryptkey :
'';
130 $db =
getDoliDBInstance($conf->db->type, $conf->db->host, $conf->db->user, $conf->db->pass, $conf->db->name, $conf->db->port);
132 if ($db->connected) {
133 print
'<tr><td class="nowrap">';
134 print $langs->trans(
"ServerConnection").
" : $dolibarr_main_db_host</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
135 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ServerConnection").
": ".$dolibarr_main_db_host.$langs->transnoentities(
"OK"));
138 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->transnoentities(
"Error").
"</td></tr>";
139 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
144 if ($db->database_selected) {
145 print
'<tr><td class="nowrap">';
146 print $langs->trans(
"DatabaseConnection").
" : ".$dolibarr_main_db_name.
"</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
150 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->trans(
"Error").
"</td></tr>";
151 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
158 $version = $db->getVersion();
159 $versionarray = $db->getVersionArray();
160 print
'<tr><td>'.$langs->trans(
"ServerVersion").
'</td>';
161 print
'<td class="right">'.$version.
'</td></tr>';
166 $conf->setValues($db);
168 if (defined(
'SYSLOG_FILE')) {
169 $conf->global->SYSLOG_FILE = constant(
'SYSLOG_FILE');
171 $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
176 $oneoptionset = (
GETPOST(
'standard',
'alpha') ||
GETPOST(
'restore_thirdparties_logos',
'alpha') ||
GETPOST(
'clean_linked_elements',
'alpha') ||
GETPOST(
'clean_menus',
'alpha')
177 ||
GETPOST(
'clean_orphelin_dir',
'alpha') ||
GETPOST(
'clean_product_stock_batch',
'alpha') ||
GETPOST(
'set_empty_time_spent_amount',
'alpha') ||
GETPOST(
'rebuild_product_thumbs',
'alpha')
178 ||
GETPOST(
'clean_perm_table',
'alpha')
179 ||
GETPOST(
'force_disable_of_modules_not_found',
'alpha')
180 ||
GETPOST(
'force_utf8_on_tables',
'alpha') ||
GETPOST(
'force_utf8mb4_on_tables',
'alpha')
181 ||
GETPOST(
'rebuild_sequences',
'alpha'));
183 if ($ok && $oneoptionset) {
185 print
'<tr><td colspan="2">'.$langs->trans(
"PleaseBePatient").
'<br><br></td></tr>';
191 if ($ok &&
GETPOST(
'standard',
'alpha')) {
192 $dir =
"mysql/migration/";
199 $filesindir = array();
200 $handle = opendir($dir);
201 if (is_resource($handle)) {
202 while (($file = readdir($handle)) !==
false) {
203 if (preg_match(
'/\.sql$/i', $file)) {
204 $filesindir[] = $file;
210 foreach ($filesindir as $file) {
211 if (preg_match(
'/repair/i', $file)) {
217 foreach ($filelist as $file) {
218 print
'<tr><td class="nowrap">*** ';
219 print $langs->trans(
"Script").
'</td><td class="right">'.$file.
'</td></tr>';
221 $name = substr($file, 0,
dol_strlen($file) - 4);
224 $ok =
run_sql($dir.$file, 0,
'', 1);
231 if ($ok &&
GETPOST(
'standard',
'alpha')) {
233 $listofmodulesextra = array(
'societe'=>
'societe',
'adherent'=>
'adherent',
'product'=>
'product',
234 'socpeople'=>
'socpeople',
'propal'=>
'propal',
'commande'=>
'commande',
'facture'=>
'facture',
235 'supplier_proposal'=>
'supplier_proposal',
'commande_fournisseur'=>
'commande_fournisseur',
'facture_fourn'=>
'facture_fourn',
236 'actioncomm'=>
'actioncomm',
'bom_bom'=>
'bom_bom',
'mrp_mo'=>
'mrp_mo',
237 'adherent_type'=>
'adherent_type',
'user'=>
'user',
'projet'=>
'projet',
'projet_task'=>
'projet_task');
238 print
'<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
239 foreach ($listofmodulesextra as $tablename => $elementtype) {
241 $tableextra = MAIN_DB_PREFIX.$tablename.
'_extrafields';
244 $arrayoffieldsdesc = $extrafields->fetch_name_optionals_label($elementtype);
247 $arrayoffieldsfound = array();
248 $resql = $db->DDLDescTable($tableextra);
250 print
'<tr><td>Check availability of extra field for '.$tableextra.
"<br>\n";
252 while ($obj = $db->fetch_object(
$resql)) {
253 $fieldname = $fieldtype =
'';
254 if (preg_match(
'/mysql/', $db->type)) {
255 $fieldname = $obj->Field;
256 $fieldtype = $obj->Type;
258 $fieldname = isset($obj->Key) ? $obj->Key : $obj->attname;
259 $fieldtype = isset($obj->Type) ? $obj->Type :
'varchar';
262 if (empty($fieldname)) {
265 if (in_array($fieldname, array(
'rowid',
'tms',
'fk_object',
'import_key'))) {
268 $arrayoffieldsfound[$fieldname] = array(
'type'=>$fieldtype);
272 foreach ($arrayoffieldsdesc as $code => $label) {
273 if (!in_array($code, array_keys($arrayoffieldsfound))) {
274 print
'Found field '.$code.
' declared into '.MAIN_DB_PREFIX.
'extrafields table but not found into desc of table '.$tableextra.
" -> ";
275 $type = $extrafields->attributes[$elementtype][
'type'][$code]; $length = $extrafields->attributes[$elementtype][
'size'][$code]; $attribute =
''; $default =
''; $extra =
''; $null =
'null';
277 if ($type ==
'boolean') {
280 } elseif ($type ==
'price') {
283 } elseif ($type ==
'phone') {
286 } elseif ($type ==
'mail') {
289 } elseif (($type ==
'select') || ($type ==
'sellist') || ($type ==
'radio') || ($type ==
'checkbox') || ($type ==
'chkbxlst')) {
292 } elseif ($type ==
'link') {
303 'attribute'=>$attribute,
311 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
312 $result = $db->DDLAddField($tableextra, $code, $field_desc,
"");
315 print
"KO ".$db->lasterror.
"<br>\n";
320 print
' - Mode test, no column added.';
325 print
"</td><td> </td></tr>\n";
334 if ($ok &&
GETPOST(
'standard',
'alpha')) {
340 if ($ok &&
GETPOST(
'standard',
'alpha')) {
341 print
'<tr><td colspan="2"><br>*** Clean constant record of modules not enabled</td></tr>';
343 $sql =
"SELECT name, entity, value";
344 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
345 $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'";
346 $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'";
347 $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_%'";
348 $sql .=
" OR name LIKE 'MAIN_MODULE_%_MODULEFOREXTERNAL'";
349 $sql .=
" ORDER BY name, entity";
351 $resql = $db->query($sql);
353 $num = $db->num_rows(
$resql);
360 $obj = $db->fetch_object(
$resql);
363 if (preg_match(
'/MAIN_MODULE_([^_]+)_(.+)/i', $obj->name, $reg)) {
367 $sql2 =
"SELECT COUNT(*) as nb";
368 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
369 $sql2 .=
" WHERE name = 'MAIN_MODULE_".$name.
"'";
370 $sql2 .=
" AND entity = ".((int) $obj->entity);
371 $resql2 = $db->query($sql2);
373 $obj2 = $db->fetch_object($resql2);
374 if ($obj2 && $obj2->nb == 0) {
376 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = '".$db->escape($obj->name).
"' AND entity = ".((int) $obj->entity);
378 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
379 $db->query($sqldelete);
381 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>';
383 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>';
403 if ($ok &&
GETPOST(
'standard',
'alpha')) {
404 print
'<tr><td colspan="2"><br>*** Clean definition of boxes of modules not enabled</td></tr>';
406 $sql =
"SELECT file, entity FROM ".MAIN_DB_PREFIX.
"boxes_def";
407 $sql .=
" WHERE file like '%@%'";
409 $resql = $db->query($sql);
411 $num = $db->num_rows(
$resql);
418 $obj = $db->fetch_object(
$resql);
421 if (preg_match(
'/^(.+)@(.+)$/i', $obj->file, $reg)) {
425 $sql2 =
"SELECT COUNT(*) as nb";
426 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
427 $sql2 .=
" WHERE name = 'MAIN_MODULE_".strtoupper($module).
"'";
428 $sql2 .=
" AND entity = ".((int) $obj->entity);
429 $sql2 .=
" AND value <> 0";
430 $resql2 = $db->query($sql2);
432 $obj2 = $db->fetch_object($resql2);
433 if ($obj2 && $obj2->nb == 0) {
435 $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).
")";
436 $sqldeleteb =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def WHERE file = '".$db->escape($obj->file).
"' AND entity = ".((int) $obj->entity);
438 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
439 $db->query($sqldeletea);
440 $db->query($sqldeleteb);
442 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>';
444 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>';
462 if ($ok &&
GETPOST(
'restore_thirdparties_logos')) {
467 print
'<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
469 $sql =
"SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX.
"societe as s ORDER BY s.nom";
470 $resql = $db->query($sql);
472 $num = $db->num_rows(
$resql);
476 $obj = $db->fetch_object(
$resql);
484 $tmp = explode(
'.', $obj->logo);
486 if (isset($tmp[1])) {
491 $filetotest = $dolibarr_main_data_root.
'/societe/logos/'.$name.$ext;
492 $filetotestsmall = $dolibarr_main_data_root.
'/societe/logos/thumbs/'.$name.
'_small'.$ext;
494 print
'Check thirdparty '.$obj->rowid.
' name='.$obj->name.
' logo='.$obj->logo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
496 $filetarget = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/'.$name.$ext;
497 $filetargetsmall = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs/'.$name.
'_small'.$ext;
500 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
501 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos');
504 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
505 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
506 dol_copy($filetotest, $filetarget,
'', 0);
512 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
513 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs');
515 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
516 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
517 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
536 if ($ok &&
GETPOST(
'restore_user_pictures',
'alpha')) {
541 print
'<tr><td colspan="2"><br>*** Restore user pictures<br>';
543 $sql =
"SELECT s.rowid, s.firstname, s.lastname, s.login, s.photo FROM ".MAIN_DB_PREFIX.
"user as s ORDER BY s.rowid";
544 $resql = $db->query($sql);
546 $num = $db->num_rows(
$resql);
550 $obj = $db->fetch_object(
$resql);
558 $tmp = explode(
'.', $obj->photo);
560 if (isset($tmp[1])) {
565 $filetotest = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/'.$name.$ext;
566 $filetotestsmall = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_small'.$ext;
567 $filetotestmini = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_mini'.$ext;
569 print
'Check user '.$obj->rowid.
' lastname='.$obj->lastname.
' firstname='.$obj->firstname.
' photo='.$obj->photo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
571 $filetarget = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/'.$name.$ext;
572 $filetargetsmall = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_small'.$ext;
573 $filetargetmini = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_mini'.$ext;
577 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
578 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid);
581 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
582 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
583 dol_copy($filetotest, $filetarget,
'', 0);
589 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
590 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
593 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
594 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
595 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
601 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
602 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
605 print
" -> Copy file ".$filetotestmini.
" -> ".$filetargetmini.
"<br>\n";
606 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
607 dol_copy($filetotestmini, $filetargetmini,
'', 0);
625 if ($ok &&
GETPOST(
'rebuild_product_thumbs',
'alpha')) {
627 global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
629 print
'<tr><td colspan="2"><br>*** Rebuild product thumbs<br>';
631 $sql =
"SELECT s.rowid, s.ref FROM ".MAIN_DB_PREFIX.
"product as s ORDER BY s.ref";
632 $resql = $db->query($sql);
634 $num = $db->num_rows(
$resql);
638 $obj = $db->fetch_object(
$resql);
640 if (!empty($obj->ref)) {
641 $files =
dol_dir_list($dolibarr_main_data_root.
'/produit/'.$obj->ref,
'files', 0);
642 foreach ($files as $file) {
645 $imgThumbSmall =
'notbuild';
646 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
648 $imgThumbSmall =
vignette($file[
'fullname'], $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
650 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbSmall.
" maxwidthsmall=".$maxwidthsmall.
" maxheightsmall=".$maxheightsmall.
"<br>\n";
651 $imgThumbMini =
'notbuild';
652 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
655 $imgThumbMini =
vignette($file[
'fullname'], $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
657 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbMini.
" maxwidthmini=".$maxwidthmini.
" maxheightmini=".$maxheightmini.
"<br>\n";
673 if ($ok &&
GETPOST(
'clean_linked_elements',
'alpha')) {
674 print
'<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
676 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'commande').
"</td></tr>\n";
679 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'facture').
"</td></tr>\n";
682 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'facture').
"</td></tr>\n";
685 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'shipping').
"</td></tr>\n";
688 print
'<tr><td colspan="2">'.checkLinkedElements(
'shipping',
'delivery').
"</td></tr>\n";
691 print
'<tr><td colspan="2">'.checkLinkedElements(
'order_supplier',
'invoice_supplier').
"</td></tr>\n";
696 if ($ok &&
GETPOST(
'clean_menus',
'alpha')) {
697 print
'<tr><td colspan="2"><br>*** Clean menu entries coming from disabled modules</td></tr>';
699 $sql =
"SELECT rowid, module";
700 $sql .=
" FROM ".MAIN_DB_PREFIX.
"menu as c";
701 $sql .=
" WHERE module IS NOT NULL AND module <> ''";
702 $sql .=
" ORDER BY module";
704 $resql = $db->query($sql);
706 $num = $db->num_rows(
$resql);
710 $obj = $db->fetch_object(
$resql);
712 $modulecond = $obj->module;
713 $modulecondarray = explode(
'|', $obj->module);
722 foreach ($modulecondarray as $tmpname) {
723 if ($tmpname ==
'margins') {
728 if (!empty($conf->$tmpname)) {
729 $result = $conf->$tmpname->enabled;
736 if (!$moduleok && $modulecond) {
737 print
' - Module condition '.$modulecond.
' seems ko, we delete menu entry.';
738 if (
GETPOST(
'clean_menus') ==
'confirmed') {
739 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"menu WHERE module = '".$db->escape($modulecond).
"'";
740 $resql2 = $db->query($sql2);
745 print
' - <span class="warning">Cleaned</span>';
748 print
' - <span class="warning">Canceled (test mode)</span>';
751 print
' - Module condition '.$modulecond.
' is ok, we do nothing.';
770 print
'<tr><td>No menu entries of disabled menus found</td></tr>';
780 if ($ok &&
GETPOST(
'clean_orphelin_dir',
'alpha')) {
781 $listmodulepart = array(
'company',
'invoice',
'invoice_supplier',
'propal',
'order',
'order_supplier',
'contract',
'tax');
782 foreach ($listmodulepart as $modulepart) {
783 $filearray = array();
784 $upload_dir = isset($conf->$modulepart->dir_output) ? $conf->$modulepart->dir_output :
'';
785 if ($modulepart ==
'company') {
786 $upload_dir = $conf->societe->dir_output;
788 if ($modulepart ==
'invoice') {
789 $upload_dir = $conf->facture->dir_output;
791 if ($modulepart ==
'invoice_supplier') {
792 $upload_dir = $conf->fournisseur->facture->dir_output;
794 if ($modulepart ==
'order') {
795 $upload_dir = $conf->commande->dir_output;
797 if ($modulepart ==
'order_supplier') {
798 $upload_dir = $conf->fournisseur->commande->dir_output;
800 if ($modulepart ==
'contract') {
801 $upload_dir = $conf->contrat->dir_output;
804 if (empty($upload_dir)) {
808 print
'<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.
'</td></tr>';
810 $filearray =
dol_dir_list($upload_dir,
"files", 1,
'', array(
'^SPECIMEN\.pdf$',
'^\.',
'(\.meta|_preview.*\.png)$',
'^temp$',
'^payments$',
'^CVS$',
'^thumbs$'),
'', SORT_DESC, 1,
true);
813 if ($modulepart ==
'company') {
814 include_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
815 $object_instance =
new Societe($db);
817 if ($modulepart ==
'invoice') {
818 include_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
819 $object_instance =
new Facture($db);
820 } elseif ($modulepart ==
'invoice_supplier') {
821 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.facture.class.php';
823 } elseif ($modulepart ==
'propal') {
824 include_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
825 $object_instance =
new Propal($db);
826 } elseif ($modulepart ==
'order') {
827 include_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
828 $object_instance =
new Commande($db);
829 } elseif ($modulepart ==
'order_supplier') {
830 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
832 } elseif ($modulepart ==
'contract') {
833 include_once DOL_DOCUMENT_ROOT.
'/contrat/class/contrat.class.php';
834 $object_instance =
new Contrat($db);
835 } elseif ($modulepart ==
'tax') {
836 include_once DOL_DOCUMENT_ROOT.
'/compta/sociales/class/chargesociales.class.php';
840 foreach ($filearray as $key => $file) {
841 if (!is_dir($file[
'name'])
842 && $file[
'name'] !=
'.'
843 && $file[
'name'] !=
'..'
844 && $file[
'name'] !=
'CVS'
847 $relativefile = preg_replace(
'/'.preg_quote($upload_dir.
'/',
'/').
'/',
'', $file[
'fullname']);
850 $id = 0; $ref =
''; $object_instance->id = 0; $object_instance->ref =
''; $label =
'';
853 if ($modulepart ==
'invoice') {
854 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
856 if ($modulepart ==
'invoice_supplier') {
857 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg); $id = empty($reg[1]) ?
'' : $reg[1];
859 if ($modulepart ==
'propal') {
860 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
862 if ($modulepart ==
'order') {
863 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
865 if ($modulepart ==
'order_supplier') {
866 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
868 if ($modulepart ==
'contract') {
869 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
871 if ($modulepart ==
'tax') {
872 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg); $id = $reg[1];
877 $result = $object_instance->fetch($id, $ref);
881 print
'<tr><td colspan="2">';
882 print
'Delete orphelins file '.$file[
'fullname'].
'<br>';
883 if (
GETPOST(
'clean_orphelin_dir',
'alpha') ==
'confirmed') {
888 } elseif ($result < 0) {
889 print
'Error in '.get_class($object_instance).
'.fetch of id'.$id.
' ref='.$ref.
', result='.$result.
'<br>';
898 if ($ok &&
GETPOST(
'clean_product_stock_batch',
'alpha')) {
899 $methodtofix =
GETPOST(
'methodtofix',
'alpha') ?
GETPOST(
'methodtofix',
'alpha') :
'updatestock';
901 print
'<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
903 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
904 $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";
905 $sql .=
" WHERE p.rowid = ps.fk_product";
906 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
907 $sql .=
" HAVING (SUM(pb.qty) IS NOT NULL AND reel != SUM(pb.qty)) OR (SUM(pb.qty) IS NULL AND p.tobatch > 0)";
909 $resql = $db->query($sql);
911 $num = $db->num_rows(
$resql);
916 $obj = $db->fetch_object(
$resql);
917 print
'<tr><td>Product '.$obj->rowid.
'-'.$obj->ref.
' in warehouse id='.$obj->fk_entrepot.
' -> product_stock.id='.$obj->psrowid.
': '.$obj->reel.
' (product_stock.reel) != '.($obj->reelbatch ? $obj->reelbatch :
'0').
' (sum product_batch)';
920 if ($obj->reel != $obj->reelbatch) {
921 if (empty($obj->tobatch)) {
923 print
' -> Delete qty '.$obj->reelbatch.
' for any lot linked to fk_product_stock='.$obj->psrowid;
924 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_batch";
925 $sql2 .=
" WHERE fk_product_stock = ".((int) $obj->psrowid);
928 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
929 $resql2 = $db->query($sql2);
936 if ($methodtofix ==
'updatebatch') {
938 print
' -> Insert qty '.($obj->reel - $obj->reelbatch).
' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
939 $sql2 =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_batch(fk_product_stock, batch, qty)";
940 $sql2 .=
"VALUES(".((int) $obj->psrowid).
", '000000', ".((
float) ($obj->reel - $obj->reelbatch)).
")";
943 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
944 $resql2 = $db->query($sql2);
953 if ($methodtofix ==
'updatestock') {
955 print
' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((
float) $obj->reelbatch) :
'0').
' for ps.rowid = '.((
int) $obj->psrowid);
956 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"product_stock";
957 $sql2 .=
" SET reel = ".($obj->reelbatch ? ((
float) $obj->reelbatch) :
'0').
" WHERE rowid = ".((
int) $obj->psrowid);
960 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
965 $resql2 = $db->query($sql2);
968 $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)';
969 $resql3 = $db->query($sql3);
994 print
'<tr><td colspan="2">Nothing to do</td></tr>';
1003 if ($ok &&
GETPOST(
'clean_product_stock_negative_if_batch',
'alpha')) {
1004 print
'<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
1006 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
1007 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product as p, ".MAIN_DB_PREFIX.
"product_stock as ps, ".MAIN_DB_PREFIX.
"product_batch as pb";
1008 $sql .=
" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
1009 $sql .=
" AND p.tobatch > 0";
1010 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
1011 $sql .=
" HAVING reel != SUM(pb.qty)";
1012 $resql = $db->query($sql);
1014 $num = $db->num_rows(
$resql);
1019 $obj = $db->fetch_object(
$resql);
1020 print
'<tr><td>'.$obj->rowid.
'-'.$obj->ref.
'-'.$obj->fk_entrepot.
' -> '.$obj->psrowid.
': '.$obj->reel.
' != '.$obj->reelbatch;
1029 if ($ok &&
GETPOST(
'set_empty_time_spent_amount',
'alpha')) {
1030 print
'<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
1032 $sql =
"SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
1033 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time as ptt, ".MAIN_DB_PREFIX.
"user as u";
1034 $sql .=
" WHERE ptt.fk_user = u.rowid";
1035 $sql .=
" AND ptt.thm IS NULL and u.thm > 0";
1036 $sql .=
" GROUP BY u.rowid, u.login, u.thm";
1038 $resql = $db->query($sql);
1040 $num = $db->num_rows(
$resql);
1045 $obj = $db->fetch_object(
$resql);
1046 print
'<tr><td>'.$obj->login.
'-'.$obj->user_id.
' ('.$obj->nb.
' lines to fix) -> '.$obj->user_thm;
1050 if (
GETPOST(
'set_empty_time_spent_amount') ==
'confirmed') {
1051 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task_time";
1052 $sql2 .=
" SET thm = ".$obj->user_thm.
" WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id);
1053 $resql2 = $db->query($sql2);
1075 print
'<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
1084 if ($ok &&
GETPOST(
'force_disable_of_modules_not_found',
'alpha')) {
1085 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>';
1087 $arraylistofkey = array(
'hooks',
'js',
'css');
1089 foreach ($arraylistofkey as $key) {
1090 $sql =
"SELECT DISTINCT name, value";
1091 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
1092 $sql .=
" WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($key).
"'";
1093 $sql .=
" ORDER BY name";
1095 $resql = $db->query($sql);
1097 $num = $db->num_rows(
$resql);
1101 $obj = $db->fetch_object(
$resql);
1102 $constantname = $obj->name;
1110 if (preg_match(
'/MAIN_MODULE_(.*)_'.strtoupper($key).
'/i', $constantname, $reg)) {
1111 $name = strtolower($reg[1]);
1117 if ($key ==
'hooks') {
1118 $reloffile = $name.
'/class/actions_'.$name.
'.class.php';
1121 $value = $obj->value;
1122 $valuearray = json_decode($value);
1123 $reloffile = $valuearray[0];
1124 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1126 if ($key ==
'css') {
1127 $value = $obj->value;
1128 $valuearray = json_decode($value);
1129 if ($value && (!is_array($valuearray) || count($valuearray) == 0)) {
1130 $valuearray = array();
1131 $valuearray[0] = $value;
1133 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1148 print
' - File of '.$key.
' ('.$reloffile.
') NOT found, we disable the module.';
1149 if (
GETPOST(
'force_disable_of_modules_not_found') ==
'confirmed') {
1150 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"_".strtoupper($key).
"'";
1151 $resql2 = $db->query($sql2);
1156 $sql3 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"'";
1157 $resql3 = $db->query($sql3);
1162 print
' - <span class="warning">Cleaned</span>';
1165 print
' - <span class="warning">Canceled (test mode)</span>';
1168 print
' - File of '.$key.
' ('.$reloffile.
') found, we do nothing.';
1188 print
'<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).
'</td></tr>';
1198 if ($ok &&
GETPOST(
'clean_perm_table',
'alpha')) {
1199 print
'<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1202 foreach ($conf->modules as $key => $val) {
1203 $listofmods .= ($listofmods ?
',' :
'').
"'".$db->escape($val).
"'";
1206 $sql =
"SELECT id, libelle as label, module from ".MAIN_DB_PREFIX.
"rights_def WHERE module NOT IN (".$db->sanitize($listofmods, 1).
") AND id > 100000";
1208 $resql = $db->query($sql);
1210 $num = $db->num_rows(
$resql);
1214 $obj = $db->fetch_object(
$resql);
1216 print
'<tr><td>Found line with id '.$obj->id.
', label "'.$obj->label.
'" of module "'.$obj->module.
'" to delete';
1217 if (
GETPOST(
'clean_perm_table',
'alpha') ==
'confirmed') {
1218 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def WHERE id = ".((int) $obj->id);
1219 $resqldelete = $db->query($sqldelete);
1220 if (!$resqldelete) {
1230 print
'<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1240 if ($ok &&
GETPOST(
'force_utf8_on_tables',
'alpha')) {
1241 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>';
1243 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1244 $force_utf8_on_tables =
GETPOST(
'force_utf8_on_tables',
'alpha');
1246 $listoftables = $db->DDLListTables($db->database_name);
1249 if ($force_utf8_on_tables ==
'confirmed') {
1250 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1251 print
'<!-- '.$sql.
' -->';
1252 $resql = $db->query($sql);
1255 foreach ($listoftables as $table) {
1257 if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table)) {
1261 print
'<tr><td colspan="2">';
1263 $sql1 =
"ALTER TABLE ".$table.
" ROW_FORMAT=dynamic";
1264 $sql2 =
"ALTER TABLE ".$table.
" CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci";
1265 print
'<!-- '.$sql1.
' -->';
1266 print
'<!-- '.$sql2.
' -->';
1267 if ($force_utf8_on_tables ==
'confirmed') {
1268 $resql1 = $db->query($sql1);
1270 $resql2 = $db->query($sql2);
1274 print
' - Done ('.(($resql1 && $resql2) ?
'OK' :
'KO').
')';
1276 print
' - Disabled';
1282 if ($force_utf8_on_tables ==
'confirmed') {
1283 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1284 print
'<!-- '.$sql.
' -->';
1285 $resql = $db->query($sql);
1288 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1293 if ($ok &&
GETPOST(
'force_utf8mb4_on_tables',
'alpha')) {
1294 print
'<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8mb4/utf8mb4_unicode_ci (for mysql/mariadb only)</td></tr>';
1296 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1297 $force_utf8mb4_on_tables =
GETPOST(
'force_utf8mb4_on_tables',
'alpha');
1299 $listoftables = $db->DDLListTables($db->database_name);
1302 if ($force_utf8mb4_on_tables ==
'confirmed') {
1303 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1304 print
'<!-- '.$sql.
' -->';
1305 $resql = $db->query($sql);
1308 foreach ($listoftables as $table) {
1310 if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table)) {
1314 print
'<tr><td colspan="2">';
1316 $sql1 =
"ALTER TABLE ".$table.
" ROW_FORMAT=dynamic";
1317 $sql2 =
"ALTER TABLE ".$table.
" CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
1318 print
'<!-- '.$sql1.
' -->';
1319 print
'<!-- '.$sql2.
' -->';
1320 if ($force_utf8mb4_on_tables ==
'confirmed') {
1321 $resql1 = $db->query($sql1);
1323 $resql2 = $db->query($sql2);
1327 print
' - Done ('.(($resql1 && $resql2) ?
'OK' :
'KO').
')';
1329 print
' - Disabled';
1337 if ($force_utf8mb4_on_tables ==
'confirmed') {
1338 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1339 print
'<!-- '.$sql.
' -->';
1340 $resql = $db->query($sql);
1343 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1348 if ($ok &&
GETPOST(
'rebuild_sequences',
'alpha')) {
1349 print
'<tr><td colspan="2"><br>*** Force to rebuild sequences (for postgresql only)</td></tr>';
1351 if ($db->type ==
"pgsql") {
1352 $rebuild_sequence =
GETPOST(
'rebuild_sequences',
'alpha');
1354 if ($rebuild_sequence ==
'confirmed') {
1355 $sql =
"SELECT dol_util_rebuild_sequences();";
1356 print
'<!-- '.$sql.
' -->';
1357 $resql = $db->query($sql);
1360 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1365 if ($ok &&
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines')) {
1389 $repair_link_dispatch_lines_supplier_order_lines =
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha');
1392 echo
'<tr><th>Repair llx_commande_fournisseur_dispatch.fk_commandefourndet</th></tr>';
1393 echo
'<tr><td>Repair in progress. This may take a while.</td></tr>';
1395 $sql_dispatch =
'SELECT * FROM '.MAIN_DB_PREFIX.
'commande_fournisseur_dispatch WHERE COALESCE(fk_commandefourndet, 0) = 0';
1397 $resql_dispatch = $db->query($sql_dispatch);
1398 $n_processed_rows = 0;
1400 if ($resql_dispatch) {
1401 if ($db->num_rows($resql_dispatch) == 0) {
1402 echo
'<tr><td>Nothing to do.</td></tr>';
1405 while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
1406 $sql_line =
'SELECT line.rowid, line.qty FROM '.MAIN_DB_PREFIX.
'commande_fournisseurdet AS line';
1407 $sql_line .=
' WHERE line.fk_commande = '.((int) $obj_dispatch->fk_commande);
1408 $sql_line .=
' AND line.fk_product = '.((int) $obj_dispatch->fk_product);
1409 $resql_line = $db->query($sql_line);
1415 $remaining_qty = $obj_dispatch->qty;
1416 $first_iteration =
true;
1418 echo
'<tr><td>Unable to find a matching supplier order line for dispatch #'.$obj_dispatch->rowid.
'</td></tr>';
1419 $errors[] = $sql_line;
1420 $n_processed_rows++;
1423 if ($db->num_rows($resql_line) == 0) {
1426 while ($obj_line = $db->fetch_object($resql_line)) {
1427 if (!$remaining_qty) {
1430 if (!$obj_line->rowid) {
1433 $qty_for_line = min($remaining_qty, $obj_line->qty);
1434 if ($first_iteration) {
1435 $sql_attach =
'UPDATE '.MAIN_DB_PREFIX.
'commande_fournisseur_dispatch';
1436 $sql_attach .=
' SET fk_commandefourndet = '.((int) $obj_line->rowid).
', qty = '.((
float) $qty_for_line);
1437 $sql_attach .=
' WHERE rowid = '.((int) $obj_dispatch->rowid);
1438 $first_iteration =
false;
1440 $sql_attach_values = array(
1441 ((
int) $obj_dispatch->fk_commande),
1442 ((
int) $obj_dispatch->fk_product),
1443 ((
int) $obj_line->rowid),
1444 ((
float) $qty_for_line),
1445 ((
int) $obj_dispatch->fk_entrepot),
1446 ((
int) $obj_dispatch->fk_user),
1447 $obj_dispatch->datec ?
"'".$db->idate($db->jdate($obj_dispatch->datec)).
"'" :
'NULL',
1448 $obj_dispatch->comment ?
"'".$db->escape($obj_dispatch->comment).
"'" :
'NULL',
1449 $obj_dispatch->status ? ((
int) $obj_dispatch->status) :
'NULL',
1450 $obj_dispatch->tms ?
"'".$db->idate($db->jdate($obj_dispatch->tms)).
"'" :
'NULL',
1451 $obj_dispatch->batch ?
"'".$db->escape($obj_dispatch->batch).
"'" :
'NULL',
1452 $obj_dispatch->eatby ?
"'".$db->escape($obj_dispatch->eatby).
"'" :
'NULL',
1453 $obj_dispatch->sellby ?
"'".$db->escape($obj_dispatch->sellby).
"'" :
'NULL'
1455 $sql_attach_values = join(
', ', $sql_attach_values);
1457 $sql_attach =
'INSERT INTO '.MAIN_DB_PREFIX.
'commande_fournisseur_dispatch';
1458 $sql_attach .=
' (fk_commande, fk_product, fk_commandefourndet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)';
1459 $sql_attach .=
" VALUES (".$sql_attach_values.
")";
1462 if ($repair_link_dispatch_lines_supplier_order_lines ==
'confirmed') {
1463 $resql_attach = $db->query($sql_attach);
1465 $resql_attach =
true;
1468 if ($resql_attach) {
1469 $remaining_qty -= $qty_for_line;
1471 $errors[] = $sql_attach;
1474 $first_iteration =
false;
1476 $n_processed_rows++;
1479 if (!($n_processed_rows & 0xff)) {
1480 echo
'<tr><td>Processed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1486 echo
'<tr><td>Unable to find any dispatch without an fk_commandefourndet.'.
"</td></tr>\n";
1487 echo $sql_dispatch.
"\n";
1489 echo
'<tr><td>Fixed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1490 echo
'<tr><td>DONE.'.
"</td></tr>\n";
1492 if (count($errors)) {
1494 echo
'<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
1500 echo
'<tr><td><h3>SQL queries with errors:</h3></tr></td>';
1501 echo
'<tr><td>'.join(
'</td></tr><tr><td>', $errors).
'</td></tr>';
1508 if (empty($actiondone)) {
1509 print
'<div class="error">'.$langs->trans(
"ErrorWrongParameters").
'</div>';
1512 if ($oneoptionset) {
1513 print
'<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(GETPOSTISSET(
"login") ?
'&username='.urlencode(
GETPOST(
"login")) :
'').
'">';
1514 print $langs->trans(
"GoToDolibarr");
1517 print
'<div class="center warning" style="padding-top: 10px">';
1518 print $langs->trans(
"SetAtLeastOneOptionAsUrlParameter");
1525 if ($db->connected) {
1530 if (!$ok && isset($argv[1])) {