Issues (2811)

public/htdocs/install/upgrade2.php (2 issues)

Code
1
<?php
2
3
/* Copyright (C) 2005       Marc Barilley / Ocebo   <[email protected]>
4
 * Copyright (C) 2005-2018  Laurent Destailleur     <[email protected]>
5
 * Copyright (C) 2005-2011  Regis Houssin           <[email protected]>
6
 * Copyright (C) 2010       Juanjo Menent           <[email protected]>
7
 * Copyright (C) 2015-2016  Raphaël Doursenaud      <[email protected]>
8
 * Copyright (C) 2023      	Gauthier VERDOL       	<[email protected]>
9
 * Copyright (C) 2024		MDW							<[email protected]>
10
 * Copyright (C) 2024       Rafael San José             <[email protected]>
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24
 *
25
 * Upgrade2 scripts can be ran from command line with syntax:
26
 *
27
 * cd htdocs/install
28
 * php upgrade.php 3.4.0 3.5.0 [dirmodule|ignoredbversion]
29
 * php upgrade2.php 3.4.0 3.5.0 [MAIN_MODULE_NAME1_TO_ENABLE,MAIN_MODULE_NAME2_TO_ENABLE]
30
 *
31
 * And for final step:
32
 * php step5.php 3.4.0 3.5.0
33
 *
34
 * Return code is 0 if OK, >0 if error
35
 *
36
 * Note: To just enable a module from command line, use this syntax:
37
 * php upgrade2.php 0.0.0 0.0.0 [MAIN_MODULE_NAME1_TO_ENABLE,MAIN_MODULE_NAME2_TO_ENABLE]
38
 */
39
40
use Dolibarr\Code\BloquedLog\Classes\BlockedLog;
41
use Dolibarr\Core\Model\Constant;
42
use Dolibarr\Lib\Version;
43
44
/**
45
 *  \file       htdocs/install/upgrade2.php
46
 *  \brief      Upgrade some data
47
 */
48
49
define('ALLOWED_IF_UPGRADE_UNLOCK_FOUND', 1);
50
include_once constant('DOL_DOCUMENT_ROOT') . '/install/inc.php';
51
if (!file_exists($conffile)) {
52
    print 'Error: Dolibarr config file was not found. This may means that Dolibarr is not installed yet. Please call the page "/install/index.php" instead of "/install/upgrade.php").';
53
}
54
require_once $conffile;
55
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/price.lib.php';
56
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
57
58
global $langs;
59
60
$grant_query = '';
61
$step = 2;
62
$error = 0;
63
64
65
// Cette page peut etre longue. On augmente le delai autorise.
66
// Ne fonctionne que si on est pas en safe_mode.
67
$err = error_reporting();
68
error_reporting(0);
69
if (getDolGlobalString('MAIN_OVERRIDE_TIME_LIMIT')) {
70
    @set_time_limit((int)$conf->global->MAIN_OVERRIDE_TIME_LIMIT);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for set_time_limit(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

70
    /** @scrutinizer ignore-unhandled */ @set_time_limit((int)$conf->global->MAIN_OVERRIDE_TIME_LIMIT);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
71
} else {
72
    @set_time_limit(600);
73
}
74
error_reporting($err);
75
76
$setuplang = GETPOST("selectlang", 'aZ09', 3) ? GETPOST("selectlang", 'aZ09', 3) : 'auto';
77
$langs->setDefaultLang($setuplang);
78
$versionfrom = GETPOST("versionfrom", 'alpha', 3) ? GETPOST("versionfrom", 'alpha', 3) : (empty($argv[1]) ? '' : $argv[1]);
79
$versionto = GETPOST("versionto", 'alpha', 3) ? GETPOST("versionto", 'alpha', 3) : (empty($argv[2]) ? '' : $argv[2]);
80
$enablemodules = GETPOST("enablemodules", 'alpha', 3) ? GETPOST("enablemodules", 'alpha', 3) : (empty($argv[3]) ? '' : $argv[3]);
81
82
$langs->loadLangs(array("admin", "install", "bills", "suppliers"));
83
84
if ($dolibarr_main_db_type == 'mysqli') {
85
    $choix = 1;
86
}
87
if ($dolibarr_main_db_type == 'pgsql') {
88
    $choix = 2;
89
}
90
if ($dolibarr_main_db_type == 'mssql') {
91
    $choix = 3;
92
}
93
94
95
dolibarr_install_syslog("--- upgrade2: entering upgrade2.php page " . $versionfrom . " " . $versionto . " " . $enablemodules);
96
if (!is_object($conf)) {
97
    dolibarr_install_syslog("upgrade2: conf file not initialized", LOG_ERR);
98
}
99
100
101
/*
102
 * View
103
 */
104
105
if ((!$versionfrom || preg_match('/version/', $versionfrom)) && (!$versionto || preg_match('/version/', $versionto))) {
106
    print 'Error: Parameter versionfrom or versionto missing or having a bad format.' . "\n";
107
    print 'Upgrade must be ran from command line with parameters or called from page install/index.php (like a first install)' . "\n";
108
    // Test if batch mode
109
    $sapi_type = php_sapi_name();
110
    $script_file = basename(__FILE__);
111
    $path = __DIR__ . '/';
112
    if (substr($sapi_type, 0, 3) == 'cli') {
113
        print 'Syntax from command line: ' . $script_file . " x.y.z a.b.c [MAIN_MODULE_NAME1_TO_ENABLE,MAIN_MODULE_NAME2_TO_ENABLE...]\n";
114
    }
115
    exit;
116
}
117
118
pHeader('', 'step5', GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'upgrade', 'versionfrom=' . $versionfrom . '&versionto=' . $versionto, '', 'main-inside main-inside-borderbottom');
119
120
121
if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ09'))) {
122
    print '<h3><img class="valignmiddle inline-block paddingright" src="' . constant('DOL_URL_ROOT') . '/theme/common/octicons/build/svg/database.svg" width="20" alt="Database"> ';
123
    print '<span class="inline-block">' . $langs->trans('DataMigration') . '</span></h3>';
124
125
    print '<table border="0" width="100%">';
126
127
    // If password is encoded, we decode it
128
    if ((!empty($dolibarr_main_db_pass) && preg_match('/crypted:/i', $dolibarr_main_db_pass)) || !empty($dolibarr_main_db_encrypted_pass)) {
129
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/security.lib.php';
130
        if (!empty($dolibarr_main_db_pass) && preg_match('/crypted:/i', $dolibarr_main_db_pass)) {
131
            $dolibarr_main_db_pass = preg_replace('/crypted:/i', '', $dolibarr_main_db_pass);
132
            $dolibarr_main_db_pass = dol_decode($dolibarr_main_db_pass);
133
            $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass; // We need to set this as it is used to know the password was initially encrypted
134
        } else {
135
            $dolibarr_main_db_pass = dol_decode($dolibarr_main_db_encrypted_pass);
136
        }
137
    }
138
139
    // $conf is already instantiated inside inc.php
140
    $conf->db->type = $dolibarr_main_db_type;
141
    $conf->db->host = $dolibarr_main_db_host;
142
    $conf->db->port = $dolibarr_main_db_port;
143
    $conf->db->name = $dolibarr_main_db_name;
144
    $conf->db->user = $dolibarr_main_db_user;
145
    $conf->db->pass = $dolibarr_main_db_pass;
146
147
    $db = getDoliDBInstance($conf->db->type, $conf->db->host, $conf->db->user, $conf->db->pass, $conf->db->name, (int)$conf->db->port);
148
149
    if (!$db->connected) {
150
        print '<tr><td colspan="4">' . $langs->trans("ErrorFailedToConnectToDatabase", $conf->db->name) . '</td><td class="right">' . $langs->trans('Error') . '</td></tr>';
151
        dolibarr_install_syslog('upgrade2: failed to connect to database :' . $conf->db->name . ' on ' . $conf->db->host . ' for user ' . $conf->db->user, LOG_ERR);
152
        $error++;
153
    }
154
155
    if (!$error) {
156
        if ($db->database_selected) {
157
            dolibarr_install_syslog('upgrade2: database connection successful :' . $dolibarr_main_db_name);
158
        } else {
159
            $error++;
160
        }
161
    }
162
163
    if (empty($dolibarr_main_db_encryption)) {
164
        $dolibarr_main_db_encryption = 0;
165
    }
166
    $conf->db->dolibarr_main_db_encryption = $dolibarr_main_db_encryption;
167
    if (empty($dolibarr_main_db_cryptkey)) {
168
        $dolibarr_main_db_cryptkey = '';
169
    }
170
    $conf->db->dolibarr_main_db_cryptkey = $dolibarr_main_db_cryptkey;
171
172
    // Load global conf
173
    $conf->setValues($db);
174
175
176
    $listofentities = array(1);
177
178
    // Create the global $hookmanager object
179
    $hookmanager = new HookManager($db);
180
    $hookmanager->initHooks(array('upgrade2'));
181
182
    $parameters = array('versionfrom' => $versionfrom, 'versionto' => $versionto);
183
    $object = new stdClass();
184
    $action = "upgrade";
185
    $reshook = $hookmanager->executeHooks('doUpgradeBefore', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
186
    if ($reshook >= 0 && is_array($hookmanager->resArray)) {
187
        // Example: $hookmanager->resArray = array(2, 3, 10);
188
        $listofentities = array_unique(array_merge($listofentities, $hookmanager->resArray));
189
    }
190
191
192
    /***************************************************************************************
193
     *
194
     * Migration of data
195
     *
196
     ***************************************************************************************/
197
198
    // Force to execute this at begin to avoid the new core code into Dolibarr to be broken.
199
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'user ADD COLUMN birth date';
200
    $db->query($sql, 1);
201
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'user ADD COLUMN dateemployment date';
202
    $db->query($sql, 1);
203
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'user ADD COLUMN dateemploymentend date';
204
    $db->query($sql, 1);
205
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'user ADD COLUMN default_range integer';
206
    $db->query($sql, 1);
207
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'user ADD COLUMN default_c_exp_tax_cat integer';
208
    $db->query($sql, 1);
209
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'extrafields ADD COLUMN langs varchar(24)';
210
    $db->query($sql, 1);
211
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'extrafields ADD COLUMN fieldcomputed text';
212
    $db->query($sql, 1);
213
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'extrafields ADD COLUMN fielddefault varchar(255)';
214
    $db->query($sql, 1);
215
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . "extrafields ADD COLUMN enabled varchar(255) DEFAULT '1'";
216
    $db->query($sql, 1);
217
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'extrafields ADD COLUMN help text';
218
    $db->query($sql, 1);
219
    $sql = 'ALTER TABLE ' . MAIN_DB_PREFIX . 'user_rights ADD COLUMN entity integer DEFAULT 1 NOT NULL';
220
    $db->query($sql, 1);
221
222
223
    $db->begin();
224
225
    foreach ($listofentities as $entity) {
226
        // Set $conf context for entity
227
        $conf->setEntityValues($db, $entity);
228
        // Reset forced setup after the setValues
229
        if (defined('SYSLOG_FILE')) {
230
            $conf->global->SYSLOG_FILE = constant('SYSLOG_FILE');
231
        }
232
        $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
233
234
        if (!$error) {
235
            if (count($listofentities) > 1) {
236
                print '<tr><td colspan="4">*** ' . $langs->trans("Entity") . ' ' . $entity . '</td></tr>' . "\n";
237
            }
238
239
            // Current version is $conf->global->MAIN_VERSION_LAST_UPGRADE
240
            // Version to install is DOL_VERSION
241
            $dolibarrlastupgradeversionarray = preg_split('/[\.-]/', isset($conf->global->MAIN_VERSION_LAST_UPGRADE) ? $conf->global->MAIN_VERSION_LAST_UPGRADE : (isset($conf->global->MAIN_VERSION_LAST_INSTALL) ? $conf->global->MAIN_VERSION_LAST_INSTALL : ''));
242
243
            // Chaque action de migration doit renvoyer une ligne sur 4 colonnes avec
244
            // dans la 1ere colonne, la description de l'action a faire
245
            // dans la 4eme colonne, le texte 'OK' si fait ou 'AlreadyDone' si rien n'est fait ou 'Error'
246
247
            $versiontoarray = explode('.', $versionto);
248
            $versionranarray = explode('.', DOL_VERSION);
249
250
251
            $afterversionarray = explode('.', '2.0.0');
252
            $beforeversionarray = explode('.', '2.7.9');
253
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
254
                // Script pour V2 -> V2.1
255
                migrate_paiements($db, $langs, $conf);
256
257
                migrate_contracts_det($db, $langs, $conf);
258
259
                migrate_contracts_date1($db, $langs, $conf);
260
261
                migrate_contracts_date2($db, $langs, $conf);
262
263
                migrate_contracts_date3($db, $langs, $conf);
264
265
                migrate_contracts_open($db, $langs, $conf);
266
267
                migrate_modeles($db, $langs, $conf);
268
269
                migrate_price_propal($db, $langs, $conf);
270
271
                migrate_price_commande($db, $langs, $conf);
272
273
                migrate_price_commande_fournisseur($db, $langs, $conf);
274
275
                migrate_price_contrat($db, $langs, $conf);
276
277
                migrate_paiementfourn_facturefourn($db, $langs, $conf);
278
279
280
                // Script pour V2.1 -> V2.2
281
                migrate_paiements_orphelins_1($db, $langs, $conf);
282
283
                migrate_paiements_orphelins_2($db, $langs, $conf);
284
285
                migrate_links_transfert($db, $langs, $conf);
286
287
288
                // Script pour V2.2 -> V2.4
289
                migrate_commande_expedition($db, $langs, $conf);
290
291
                migrate_commande_livraison($db, $langs, $conf);
292
293
                migrate_detail_livraison($db, $langs, $conf);
294
295
296
                // Script pour V2.5 -> V2.6
297
                migrate_stocks($db, $langs, $conf);
298
299
300
                // Script pour V2.6 -> V2.7
301
                migrate_menus($db, $langs, $conf);
302
303
                migrate_commande_deliveryaddress($db, $langs, $conf);
304
305
                migrate_restore_missing_links($db, $langs, $conf);
306
307
                migrate_rename_directories($db, $langs, $conf, '/compta', '/banque');
308
309
                migrate_rename_directories($db, $langs, $conf, '/societe', '/mycompany');
310
            }
311
312
            // Script for 2.8
313
            $afterversionarray = explode('.', '2.7.9');
314
            $beforeversionarray = explode('.', '2.8.9');
315
            //print $versionto.' '.Version::compare($versiontoarray,$afterversionarray).' '.Version::compare($versiontoarray,$beforeversionarray);
316
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
317
                migrate_price_facture($db, $langs, $conf); // Code of this function works for 2.8+ because need a field tva_tx
318
319
                migrate_relationship_tables($db, $langs, $conf, 'co_exp', 'fk_commande', 'commande', 'fk_expedition', 'shipping');
320
321
                migrate_relationship_tables($db, $langs, $conf, 'pr_exp', 'fk_propal', 'propal', 'fk_expedition', 'shipping');
322
323
                migrate_relationship_tables($db, $langs, $conf, 'pr_liv', 'fk_propal', 'propal', 'fk_livraison', 'delivery');
324
325
                migrate_relationship_tables($db, $langs, $conf, 'co_liv', 'fk_commande', 'commande', 'fk_livraison', 'delivery');
326
327
                migrate_relationship_tables($db, $langs, $conf, 'co_pr', 'fk_propale', 'propal', 'fk_commande', 'commande');
328
329
                migrate_relationship_tables($db, $langs, $conf, 'fa_pr', 'fk_propal', 'propal', 'fk_facture', 'facture');
330
331
                migrate_relationship_tables($db, $langs, $conf, 'co_fa', 'fk_commande', 'commande', 'fk_facture', 'facture');
332
333
                migrate_project_user_resp($db, $langs, $conf);
334
335
                migrate_project_task_actors($db, $langs, $conf);
336
            }
337
338
            // Script for 2.9
339
            $afterversionarray = explode('.', '2.8.9');
340
            $beforeversionarray = explode('.', '2.9.9');
341
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
342
                migrate_element_time($db, $langs, $conf);
343
344
                migrate_customerorder_shipping($db, $langs, $conf);
345
346
                migrate_shipping_delivery($db, $langs, $conf);
347
348
                migrate_shipping_delivery2($db, $langs, $conf);
349
            }
350
351
            // Script for 3.0
352
            $afterversionarray = explode('.', '2.9.9');
353
            $beforeversionarray = explode('.', '3.0.9');
354
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
355
                // No particular code
356
            }
357
358
            // Script for 3.1
359
            $afterversionarray = explode('.', '3.0.9');
360
            $beforeversionarray = explode('.', '3.1.9');
361
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
362
                migrate_rename_directories($db, $langs, $conf, '/rss', '/externalrss');
363
364
                migrate_actioncomm_element($db, $langs, $conf);
365
            }
366
367
            // Script for 3.2
368
            $afterversionarray = explode('.', '3.1.9');
369
            $beforeversionarray = explode('.', '3.2.9');
370
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
371
                migrate_price_contrat($db, $langs, $conf);
372
373
                migrate_mode_reglement($db, $langs, $conf);
374
375
                migrate_clean_association($db, $langs, $conf);
376
            }
377
378
            // Script for 3.3
379
            $afterversionarray = explode('.', '3.2.9');
380
            $beforeversionarray = explode('.', '3.3.9');
381
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
382
                migrate_categorie_association($db, $langs, $conf);
383
            }
384
385
            // Script for 3.4
386
            // No specific scripts
387
388
            // Tasks to do always and only into last targeted version
389
            $afterversionarray = explode('.', '3.6.9'); // target is after this
390
            $beforeversionarray = explode('.', '3.7.9'); // target is before this
391
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
392
                migrate_event_assignement($db, $langs, $conf);
393
            }
394
395
            // Scripts for 3.9
396
            $afterversionarray = explode('.', '3.7.9');
397
            $beforeversionarray = explode('.', '3.8.9');
398
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
399
                // No particular code
400
            }
401
402
            // Scripts for 4.0
403
            $afterversionarray = explode('.', '3.9.9');
404
            $beforeversionarray = explode('.', '4.0.9');
405
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
406
                migrate_rename_directories($db, $langs, $conf, '/fckeditor', '/medias');
407
            }
408
409
            // Scripts for 5.0
410
            $afterversionarray = explode('.', '4.0.9');
411
            $beforeversionarray = explode('.', '5.0.9');
412
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
413
                // Migrate to add entity value into llx_societe_remise
414
                migrate_remise_entity($db, $langs, $conf);
415
416
                // Migrate to add entity value into llx_societe_remise_except
417
                migrate_remise_except_entity($db, $langs, $conf);
418
            }
419
420
            // Scripts for 6.0
421
            $afterversionarray = explode('.', '5.0.9');
422
            $beforeversionarray = explode('.', '6.0.9');
423
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
424
                if (isModEnabled('multicompany')) {
425
                    global $multicompany_transverse_mode;
426
427
                    // Only if the transverse mode is not used
428
                    if (empty($multicompany_transverse_mode)) {
429
                        // Migrate to add entity value into llx_user_rights
430
                        migrate_user_rights_entity($db, $langs, $conf);
431
432
                        // Migrate to add entity value into llx_usergroup_rights
433
                        migrate_usergroup_rights_entity($db, $langs, $conf);
434
                    }
435
                }
436
            }
437
438
            // Scripts for 7.0
439
            $afterversionarray = explode('.', '6.0.9');
440
            $beforeversionarray = explode('.', '7.0.9');
441
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
442
                // Migrate contact association
443
                migrate_event_assignement_contact($db, $langs, $conf);
444
445
                migrate_reset_blocked_log($db, $langs, $conf);
446
            }
447
448
            // Scripts for 8.0
449
            $afterversionarray = explode('.', '7.0.9');
450
            $beforeversionarray = explode('.', '8.0.9');
451
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
452
                migrate_rename_directories($db, $langs, $conf, '/contracts', '/contract');
453
            }
454
455
            // Scripts for 9.0
456
            $afterversionarray = explode('.', '8.0.9');
457
            $beforeversionarray = explode('.', '9.0.9');
458
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
459
                //migrate_user_photospath();
460
            }
461
462
            // Scripts for 11.0
463
            $afterversionarray = explode('.', '10.0.9');
464
            $beforeversionarray = explode('.', '11.0.9');
465
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
466
                migrate_users_socialnetworks();
467
                migrate_members_socialnetworks();
468
                migrate_contacts_socialnetworks();
469
                migrate_thirdparties_socialnetworks();
470
            }
471
472
            // Scripts for 14.0
473
            $afterversionarray = explode('.', '13.0.9');
474
            $beforeversionarray = explode('.', '14.0.9');
475
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
476
                migrate_export_import_profiles('export');
477
                migrate_export_import_profiles('import');
478
            }
479
480
            // Scripts for 16.0
481
            $afterversionarray = explode('.', '15.0.9');
482
            $beforeversionarray = explode('.', '16.0.9');
483
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
484
                migrate_user_photospath();
485
                migrate_user_photospath2();
486
            }
487
488
            // Scripts for 17.0
489
            $afterversionarray = explode('.', '16.0.9');
490
            $beforeversionarray = explode('.', '17.0.9');
491
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
492
                migrate_contractdet_rank();
493
            }
494
495
            // Scripts for 18.0
496
            $afterversionarray = explode('.', '17.0.9');
497
            $beforeversionarray = explode('.', '18.0.9');
498
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
499
                migrate_contractdet_rank();
500
            }
501
502
            // Scripts for 19.0
503
            /*
504
            $afterversionarray = explode('.', '18.0.9');
505
            $beforeversionarray = explode('.', '19.0.9');
506
            if (Version::compare($versiontoarray, $afterversionarray) >= 0 && Version::compare($versiontoarray, $beforeversionarray) <= 0) {
507
                migrate_contractdet_rank();
508
            }
509
            */
510
        }
511
512
513
        // Code executed only if migration is LAST ONE. Must always be done.
514
        if (Version::compare($versiontoarray, $versionranarray) >= 0 || Version::compare($versiontoarray, $versionranarray) <= -3) {
515
            // Reload modules (this must be always done and only into last targeted version, because code to reload module may need table structure of last version)
516
            $listofmodule = array(
517
                'MAIN_MODULE_ACCOUNTING' => 'newboxdefonly',
518
                'MAIN_MODULE_AGENDA' => 'newboxdefonly',
519
                'MAIN_MODULE_BOM' => 'menuonly',
520
                'MAIN_MODULE_BANQUE' => 'menuonly',
521
                'MAIN_MODULE_BARCODE' => 'newboxdefonly',
522
                'MAIN_MODULE_CRON' => 'newboxdefonly',
523
                'MAIN_MODULE_COMMANDE' => 'newboxdefonly',
524
                'MAIN_MODULE_BLOCKEDLOG' => 'noboxes',
525
                'MAIN_MODULE_DEPLACEMENT' => 'newboxdefonly',
526
                'MAIN_MODULE_DON' => 'newboxdefonly',
527
                'MAIN_MODULE_ECM' => 'newboxdefonly',
528
                'MAIN_MODULE_EXTERNALSITE' => 'newboxdefonly',
529
                'MAIN_MODULE_EXPENSEREPORT' => 'newboxdefonly',
530
                'MAIN_MODULE_FACTURE' => 'newboxdefonly',
531
                'MAIN_MODULE_FOURNISSEUR' => 'newboxdefonly',
532
                'MAIN_MODULE_FICHEINTER' => 'newboxdefonly',
533
                'MAIN_MODULE_HOLIDAY' => 'newboxdefonly',
534
                'MAIN_MODULE_MARGIN' => 'menuonly',
535
                'MAIN_MODULE_MRP' => 'menuonly',
536
                'MAIN_MODULE_OPENSURVEY' => 'newboxdefonly',
537
                'MAIN_MODULE_PAYBOX' => 'newboxdefonly',
538
                'MAIN_MODULE_PRINTING' => 'newboxdefonly',
539
                'MAIN_MODULE_PRODUIT' => 'newboxdefonly',
540
                'MAIN_MODULE_RECRUITMENT' => 'menuonly',
541
                'MAIN_MODULE_RESOURCE' => 'noboxes',
542
                'MAIN_MODULE_SALARIES' => 'newboxdefonly',
543
                'MAIN_MODULE_SERVICE' => 'newboxdefonly',
544
                'MAIN_MODULE_SYSLOG' => 'newboxdefonly',
545
                'MAIN_MODULE_SOCIETE' => 'newboxdefonly',
546
                'MAIN_MODULE_STRIPE' => 'menuonly',
547
                'MAIN_MODULE_TICKET' => 'newboxdefonly',
548
                'MAIN_MODULE_TAKEPOS' => 'newboxdefonly',
549
                'MAIN_MODULE_USER' => 'newboxdefonly', //This one must be always done and only into last targeted version)
550
                'MAIN_MODULE_VARIANTS' => 'newboxdefonly',
551
                'MAIN_MODULE_WEBSITE' => 'newboxdefonly',
552
            );
553
554
            $result = migrate_reload_modules($db, $langs, $conf, $listofmodule);
555
            if ($result < 0) {
556
                $error++;
557
            }
558
            // Reload menus (this must be always and only into last targeted version)
559
            $result = migrate_reload_menu($db, $langs, $conf);
560
            if ($result < 0) {
561
                $error++;
562
            }
563
        }
564
565
        // Can force activation of some module during migration with parameter 'enablemodules=MAIN_MODULE_XXX,MAIN_MODULE_YYY,...'
566
        // In most cases (online install or upgrade) $enablemodules is empty. Can be forced when ran from command line.
567
        if (!$error && $enablemodules) {
568
            // Reload modules (this must be always done and only into last targeted version)
569
            $listofmodules = array();
570
            $enablemodules = preg_replace('/enablemodules=/', '', $enablemodules);
571
            $tmplistofmodules = explode(',', $enablemodules);
572
            foreach ($tmplistofmodules as $value) {
573
                $listofmodules[$value] = 'forceactivate';
574
            }
575
576
            $resultreloadmodules = migrate_reload_modules($db, $langs, $conf, $listofmodules, 1);
577
            if ($resultreloadmodules < 0) {
578
                $error++;
579
            }
580
        }
581
582
583
        // Can call a dedicated external upgrade process with hook doUpgradeAfterDB()
584
        if (!$error) {
585
            $parameters = array('versionfrom' => $versionfrom, 'versionto' => $versionto, 'conf' => $conf);
586
            $object = new stdClass();
587
            $action = "upgrade";
588
            $reshook = $hookmanager->executeHooks('doUpgradeAfterDB', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
589
            if ($hookmanager->resNbOfHooks > 0) {
590
                if ($reshook < 0) {
591
                    print '<tr><td colspan="4">';
592
                    print '<b>' . $langs->trans('UpgradeExternalModule') . '</b>: ';
593
                    print $hookmanager->error;
594
                    print "<!-- (" . $reshook . ") -->";
595
                    print '</td></tr>';
596
                } else {
597
                    print '<tr class="trforrunsql"><td colspan="4">';
598
                    print '<b>' . $langs->trans('UpgradeExternalModule') . ' (DB)</b>: <span class="ok">OK</span>';
599
                    print "<!-- (" . $reshook . ") -->";
600
                    print '</td></tr>';
601
                }
602
            } else {
603
                //if (!empty($conf->modules))
604
                if (!empty($conf->modules_parts['hooks'])) {     // If there is at least one module with one hook, we show message to say nothing was done
605
                    print '<tr class="trforrunsql"><td colspan="4">';
606
                    print '<b>' . $langs->trans('UpgradeExternalModule') . '</b>: ' . $langs->trans("NodoUpgradeAfterDB");
607
                    print '</td></tr>';
608
                }
609
            }
610
        }
611
    }
612
613
    print '</table>';
614
615
    if (!$error) {
616
        // Set constant to ask to remake a new ping to inform about upgrade (if first ping was done and OK)
617
        Constant::updateValueByName('MAIN_FIRST_PING_OK_ID', 'torefresh');
618
    }
619
620
    // We always commit.
621
    // Process is designed so we can run it several times whatever is situation.
622
    $db->commit();
623
624
625
    /***************************************************************************************
626
     *
627
     * Migration of files
628
     *
629
     ***************************************************************************************/
630
631
    foreach ($listofentities as $entity) {
632
        // Set $conf context for entity
633
        $conf->setEntityValues($db, $entity);
634
        // Reset forced setup after the setValues
635
        if (defined('SYSLOG_FILE')) {
636
            $conf->global->SYSLOG_FILE = constant('SYSLOG_FILE');
637
        }
638
        $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
639
640
641
        // Copy directory medias
642
        $srcroot = DOL_DOCUMENT_ROOT . '/install/medias';
643
        $destroot = DOL_DATA_ROOT . '/medias';
644
        dolCopyDir($srcroot, $destroot, 0, 0);
645
646
647
        // Actions for all versions (no database change but delete some files and directories)
648
        migrate_delete_old_files($db, $langs, $conf);
649
        migrate_delete_old_dir($db, $langs, $conf);
650
        // Actions for all versions (no database change but create some directories)
651
        dol_mkdir(DOL_DATA_ROOT . '/bank');
652
        // Actions for all versions (no database change but rename some directories)
653
        migrate_rename_directories($db, $langs, $conf, '/banque/bordereau', '/bank/checkdeposits');
654
655
656
        $parameters = array('versionfrom' => $versionfrom, 'versionto' => $versionto, 'conf' => $conf);
657
        $object = new stdClass();
658
        $action = "upgrade";
659
        $reshook = $hookmanager->executeHooks('doUpgradeAfterFiles', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
660
        if ($hookmanager->resNbOfHooks > 0) {
661
            if ($reshook < 0) {
662
                print '<tr><td colspan="4">';
663
                print '<b>' . $langs->trans('UpgradeExternalModule') . '</b>: ';
664
                print $hookmanager->error;
665
                print "<!-- (" . $reshook . ") -->";
666
                print '</td></tr>';
667
            } else {
668
                print '<tr class="trforrunsql"><td colspan="4">';
669
                print '<b>' . $langs->trans('UpgradeExternalModule') . ' (Files)</b>: <span class="ok">OK</span>';
670
                print "<!-- (" . $reshook . ") -->";
671
                print '</td></tr>';
672
            }
673
        } else {
674
            //if (!empty($conf->modules))
675
            if (!empty($conf->modules_parts['hooks'])) {     // If there is at least one module with one hook, we show message to say nothing was done
676
                print '<tr class="trforrunsql"><td colspan="4">';
677
                print '<b>' . $langs->trans('UpgradeExternalModule') . '</b>: ' . $langs->trans("NodoUpgradeAfterFiles");
678
                print '</td></tr>';
679
            }
680
        }
681
    }
682
683
    $db->close();
684
685
    $silent = 0;
686
    if (!$silent) {
687
        print '<table width="100%">';
688
        print '<tr><td style="width: 30%">' . $langs->trans("MigrationFinished") . '</td>';
689
        print '<td class="right">';
690
        if ($error == 0) {
691
            //print '<span class="ok">'.$langs->trans("OK").'</span> - ';       // $error = 0 does not mean there is no error (error are not always trapped)
692
        } else {
693
            print '<span class="error">' . $langs->trans("Error") . '</span> - ';
694
        }
695
696
        //if (!empty($conf->use_javascript_ajax)) {     // use_javascript_ajax is not defined
697
        print '<script type="text/javascript">
698
		jQuery(document).ready(function() {
699
			function init_trrunsql()
700
			{
701
				console.log("toggle .trforrunsql");
702
				jQuery(".trforrunsql").toggle();
703
			}
704
			init_trrunsql();
705
			jQuery(".trforrunsqlshowhide").click(function() {
706
				init_trrunsql();
707
			});
708
		});
709
		</script>';
710
        print '<a class="trforrunsqlshowhide" href="#">' . $langs->trans("ShowHideDetails") . '</a>';
711
        //}
712
713
        print '</td></tr>' . "\n";
714
        print '</table>';
715
    }
716
717
    //print '<div><br>'.$langs->trans("MigrationFinished").'</div>';
718
} else {
719
    print '<div class="error">' . $langs->trans('ErrorWrongParameters') . '</div>';
720
    $error++;
721
}
722
723
$ret = 0;
724
if ($error && isset($argv[1])) {
725
    $ret = 1;
726
}
727
dolibarr_install_syslog("Exit " . $ret);
728
729
dolibarr_install_syslog("--- upgrade2: end");
730
pFooter($error ? 2 : 0, $setuplang);
731
732
if ($db->connected) {
733
    $db->close();
734
}
735
736
// Return code if ran from command line
737
if ($ret) {
738
    exit($ret);
739
}
740
741
742
/**
743
 * Reporte liens vers une facture de paiements sur table de jointure (lien n-n paiements factures)
744
 *
745
 * @param DoliDB $db Database handler
746
 * @param Translate $langs Object langs
747
 * @param Conf $conf Object conf
748
 * @return  void
749
 */
750
function migrate_paiements($db, $langs, $conf)
751
{
752
    print '<tr><td colspan="4">';
753
754
    print '<br>';
755
    print '<b>' . $langs->trans('MigrationPaymentsUpdate') . "</b><br>\n";
756
757
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "paiement", "fk_facture");
758
    $obj = $db->fetch_object($result);
759
    if ($obj) {
760
        $sql = "SELECT p.rowid, p.fk_facture, p.amount";
761
        $sql .= " FROM " . MAIN_DB_PREFIX . "paiement as p";
762
        $sql .= " WHERE p.fk_facture > 0";
763
764
        $resql = $db->query($sql);
765
766
        dolibarr_install_syslog("upgrade2::migrate_paiements");
767
        if ($resql) {
768
            $i = 0;
769
            $row = array();
770
            $num = $db->num_rows($resql);
771
772
            while ($i < $num) {
773
                $obj = $db->fetch_object($resql);
774
                $row[$i][0] = $obj->rowid;
775
                $row[$i][1] = $obj->fk_facture;
776
                $row[$i][2] = $obj->amount;
777
                $i++;
778
            }
779
        } else {
780
            dol_print_error($db);
781
        }
782
783
        if ($num) {
784
            print $langs->trans('MigrationPaymentsNumberToUpdate', $num) . "<br>\n";
785
            if ($db->begin()) {
786
                $res = 0;
787
                $num = count($row);
788
                for ($i = 0; $i < $num; $i++) {
789
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "paiement_facture (fk_facture, fk_paiement, amount)";
790
                    $sql .= " VALUES (" . ((int)$row[$i][1]) . "," . ((int)$row[$i][0]) . "," . ((float)$row[$i][2]) . ")";
791
792
                    $res += $db->query($sql);
793
794
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "paiement SET fk_facture = 0 WHERE rowid = " . ((int)$row[$i][0]);
795
796
                    $res += $db->query($sql);
797
798
                    print $langs->trans('MigrationProcessPaymentUpdate', $row[$i][0]) . "<br>\n";
799
                }
800
            }
801
802
            if ($res == (2 * count($row))) {
803
                $db->commit();
804
                print $langs->trans('MigrationSuccessfullUpdate') . "<br>";
805
            } else {
806
                $db->rollback();
807
                print $langs->trans('MigrationUpdateFailed') . '<br>';
808
            }
809
        } else {
810
            print $langs->trans('MigrationPaymentsNothingToUpdate') . "<br>\n";
811
        }
812
    } else {
813
        print $langs->trans('MigrationPaymentsNothingToUpdate') . "<br>\n";
814
    }
815
816
    print '</td></tr>';
817
}
818
819
/**
820
 * Corrige paiement orphelins (liens paumes suite a bugs)
821
 * Pour verifier s'il reste des orphelins:
822
 * select * from llx_paiement as p left join llx_paiement_facture as pf on pf.fk_paiement=p.rowid WHERE pf.rowid IS NULL AND (p.fk_facture = 0 OR p.fk_facture IS NULL)
823
 *
824
 * @param DoliDB $db Database handler
825
 * @param Translate $langs Object langs
826
 * @param Conf $conf Object conf
827
 * @return  void
828
 */
829
function migrate_paiements_orphelins_1($db, $langs, $conf)
830
{
831
    print '<tr><td colspan="4">';
832
833
    print '<br>';
834
    print '<b>' . $langs->trans('MigrationPaymentsUpdate') . "</b><br>\n";
835
836
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "paiement", "fk_facture");
837
    $obj = $db->fetch_object($result);
838
    if ($obj) {
839
        // Tous les enregistrements qui sortent de cette requete devrait avoir un pere dans llx_paiement_facture
840
        $sql = "SELECT distinct p.rowid, p.datec, p.amount as pamount, bu.fk_bank, b.amount as bamount,";
841
        $sql .= " bu2.url_id as socid";
842
        $sql .= " FROM (" . MAIN_DB_PREFIX . "paiement as p, " . MAIN_DB_PREFIX . "bank_url as bu, " . MAIN_DB_PREFIX . "bank as b)";
843
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "paiement_facture as pf ON pf.fk_paiement = p.rowid";
844
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu2 ON (bu.fk_bank=bu2.fk_bank AND bu2.type = 'company')";
845
        $sql .= " WHERE pf.rowid IS NULL AND (p.rowid=bu.url_id AND bu.type='payment') AND bu.fk_bank = b.rowid";
846
        $sql .= " AND b.rappro = 1";
847
        $sql .= " AND (p.fk_facture = 0 OR p.fk_facture IS NULL)";
848
849
        $resql = $db->query($sql);
850
851
        dolibarr_install_syslog("upgrade2::migrate_paiements_orphelins_1");
852
        $row = array();
853
        if ($resql) {
854
            $i = $j = 0;
855
            $num = $db->num_rows($resql);
856
857
            while ($i < $num) {
858
                $obj = $db->fetch_object($resql);
859
                if ($obj->pamount == $obj->bamount && $obj->socid) {    // Pour etre sur d'avoir bon cas
860
                    $row[$j]['paymentid'] = $obj->rowid; // paymentid
861
                    $row[$j]['pamount'] = $obj->pamount;
862
                    $row[$j]['fk_bank'] = $obj->fk_bank;
863
                    $row[$j]['bamount'] = $obj->bamount;
864
                    $row[$j]['socid'] = $obj->socid;
865
                    $row[$j]['datec'] = $obj->datec;
866
                    $j++;
867
                }
868
                $i++;
869
            }
870
        } else {
871
            dol_print_error($db);
872
        }
873
874
        if (count($row)) {
875
            print $langs->trans('OrphelinsPaymentsDetectedByMethod', 1) . ': ' . count($row) . "<br>\n";
876
            $db->begin();
877
878
            $res = 0;
879
            $num = count($row);
880
            for ($i = 0; $i < $num; $i++) {
881
                if (getDolGlobalInt('MAIN_FEATURES_LEVEL') == 2) {
882
                    print '* ' . $row[$i]['datec'] . ' paymentid=' . $row[$i]['paymentid'] . ' pamount=' . $row[$i]['pamount'] . ' fk_bank=' . $row[$i]['fk_bank'] . ' bamount=' . $row[$i]['bamount'] . ' socid=' . $row[$i]['socid'] . '<br>';
883
                }
884
885
                // On cherche facture sans lien paiement et du meme montant et pour meme societe.
886
                $sql = " SELECT distinct f.rowid from " . MAIN_DB_PREFIX . "facture as f";
887
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "paiement_facture as pf ON f.rowid = pf.fk_facture";
888
                $sql .= " WHERE f.fk_statut in (2,3) AND fk_soc = " . ((int)$row[$i]['socid']) . " AND total_ttc = " . ((float)$row[$i]['pamount']);
889
                $sql .= " AND pf.fk_facture IS NULL";
890
                $sql .= " ORDER BY f.fk_statut";
891
                //print $sql.'<br>';
892
                $resql = $db->query($sql);
893
                if ($resql) {
894
                    $num = $db->num_rows($resql);
895
                    //print 'Nb of invoice found for this amount and company :'.$num.'<br>';
896
                    if ($num >= 1) {
897
                        $obj = $db->fetch_object($resql);
898
                        $facid = $obj->rowid;
899
900
                        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "paiement_facture (fk_facture, fk_paiement, amount)";
901
                        $sql .= " VALUES (" . ((int)$facid) . "," . ((int)$row[$i]['paymentid']) . ", " . ((float)$row[$i]['pamount']) . ")";
902
903
                        $res += $db->query($sql);
904
905
                        print $langs->trans('MigrationProcessPaymentUpdate', 'facid=' . $facid . '-paymentid=' . $row[$i]['paymentid'] . '-amount=' . $row[$i]['pamount']) . "<br>\n";
906
                    }
907
                } else {
908
                    print 'ERROR';
909
                }
910
            }
911
912
            if ($res > 0) {
913
                print $langs->trans('MigrationSuccessfullUpdate') . "<br>";
914
            } else {
915
                print $langs->trans('MigrationPaymentsNothingUpdatable') . "<br>\n";
916
            }
917
918
            $db->commit();
919
        } else {
920
            print $langs->trans('MigrationPaymentsNothingUpdatable') . "<br>\n";
921
        }
922
    } else {
923
        print $langs->trans('MigrationPaymentsNothingUpdatable') . "<br>\n";
924
    }
925
926
    print '</td></tr>';
927
}
928
929
/**
930
 * Corrige paiement orphelins (liens paumes suite a bugs)
931
 * Pour verifier s'il reste des orphelins:
932
 * select * from llx_paiement as p left join llx_paiement_facture as pf on pf.fk_paiement=p.rowid WHERE pf.rowid IS NULL AND (p.fk_facture = 0 OR p.fk_facture IS NULL)
933
 *
934
 * @param DoliDB $db Database handler
935
 * @param Translate $langs Object langs
936
 * @param Conf $conf Object conf
937
 * @return  void
938
 */
939
function migrate_paiements_orphelins_2($db, $langs, $conf)
940
{
941
    print '<tr><td colspan="4">';
942
943
    print '<br>';
944
    print '<b>' . $langs->trans('MigrationPaymentsUpdate') . "</b><br>\n";
945
946
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "paiement", "fk_facture");
947
    $obj = $db->fetch_object($result);
948
    if ($obj) {
949
        // Tous les enregistrements qui sortent de cette requete devrait avoir un pere dans llx_paiement_facture
950
        $sql = "SELECT distinct p.rowid, p.datec, p.amount as pamount, bu.fk_bank, b.amount as bamount,";
951
        $sql .= " bu2.url_id as socid";
952
        $sql .= " FROM (" . MAIN_DB_PREFIX . "paiement as p, " . MAIN_DB_PREFIX . "bank_url as bu, " . MAIN_DB_PREFIX . "bank as b)";
953
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "paiement_facture as pf ON pf.fk_paiement = p.rowid";
954
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu2 ON (bu.fk_bank = bu2.fk_bank AND bu2.type = 'company')";
955
        $sql .= " WHERE pf.rowid IS NULL AND (p.fk_bank = bu.fk_bank AND bu.type = 'payment') AND bu.fk_bank = b.rowid";
956
        $sql .= " AND (p.fk_facture = 0 OR p.fk_facture IS NULL)";
957
958
        $resql = $db->query($sql);
959
960
        dolibarr_install_syslog("upgrade2::migrate_paiements_orphelins_2");
961
        $row = array();
962
        if ($resql) {
963
            $i = $j = 0;
964
            $num = $db->num_rows($resql);
965
966
            while ($i < $num) {
967
                $obj = $db->fetch_object($resql);
968
                if ($obj->pamount == $obj->bamount && $obj->socid) {    // Pour etre sur d'avoir bon cas
969
                    $row[$j]['paymentid'] = $obj->rowid; // paymentid
970
                    $row[$j]['pamount'] = $obj->pamount;
971
                    $row[$j]['fk_bank'] = $obj->fk_bank;
972
                    $row[$j]['bamount'] = $obj->bamount;
973
                    $row[$j]['socid'] = $obj->socid;
974
                    $row[$j]['datec'] = $obj->datec;
975
                    $j++;
976
                }
977
                $i++;
978
            }
979
        } else {
980
            dol_print_error($db);
981
        }
982
983
        $nberr = 0;
984
985
        $num = count($row);
986
        if ($num) {
987
            print $langs->trans('OrphelinsPaymentsDetectedByMethod', 2) . ': ' . count($row) . "<br>\n";
988
            $db->begin();
989
990
            $res = 0;
991
            for ($i = 0; $i < $num; $i++) {
992
                if (getDolGlobalInt('MAIN_FEATURES_LEVEL') == 2) {
993
                    print '* ' . $row[$i]['datec'] . ' paymentid=' . $row[$i]['paymentid'] . ' pamount=' . $row[$i]['pamount'] . ' fk_bank=' . $row[$i]['fk_bank'] . ' ' . $row[$i]['bamount'] . ' socid=' . $row[$i]['socid'] . '<br>';
994
                }
995
996
                // On cherche facture sans lien paiement et du meme montant et pour meme societe.
997
                $sql = " SELECT distinct f.rowid from " . MAIN_DB_PREFIX . "facture as f";
998
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "paiement_facture as pf ON f.rowid = pf.fk_facture";
999
                $sql .= " WHERE f.fk_statut in (2,3) AND fk_soc = " . ((int)$row[$i]['socid']) . " AND total_ttc = " . ((float)$row[$i]['pamount']);
1000
                $sql .= " AND pf.fk_facture IS NULL";
1001
                $sql .= " ORDER BY f.fk_statut";
1002
                //print $sql.'<br>';
1003
                $resql = $db->query($sql);
1004
                if ($resql) {
1005
                    $num = $db->num_rows($resql);
1006
                    //print 'Nb of invoice found for this amount and company :'.$num.'<br>';
1007
                    if ($num >= 1) {
1008
                        $obj = $db->fetch_object($resql);
1009
                        $facid = $obj->rowid;
1010
1011
                        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "paiement_facture (fk_facture, fk_paiement, amount)";
1012
                        $sql .= " VALUES (" . ((int)$facid) . "," . ((int)$row[$i]['paymentid']) . ", " . ((float)$row[$i]['pamount']) . ")";
1013
1014
                        $res += $db->query($sql);
1015
1016
                        print $langs->trans('MigrationProcessPaymentUpdate', 'facid=' . $facid . '-paymentid=' . $row[$i]['paymentid'] . '-amount=' . $row[$i]['pamount']) . "<br>\n";
1017
                    }
1018
                } else {
1019
                    print 'ERROR';
1020
                    $nberr++;
1021
                }
1022
            }
1023
1024
            if ($res > 0) {
1025
                print $langs->trans('MigrationSuccessfullUpdate') . "<br>";
1026
            } else {
1027
                print $langs->trans('MigrationPaymentsNothingUpdatable') . "<br>\n";
1028
            }
1029
1030
            $db->commit();
1031
        } else {
1032
            print $langs->trans('MigrationPaymentsNothingUpdatable') . "<br>\n";
1033
        }
1034
1035
        // Delete obsolete fields fk_facture
1036
        $db->begin();
1037
1038
        $sql = "ALTER TABLE " . MAIN_DB_PREFIX . "paiement DROP COLUMN fk_facture";
1039
        $db->query($sql);
1040
1041
        if (!$nberr) {
1042
            $db->commit();
1043
        } else {
1044
            print 'ERROR';
1045
            $db->rollback();
1046
        }
1047
    } else {
1048
        print $langs->trans('MigrationPaymentsNothingUpdatable') . "<br>\n";
1049
    }
1050
1051
    print '</td></tr>';
1052
}
1053
1054
1055
/**
1056
 * Mise a jour des contrats (gestion du contrat + detail de contrat)
1057
 *
1058
 * @param DoliDB $db Database handler
1059
 * @param Translate $langs Object langs
1060
 * @param Conf $conf Object conf
1061
 * @return  void
1062
 */
1063
function migrate_contracts_det($db, $langs, $conf)
1064
{
1065
    print '<tr><td colspan="4">';
1066
1067
    $nberr = 0;
1068
1069
    print '<br>';
1070
    print '<b>' . $langs->trans('MigrationContractsUpdate') . "</b><br>\n";
1071
1072
    $sql = "SELECT c.rowid as cref, c.date_contrat, c.statut, c.fk_product, c.fk_facture, c.fk_user_author,";
1073
    $sql .= " p.ref, p.label, p.description, p.price, p.tva_tx, p.duration, cd.rowid";
1074
    $sql .= " FROM " . MAIN_DB_PREFIX . "contrat as c";
1075
    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p";
1076
    $sql .= " ON c.fk_product = p.rowid";
1077
    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "contratdet as cd";
1078
    $sql .= " ON c.rowid=cd.fk_contrat";
1079
    $sql .= " WHERE cd.rowid IS NULL AND p.rowid IS NOT NULL";
1080
    $resql = $db->query($sql);
1081
1082
    dolibarr_install_syslog("upgrade2::migrate_contracts_det");
1083
    if ($resql) {
1084
        $i = 0;
1085
        $row = array();
1086
        $num = $db->num_rows($resql);
1087
1088
        if ($num) {
1089
            print $langs->trans('MigrationContractsNumberToUpdate', $num) . "<br>\n";
1090
            $db->begin();
1091
1092
            while ($i < $num) {
1093
                $obj = $db->fetch_object($resql);
1094
1095
                $sql = "INSERT INTO " . MAIN_DB_PREFIX . "contratdet (";
1096
                $sql .= "fk_contrat, fk_product, statut, label, description,";
1097
                $sql .= "date_ouverture_prevue, date_ouverture, date_fin_validite, tva_tx, qty,";
1098
                $sql .= "subprice, price_ht, fk_user_author, fk_user_ouverture)";
1099
                $sql .= " VALUES (";
1100
                $sql .= ((int)$obj->cref) . ", " . ($obj->fk_product ? ((int)$obj->fk_product) : 0) . ", ";
1101
                $sql .= "0, ";
1102
                $sql .= "'" . $db->escape($obj->label) . "', null, ";
1103
                $sql .= ($obj->date_contrat ? "'" . $db->idate($db->jdate($obj->date_contrat)) . "'" : "null") . ", ";
1104
                $sql .= "null, ";
1105
                $sql .= "null, ";
1106
                $sql .= ((float)$obj->tva_tx) . ", 1, ";
1107
                $sql .= ((float)$obj->price) . ", " . ((float)$obj->price) . ", " . ((int)$obj->fk_user_author) . ",";
1108
                $sql .= "null";
1109
                $sql .= ")";
1110
1111
                if ($db->query($sql)) {
1112
                    print $langs->trans('MigrationContractsLineCreation', $obj->cref) . "<br>\n";
1113
                } else {
1114
                    dol_print_error($db);
1115
                    $nberr++;
1116
                }
1117
1118
                $i++;
1119
            }
1120
1121
            if (!$nberr) {
1122
                //      $db->rollback();
1123
                $db->commit();
1124
                print $langs->trans('MigrationSuccessfullUpdate') . "<br>";
1125
            } else {
1126
                $db->rollback();
1127
                print $langs->trans('MigrationUpdateFailed') . '<br>';
1128
            }
1129
        } else {
1130
            print $langs->trans('MigrationContractsNothingToUpdate') . "<br>\n";
1131
        }
1132
    } else {
1133
        print $langs->trans('MigrationContractsFieldDontExist') . "<br>\n";
1134
        //    dol_print_error($db);
1135
    }
1136
1137
    print '</td></tr>';
1138
}
1139
1140
/**
1141
 * Function to migrate links into llx_bank_url
1142
 *
1143
 * @param DoliDB $db Database handler
1144
 * @param Translate $langs Object langs
1145
 * @param Conf $conf Object conf
1146
 * @return  void
1147
 */
1148
function migrate_links_transfert($db, $langs, $conf)
1149
{
1150
    print '<tr><td colspan="4">';
1151
1152
    $nberr = 0;
1153
1154
    print '<br>';
1155
    print '<b>' . $langs->trans('MigrationBankTransfertsUpdate') . "</b><br>\n";
1156
1157
    $sql = "SELECT ba.rowid as barowid, bb.rowid as bbrowid";
1158
    $sql .= " FROM " . MAIN_DB_PREFIX . "bank as bb, " . MAIN_DB_PREFIX . "bank as ba";
1159
    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu ON bu.fk_bank = ba.rowid";
1160
    $sql .= " WHERE ba.amount = -bb.amount AND ba.fk_account <> bb.fk_account";
1161
    $sql .= " AND ba.datev = bb.datev AND ba.datec = bb.datec";
1162
    $sql .= " AND bu.fk_bank IS NULL";
1163
    $resql = $db->query($sql);
1164
1165
    dolibarr_install_syslog("upgrade2::migrate_links_transfert");
1166
    if ($resql) {
1167
        $i = 0;
1168
        $row = array();
1169
        $num = $db->num_rows($resql);
1170
1171
        if ($num) {
1172
            print $langs->trans('MigrationBankTransfertsToUpdate', $num) . "<br>\n";
1173
            $db->begin();
1174
1175
            while ($i < $num) {
1176
                $obj = $db->fetch_object($resql);
1177
1178
                $sql = "INSERT INTO " . MAIN_DB_PREFIX . "bank_url (";
1179
                $sql .= "fk_bank, url_id, url, label, type";
1180
                $sql .= ")";
1181
                $sql .= " VALUES (";
1182
                $sql .= $obj->barowid . "," . $obj->bbrowid . ", '/compta/bank/line.php?rowid=', '(banktransfert)', 'banktransfert'";
1183
                $sql .= ")";
1184
1185
                //print $sql.'<br>';
1186
                dolibarr_install_syslog("migrate_links_transfert");
1187
1188
                if (!$db->query($sql)) {
1189
                    dol_print_error($db);
1190
                    $nberr++;
1191
                }
1192
1193
                $i++;
1194
            }
1195
1196
            if (!$nberr) {
1197
                //      $db->rollback();
1198
                $db->commit();
1199
                print $langs->trans('MigrationSuccessfullUpdate') . "<br>";
1200
            } else {
1201
                $db->rollback();
1202
                print $langs->trans('MigrationUpdateFailed') . '<br>';
1203
            }
1204
        } else {
1205
            print $langs->trans('MigrationBankTransfertsNothingToUpdate') . "<br>\n";
1206
        }
1207
    } else {
1208
        dol_print_error($db);
1209
    }
1210
1211
    print '</td></tr>';
1212
}
1213
1214
/**
1215
 * Mise a jour des date de contrats non renseignees
1216
 *
1217
 * @param DoliDB $db Database handler
1218
 * @param Translate $langs Object langs
1219
 * @param Conf $conf Object conf
1220
 * @return  void
1221
 */
1222
function migrate_contracts_date1($db, $langs, $conf)
1223
{
1224
    print '<tr><td colspan="4">';
1225
1226
    print '<br>';
1227
    print '<b>' . $langs->trans('MigrationContractsEmptyDatesUpdate') . "</b><br>\n";
1228
1229
    $sql = "update " . MAIN_DB_PREFIX . "contrat set date_contrat=tms where date_contrat is null";
1230
    dolibarr_install_syslog("upgrade2::migrate_contracts_date1");
1231
    $resql = $db->query($sql);
1232
    if (!$resql) {
1233
        dol_print_error($db);
1234
    }
1235
    if ($db->affected_rows($resql) > 0) {
1236
        print $langs->trans('MigrationContractsEmptyDatesUpdateSuccess') . "<br>\n";
1237
    } else {
1238
        print $langs->trans('MigrationContractsEmptyDatesNothingToUpdate') . "<br>\n";
1239
    }
1240
1241
    $sql = "update " . MAIN_DB_PREFIX . "contrat set datec=tms where datec is null";
1242
    dolibarr_install_syslog("upgrade2::migrate_contracts_date1");
1243
    $resql = $db->query($sql);
1244
    if (!$resql) {
1245
        dol_print_error($db);
1246
    }
1247
    if ($db->affected_rows($resql) > 0) {
1248
        print $langs->trans('MigrationContractsEmptyCreationDatesUpdateSuccess') . "<br>\n";
1249
    } else {
1250
        print $langs->trans('MigrationContractsEmptyCreationDatesNothingToUpdate') . "<br>\n";
1251
    }
1252
1253
    print '</td></tr>';
1254
}
1255
1256
/**
1257
 * Update contracts with date min real if service date is lower
1258
 *
1259
 * @param DoliDB $db Database handler
1260
 * @param Translate $langs Language
1261
 * @param Conf $conf Conf
1262
 * @return  void
1263
 */
1264
function migrate_contracts_date2($db, $langs, $conf)
1265
{
1266
    print '<tr><td colspan="4">';
1267
1268
    $nberr = 0;
1269
1270
    print '<br>';
1271
    print '<b>' . $langs->trans('MigrationContractsInvalidDatesUpdate') . "</b><br>\n";
1272
1273
    $sql = "SELECT c.rowid as cref, c.datec, c.date_contrat, MIN(cd.date_ouverture) as datemin";
1274
    $sql .= " FROM " . MAIN_DB_PREFIX . "contrat as c,";
1275
    $sql .= " " . MAIN_DB_PREFIX . "contratdet as cd";
1276
    $sql .= " WHERE c.rowid=cd.fk_contrat AND cd.date_ouverture IS NOT NULL";
1277
    $sql .= " GROUP BY c.rowid, c.date_contrat";
1278
    $resql = $db->query($sql);
1279
1280
    dolibarr_install_syslog("upgrade2::migrate_contracts_date2");
1281
    if ($resql) {
1282
        $i = 0;
1283
        $row = array();
1284
        $num = $db->num_rows($resql);
1285
1286
        if ($num) {
1287
            $nbcontratsmodifie = 0;
1288
            $db->begin();
1289
1290
            while ($i < $num) {
1291
                $obj = $db->fetch_object($resql);
1292
                if ($obj->date_contrat > $obj->datemin) {
1293
                    $datemin = $db->jdate($obj->datemin);
1294
1295
                    print $langs->trans('MigrationContractsInvalidDateFix', $obj->cref, $obj->date_contrat, $obj->datemin) . "<br>\n";
1296
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "contrat";
1297
                    $sql .= " SET date_contrat='" . $db->idate($datemin) . "'";
1298
                    $sql .= " WHERE rowid = " . ((int)$obj->cref);
1299
                    $resql2 = $db->query($sql);
1300
                    if (!$resql2) {
1301
                        dol_print_error($db);
1302
                    }
1303
1304
                    $nbcontratsmodifie++;
1305
                }
1306
                $i++;
1307
            }
1308
1309
            $db->commit();
1310
1311
            if ($nbcontratsmodifie) {
1312
                print $langs->trans('MigrationContractsInvalidDatesNumber', $nbcontratsmodifie) . "<br>\n";
1313
            } else {
1314
                print  $langs->trans('MigrationContractsInvalidDatesNothingToUpdate') . "<br>\n";
1315
            }
1316
        }
1317
    } else {
1318
        dol_print_error($db);
1319
    }
1320
1321
    print '</td></tr>';
1322
}
1323
1324
/**
1325
 * Mise a jour des dates de creation de contrat
1326
 *
1327
 * @param DoliDB $db Database handler
1328
 * @param Translate $langs Object langs
1329
 * @param Conf $conf Object conf
1330
 * @return  void
1331
 */
1332
function migrate_contracts_date3($db, $langs, $conf)
1333
{
1334
    print '<tr><td colspan="4">';
1335
1336
    print '<br>';
1337
    print '<b>' . $langs->trans('MigrationContractsIncoherentCreationDateUpdate') . "</b><br>\n";
1338
1339
    $sql = "update " . MAIN_DB_PREFIX . "contrat set datec=date_contrat where datec is null or datec > date_contrat";
1340
    dolibarr_install_syslog("upgrade2::migrate_contracts_date3");
1341
    $resql = $db->query($sql);
1342
    if (!$resql) {
1343
        dol_print_error($db);
1344
    }
1345
    if ($db->affected_rows($resql) > 0) {
1346
        print $langs->trans('MigrationContractsIncoherentCreationDateUpdateSuccess') . "<br>\n";
1347
    } else {
1348
        print $langs->trans('MigrationContractsIncoherentCreationDateNothingToUpdate') . "<br>\n";
1349
    }
1350
1351
    print '</td></tr>';
1352
}
1353
1354
/**
1355
 * Reouverture des contrats qui ont au moins une ligne non fermee
1356
 *
1357
 * @param DoliDB $db Database handler
1358
 * @param Translate $langs Object langs
1359
 * @param Conf $conf Object conf
1360
 * @return  void
1361
 */
1362
function migrate_contracts_open($db, $langs, $conf)
1363
{
1364
    print '<tr><td colspan="4">';
1365
1366
    print '<br>';
1367
    print '<b>' . $langs->trans('MigrationReopeningContracts') . "</b><br>\n";
1368
1369
    $sql = "SELECT c.rowid as cref FROM " . MAIN_DB_PREFIX . "contrat as c, " . MAIN_DB_PREFIX . "contratdet as cd";
1370
    $sql .= " WHERE cd.statut = 4 AND c.statut=2 AND c.rowid=cd.fk_contrat";
1371
    dolibarr_install_syslog("upgrade2::migrate_contracts_open");
1372
    $resql = $db->query($sql);
1373
    if (!$resql) {
1374
        dol_print_error($db);
1375
    }
1376
    if ($db->affected_rows($resql) > 0) {
1377
        $i = 0;
1378
        $row = array();
1379
        $num = $db->num_rows($resql);
1380
1381
        if ($num) {
1382
            $nbcontratsmodifie = 0;
1383
            $db->begin();
1384
1385
            while ($i < $num) {
1386
                $obj = $db->fetch_object($resql);
1387
1388
                print $langs->trans('MigrationReopenThisContract', $obj->cref) . "<br>\n";
1389
                $sql = "UPDATE " . MAIN_DB_PREFIX . "contrat";
1390
                $sql .= " SET statut = 1";
1391
                $sql .= " WHERE rowid = " . ((int)$obj->cref);
1392
                $resql2 = $db->query($sql);
1393
                if (!$resql2) {
1394
                    dol_print_error($db);
1395
                }
1396
1397
                $nbcontratsmodifie++;
1398
1399
                $i++;
1400
            }
1401
1402
            $db->commit();
1403
1404
            if ($nbcontratsmodifie) {
1405
                print $langs->trans('MigrationReopenedContractsNumber', $nbcontratsmodifie) . "<br>\n";
1406
            } else {
1407
                print $langs->trans('MigrationReopeningContractsNothingToUpdate') . "<br>\n";
1408
            }
1409
        }
1410
    } else {
1411
        print $langs->trans('MigrationReopeningContractsNothingToUpdate') . "<br>\n";
1412
    }
1413
1414
    print '</td></tr>';
1415
}
1416
1417
/**
1418
 * Factures fournisseurs
1419
 *
1420
 * @param DoliDB $db Database handler
1421
 * @param Translate $langs Object langs
1422
 * @param Conf $conf Object conf
1423
 * @return  void
1424
 */
1425
function migrate_paiementfourn_facturefourn($db, $langs, $conf)
1426
{
1427
    global $bc;
1428
1429
    print '<tr><td colspan="4">';
1430
    print '<br>';
1431
    print '<b>' . $langs->trans('SuppliersInvoices') . "</b><br>\n";
1432
    print '</td></tr>';
1433
1434
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "paiementfourn", "fk_facture_fourn");
1435
    $obj = $db->fetch_object($result);
1436
    if ($obj) {
1437
        $error = 0;
1438
        $nb = 0;
1439
1440
        $select_sql = 'SELECT rowid, fk_facture_fourn, amount';
1441
        $select_sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiementfourn';
1442
        $select_sql .= ' WHERE fk_facture_fourn IS NOT NULL';
1443
1444
        dolibarr_install_syslog("upgrade2::migrate_paiementfourn_facturefourn");
1445
        $select_resql = $db->query($select_sql);
1446
        if ($select_resql) {
1447
            $select_num = $db->num_rows($select_resql);
1448
            $i = 0;
1449
1450
            // Pour chaque paiement fournisseur, on insere une ligne dans paiementfourn_facturefourn
1451
            while (($i < $select_num) && (!$error)) {
1452
                $select_obj = $db->fetch_object($select_resql);
1453
1454
                // Verifier si la ligne est deja dans la nouvelle table. On ne veut pas inserer de doublons.
1455
                $check_sql = 'SELECT fk_paiementfourn, fk_facturefourn';
1456
                $check_sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiementfourn_facturefourn';
1457
                $check_sql .= ' WHERE fk_paiementfourn = ' . ((int)$select_obj->rowid) . ' AND fk_facturefourn = ' . ((int)$select_obj->fk_facture_fourn);
1458
                $check_resql = $db->query($check_sql);
1459
                if ($check_resql) {
1460
                    $check_num = $db->num_rows($check_resql);
1461
                    if ($check_num == 0) {
1462
                        $db->begin();
1463
1464
                        if ($nb == 0) {
1465
                            print '<tr><td colspan="4" class="nowrap"><b>' . $langs->trans('SuppliersInvoices') . '</b></td></tr>';
1466
                            print '<tr><td>fk_paiementfourn</td><td>fk_facturefourn</td><td>' . $langs->trans('Amount') . '</td><td>&nbsp;</td></tr>';
1467
                        }
1468
1469
                        print '<tr class="oddeven">';
1470
                        print '<td>' . $select_obj->rowid . '</td><td>' . $select_obj->fk_facture_fourn . '</td><td>' . $select_obj->amount . '</td>';
1471
1472
                        $insert_sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'paiementfourn_facturefourn SET ';
1473
                        $insert_sql .= ' fk_paiementfourn = \'' . $select_obj->rowid . '\',';
1474
                        $insert_sql .= ' fk_facturefourn  = \'' . $select_obj->fk_facture_fourn . '\',';
1475
                        $insert_sql .= ' amount           = \'' . $select_obj->amount . '\'';
1476
                        $insert_resql = $db->query($insert_sql);
1477
1478
                        if ($insert_resql) {
1479
                            $nb++;
1480
                            print '<td><span class="ok">' . $langs->trans("OK") . '</span></td>';
1481
                        } else {
1482
                            print '<td><span class="error">Error on insert</span></td>';
1483
                            $error++;
1484
                        }
1485
                        print '</tr>';
1486
                    }
1487
                } else {
1488
                    $error++;
1489
                }
1490
                $i++;
1491
            }
1492
        } else {
1493
            $error++;
1494
        }
1495
1496
        if (!$error) {
1497
            if (!$nb) {
1498
                print '<tr><td>' . $langs->trans("AlreadyDone") . '</td></tr>';
1499
            }
1500
            $db->commit();
1501
1502
            $sql = "ALTER TABLE " . MAIN_DB_PREFIX . "paiementfourn DROP COLUMN fk_facture_fourn";
1503
            $db->query($sql);
1504
        } else {
1505
            print '<tr><td>' . $langs->trans("Error") . '</td></tr>';
1506
            $db->rollback();
1507
        }
1508
    } else {
1509
        print '<tr><td>' . $langs->trans("AlreadyDone") . '</td></tr>';
1510
    }
1511
}
1512
1513
/**
1514
 * Update total of invoice lines
1515
 *
1516
 * @param DoliDB $db Database handler
1517
 * @param Translate $langs Object langs
1518
 * @param Conf $conf Object conf
1519
 * @return  void
1520
 */
1521
function migrate_price_facture($db, $langs, $conf)
1522
{
1523
    $err = 0;
1524
1525
    $tmpmysoc = new Societe($db);
1526
    $tmpmysoc->setMysoc($conf);
1527
1528
    $db->begin();
1529
1530
    print '<tr><td colspan="4">';
1531
1532
    print '<br>';
1533
    print '<b>' . $langs->trans('MigrationInvoice') . "</b><br>\n";
1534
1535
    // List of invoice lines not up to date
1536
    $sql = "SELECT fd.rowid, fd.qty, fd.subprice, fd.remise_percent, fd.tva_tx as vatrate, fd.total_ttc, fd.info_bits,";
1537
    $sql .= " f.rowid as facid, f.remise_percent as remise_percent_global, f.total_ttc as total_ttc_f";
1538
    $sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd, " . MAIN_DB_PREFIX . "facture as f";
1539
    $sql .= " WHERE fd.fk_facture = f.rowid";
1540
    $sql .= " AND (((fd.total_ttc = 0 AND fd.remise_percent != 100) or fd.total_ttc IS NULL) or f.total_ttc IS NULL)";
1541
    //print $sql;
1542
1543
    dolibarr_install_syslog("upgrade2::migrate_price_facture");
1544
    $resql = $db->query($sql);
1545
    if ($resql) {
1546
        $num = $db->num_rows($resql);
1547
        $i = 0;
1548
        if ($num) {
1549
            while ($i < $num) {
1550
                $obj = $db->fetch_object($resql);
1551
1552
                $rowid = $obj->rowid;
1553
                $qty = $obj->qty;
1554
                $pu = $obj->subprice;
1555
                $vatrate = $obj->vatrate;
1556
                $remise_percent = $obj->remise_percent;
1557
                $remise_percent_global = $obj->remise_percent_global;
1558
                $total_ttc_f = $obj->total_ttc_f;
1559
                $info_bits = $obj->info_bits;
1560
1561
                // On met a jour les 3 nouveaux champs
1562
                $facligne = new FactureLigne($db);
1563
                $facligne->fetch($rowid);
1564
1565
                $result = calcul_price_total($qty, $pu, $remise_percent, $vatrate, 0, 0, $remise_percent_global, 'HT', $info_bits, $facligne->product_type, $tmpmysoc);
1566
                $total_ht = $result[0];
1567
                $total_tva = $result[1];
1568
                $total_ttc = $result[2];
1569
1570
                $facligne->total_ht = $total_ht;
1571
                $facligne->total_tva = $total_tva;
1572
                $facligne->total_ttc = $total_ttc;
1573
1574
                dolibarr_install_syslog("upgrade2: line " . $rowid . ": facid=" . $obj->facid . " pu=" . $pu . " qty=" . $qty . " vatrate=" . $vatrate . " remise_percent=" . $remise_percent . " remise_global=" . $remise_percent_global . " -> " . $total_ht . ", " . $total_tva . ", " . $total_ttc);
1575
                print '. ';
1576
                $facligne->update_total();
1577
1578
1579
                /* On touche a facture mere uniquement si total_ttc = 0 */
1580
                if (!$total_ttc_f) {
1581
                    $facture = new Facture($db);
1582
                    $facture->id = $obj->facid;
1583
1584
                    if ($facture->fetch($facture->id) >= 0) {
1585
                        if ($facture->update_price() > 0) {
1586
                            //print $facture->id;
1587
                        } else {
1588
                            print "Error id=" . $facture->id;
1589
                            $err++;
1590
                        }
1591
                    } else {
1592
                        print "Error #3";
1593
                        $err++;
1594
                    }
1595
                }
1596
                print " ";
1597
1598
                $i++;
1599
            }
1600
        } else {
1601
            print $langs->trans("AlreadyDone");
1602
        }
1603
        $db->free($resql);
1604
1605
        $db->commit();
1606
    } else {
1607
        print "Error #1 " . $db->error();
1608
        $err++;
1609
1610
        $db->rollback();
1611
    }
1612
1613
    print '<br>';
1614
1615
    print '</td></tr>';
1616
}
1617
1618
/**
1619
 * Update total of proposal lines
1620
 *
1621
 * @param DoliDB $db Database handler
1622
 * @param Translate $langs Object langs
1623
 * @param Conf $conf Object conf
1624
 * @return  void
1625
 */
1626
function migrate_price_propal($db, $langs, $conf)
1627
{
1628
    $tmpmysoc = new Societe($db);
1629
    $tmpmysoc->setMysoc($conf);
1630
1631
    $db->begin();
1632
1633
    print '<tr><td colspan="4">';
1634
1635
    print '<br>';
1636
    print '<b>' . $langs->trans('MigrationProposal') . "</b><br>\n";
1637
1638
    // List of proposal lines not up to date
1639
    $sql = "SELECT pd.rowid, pd.qty, pd.subprice, pd.remise_percent, pd.tva_tx as vatrate, pd.info_bits,";
1640
    $sql .= " p.rowid as propalid, p.remise_percent as remise_percent_global";
1641
    $sql .= " FROM " . MAIN_DB_PREFIX . "propaldet as pd, " . MAIN_DB_PREFIX . "propal as p";
1642
    $sql .= " WHERE pd.fk_propal = p.rowid";
1643
    $sql .= " AND ((pd.total_ttc = 0 AND pd.remise_percent != 100) or pd.total_ttc IS NULL)";
1644
1645
    dolibarr_install_syslog("upgrade2::migrate_price_propal");
1646
    $resql = $db->query($sql);
1647
    if ($resql) {
1648
        $num = $db->num_rows($resql);
1649
        $i = 0;
1650
        if ($num) {
1651
            while ($i < $num) {
1652
                $obj = $db->fetch_object($resql);
1653
1654
                $rowid = $obj->rowid;
1655
                $qty = $obj->qty;
1656
                $pu = $obj->subprice;
1657
                $vatrate = $obj->vatrate;
1658
                $remise_percent = $obj->remise_percent;
1659
                $remise_percent_global = $obj->remise_percent_global;
1660
                $info_bits = $obj->info_bits;
1661
1662
                // On met a jour les 3 nouveaux champs
1663
                $propalligne = new PropaleLigne($db);
1664
                $propalligne->fetch($rowid);
1665
1666
                $result = calcul_price_total($qty, $pu, $remise_percent, $vatrate, 0, 0, $remise_percent_global, 'HT', $info_bits, $propalligne->product_type, $tmpmysoc);
1667
                $total_ht = $result[0];
1668
                $total_tva = $result[1];
1669
                $total_ttc = $result[2];
1670
1671
                $propalligne->total_ht = $total_ht;
1672
                $propalligne->total_tva = $total_tva;
1673
                $propalligne->total_ttc = $total_ttc;
1674
1675
                dolibarr_install_syslog("upgrade2: Line " . $rowid . ": propalid=" . $obj->rowid . " pu=" . $pu . " qty=" . $qty . " vatrate=" . $vatrate . " remise_percent=" . $remise_percent . " remise_global=" . $remise_percent_global . " -> " . $total_ht . ", " . $total_tva . ", " . $total_ttc);
1676
                print '. ';
1677
                $propalligne->update_total();
1678
1679
                $i++;
1680
            }
1681
        } else {
1682
            print $langs->trans("AlreadyDone");
1683
        }
1684
1685
        $db->free($resql);
1686
1687
        $db->commit();
1688
    } else {
1689
        print "Error #1 " . $db->error();
1690
1691
        $db->rollback();
1692
    }
1693
1694
    print '<br>';
1695
1696
    print '</td></tr>';
1697
}
1698
1699
/**
1700
 * Update total of contract lines
1701
 *
1702
 * @param DoliDB $db Database handler
1703
 * @param Translate $langs Object langs
1704
 * @param Conf $conf Object conf
1705
 * @return  void
1706
 */
1707
function migrate_price_contrat($db, $langs, $conf)
1708
{
1709
    $db->begin();
1710
1711
    $tmpmysoc = new Societe($db);
1712
    $tmpmysoc->setMysoc($conf);
1713
    if (empty($tmpmysoc->country_id)) {
1714
        $tmpmysoc->country_id = 0; // Ti not have this set to '' or will make sql syntax error.
1715
    }
1716
1717
    print '<tr><td colspan="4">';
1718
1719
    print '<br>';
1720
    print '<b>' . $langs->trans('MigrationContract') . "</b><br>\n";
1721
1722
    // List of contract lines not up to date
1723
    $sql = "SELECT cd.rowid, cd.qty, cd.subprice, cd.remise_percent, cd.tva_tx as vatrate, cd.info_bits,";
1724
    $sql .= " c.rowid as contratid";
1725
    $sql .= " FROM " . MAIN_DB_PREFIX . "contratdet as cd, " . MAIN_DB_PREFIX . "contrat as c";
1726
    $sql .= " WHERE cd.fk_contrat = c.rowid";
1727
    $sql .= " AND ((cd.total_ttc = 0 AND cd.remise_percent != 100 AND cd.subprice > 0) or cd.total_ttc IS NULL)";
1728
1729
    dolibarr_install_syslog("upgrade2::migrate_price_contrat");
1730
    $resql = $db->query($sql);
1731
    if ($resql) {
1732
        $num = $db->num_rows($resql);
1733
        $i = 0;
1734
        if ($num) {
1735
            while ($i < $num) {
1736
                $obj = $db->fetch_object($resql);
1737
1738
                $rowid = $obj->rowid;
1739
                $qty = $obj->qty;
1740
                $pu = $obj->subprice;
1741
                $vatrate = $obj->vatrate;
1742
                $remise_percent = $obj->remise_percent;
1743
                $info_bits = $obj->info_bits;
1744
1745
                // On met a jour les 3 nouveaux champs
1746
                $contratligne = new ContratLigne($db);
1747
                //$contratligne->fetch($rowid); Non requis car le update_total ne met a jour que chp redefinis
1748
                $contratligne->fetch($rowid);
1749
1750
                $result = calcul_price_total($qty, $pu, $remise_percent, $vatrate, 0, 0, 0, 'HT', $info_bits, $contratligne->product_type, $tmpmysoc);
1751
                $total_ht = $result[0];
1752
                $total_tva = $result[1];
1753
                $total_ttc = $result[2];
1754
1755
                $contratligne->total_ht = $total_ht;
1756
                $contratligne->total_tva = $total_tva;
1757
                $contratligne->total_ttc = $total_ttc;
1758
1759
                dolibarr_install_syslog("upgrade2: Line " . $rowid . ": contratdetid=" . $obj->rowid . " pu=" . $pu . " qty=" . $qty . " vatrate=" . $vatrate . " remise_percent=" . $remise_percent . "  -> " . $total_ht . ", " . $total_tva . " , " . $total_ttc);
1760
                print '. ';
1761
                $contratligne->update_total();
1762
1763
                $i++;
1764
            }
1765
        } else {
1766
            print $langs->trans("AlreadyDone");
1767
        }
1768
1769
        $db->free($resql);
1770
1771
        $db->commit();
1772
    } else {
1773
        print "Error #1 " . $db->error();
1774
1775
        $db->rollback();
1776
    }
1777
1778
    print '<br>';
1779
1780
    print '</td></tr>';
1781
}
1782
1783
/**
1784
 * Update total of sales order lines
1785
 *
1786
 * @param DoliDB $db Database handler
1787
 * @param Translate $langs Object langs
1788
 * @param Conf $conf Object conf
1789
 * @return  void
1790
 */
1791
function migrate_price_commande($db, $langs, $conf)
1792
{
1793
    $db->begin();
1794
1795
    $tmpmysoc = new Societe($db);
1796
    $tmpmysoc->setMysoc($conf);
1797
1798
    print '<tr><td colspan="4">';
1799
1800
    print '<br>';
1801
    print '<b>' . $langs->trans('MigrationOrder') . "</b><br>\n";
1802
1803
    // List of sales orders lines not up to date
1804
    $sql = "SELECT cd.rowid, cd.qty, cd.subprice, cd.remise_percent, cd.tva_tx as vatrate, cd.info_bits,";
1805
    $sql .= " c.rowid as commandeid, c.remise_percent as remise_percent_global";
1806
    $sql .= " FROM " . MAIN_DB_PREFIX . "commandedet as cd, " . MAIN_DB_PREFIX . "commande as c";
1807
    $sql .= " WHERE cd.fk_commande = c.rowid";
1808
    $sql .= " AND ((cd.total_ttc = 0 AND cd.remise_percent != 100) or cd.total_ttc IS NULL)";
1809
1810
    dolibarr_install_syslog("upgrade2::migrate_price_commande");
1811
    $resql = $db->query($sql);
1812
    if ($resql) {
1813
        $num = $db->num_rows($resql);
1814
        $i = 0;
1815
        if ($num) {
1816
            while ($i < $num) {
1817
                $obj = $db->fetch_object($resql);
1818
1819
                $rowid = $obj->rowid;
1820
                $qty = $obj->qty;
1821
                $pu = $obj->subprice;
1822
                $vatrate = $obj->vatrate;
1823
                $remise_percent = $obj->remise_percent;
1824
                $remise_percent_global = $obj->remise_percent_global;
1825
                $info_bits = $obj->info_bits;
1826
1827
                // On met a jour les 3 nouveaux champs
1828
                $commandeligne = new OrderLine($db);
1829
                $commandeligne->fetch($rowid);
1830
1831
                $result = calcul_price_total($qty, $pu, $remise_percent, $vatrate, 0, 0, $remise_percent_global, 'HT', $info_bits, $commandeligne->product_type, $tmpmysoc);
1832
                $total_ht = $result[0];
1833
                $total_tva = $result[1];
1834
                $total_ttc = $result[2];
1835
1836
                $commandeligne->total_ht = $total_ht;
1837
                $commandeligne->total_tva = $total_tva;
1838
                $commandeligne->total_ttc = $total_ttc;
1839
1840
                dolibarr_install_syslog("upgrade2: Line " . $rowid . " : commandeid=" . $obj->rowid . " pu=" . $pu . " qty=" . $qty . " vatrate=" . $vatrate . " remise_percent=" . $remise_percent . " remise_global=" . $remise_percent_global . "  -> " . $total_ht . ", " . $total_tva . ", " . $total_ttc);
1841
                print '. ';
1842
                $commandeligne->update_total();
1843
1844
                $i++;
1845
            }
1846
        } else {
1847
            print $langs->trans("AlreadyDone");
1848
        }
1849
1850
        $db->free($resql);
1851
1852
        /*
1853
         $sql = "DELETE FROM ".MAIN_DB_PREFIX."commandedet";
1854
         $sql.= " WHERE price = 0 and total_ttc = 0 and total_tva = 0 and total_ht = 0 AND remise_percent = 0";
1855
         $resql=$db->query($sql);
1856
         if (! $resql)
1857
         {
1858
         dol_print_error($db);
1859
         }
1860
         */
1861
1862
        $db->commit();
1863
    } else {
1864
        print "Error #1 " . $db->error();
1865
1866
        $db->rollback();
1867
    }
1868
1869
    print '<br>';
1870
1871
    print '</td></tr>';
1872
}
1873
1874
/**
1875
 * Update total of purchase order lines
1876
 *
1877
 * @param DoliDB $db Database handler
1878
 * @param Translate $langs Object langs
1879
 * @param Conf $conf Object conf
1880
 * @return  void
1881
 */
1882
function migrate_price_commande_fournisseur($db, $langs, $conf)
1883
{
1884
    global $mysoc;
1885
1886
    $db->begin();
1887
1888
    $tmpmysoc = new Societe($db);
1889
    $tmpmysoc->setMysoc($conf);
1890
1891
    print '<tr><td colspan="4">';
1892
1893
    print '<br>';
1894
    print '<b>' . $langs->trans('MigrationSupplierOrder') . "</b><br>\n";
1895
1896
    // List of purchase order lines not up to date
1897
    $sql = "SELECT cd.rowid, cd.qty, cd.subprice, cd.remise_percent, cd.tva_tx as vatrate, cd.info_bits,";
1898
    $sql .= " c.rowid as commandeid, c.remise_percent as remise_percent_global";
1899
    $sql .= " FROM " . MAIN_DB_PREFIX . "commande_fournisseurdet as cd, " . MAIN_DB_PREFIX . "commande_fournisseur as c";
1900
    $sql .= " WHERE cd.fk_commande = c.rowid";
1901
    $sql .= " AND ((cd.total_ttc = 0 AND cd.remise_percent != 100) or cd.total_ttc IS NULL)";
1902
1903
    dolibarr_install_syslog("upgrade2::migrate_price_commande_fournisseur");
1904
    $resql = $db->query($sql);
1905
    if ($resql) {
1906
        $num = $db->num_rows($resql);
1907
        $i = 0;
1908
        if ($num) {
1909
            while ($i < $num) {
1910
                $obj = $db->fetch_object($resql);
1911
1912
                $rowid = $obj->rowid;
1913
                $qty = $obj->qty;
1914
                $pu = $obj->subprice;
1915
                $vatrate = $obj->vatrate;
1916
                $remise_percent = $obj->remise_percent;
1917
                $remise_percent_global = $obj->remise_percent_global;
1918
                $info_bits = $obj->info_bits;
1919
1920
                // On met a jour les 3 nouveaux champs
1921
                $commandeligne = new CommandeFournisseurLigne($db);
1922
                $commandeligne->fetch($rowid);
1923
1924
                $result = calcul_price_total($qty, $pu, $remise_percent, $vatrate, 0, 0, $remise_percent_global, 'HT', $info_bits, $commandeligne->product_type, $mysoc);
1925
                $total_ht = $result[0];
1926
                $total_tva = $result[1];
1927
                $total_ttc = $result[2];
1928
1929
                $commandeligne->total_ht = $total_ht;
1930
                $commandeligne->total_tva = $total_tva;
1931
                $commandeligne->total_ttc = $total_ttc;
1932
1933
                dolibarr_install_syslog("upgrade2: Line " . $rowid . ": commandeid=" . $obj->rowid . " pu=" . $pu . "  qty=" . $qty . " vatrate=" . $vatrate . " remise_percent=" . $remise_percent . " remise_global=" . $remise_percent_global . " -> " . $total_ht . ", " . $total_tva . ", " . $total_ttc);
1934
                print '. ';
1935
                $commandeligne->update_total();
1936
1937
                $i++;
1938
            }
1939
        } else {
1940
            print $langs->trans("AlreadyDone");
1941
        }
1942
1943
        $db->free($resql);
1944
1945
        /*
1946
         $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet";
1947
         $sql.= " WHERE subprice = 0 and total_ttc = 0 and total_tva = 0 and total_ht = 0";
1948
         $resql=$db->query($sql);
1949
         if (! $resql)
1950
         {
1951
         dol_print_error($db);
1952
         }
1953
         */
1954
1955
        $db->commit();
1956
    } else {
1957
        print "Error #1 " . $db->error();
1958
1959
        $db->rollback();
1960
    }
1961
1962
    print '<br>';
1963
1964
    print '</td></tr>';
1965
}
1966
1967
/**
1968
 * Mise a jour des modeles selectionnes
1969
 *
1970
 * @param DoliDB $db Database handler
1971
 * @param Translate $langs Object langs
1972
 * @param Conf $conf Object conf
1973
 * @return  void
1974
 */
1975
function migrate_modeles($db, $langs, $conf)
1976
{
1977
    //print '<br>';
1978
    //print '<b>'.$langs->trans('UpdateModelsTable')."</b><br>\n";
1979
1980
    dolibarr_install_syslog("upgrade2::migrate_modeles");
1981
1982
    if (isModEnabled('invoice')) {
1983
        $modellist = ModelePDFFactures::liste_modeles($db);
1984
        if (count($modellist) == 0) {
1985
            // Aucun model par default.
1986
            $sql = " INSERT INTO " . MAIN_DB_PREFIX . "document_model(nom,type) values('crabe','invoice')";
1987
            $resql = $db->query($sql);
1988
            if (!$resql) {
1989
                dol_print_error($db);
1990
            }
1991
        }
1992
    }
1993
1994
    if (isModEnabled('order')) {
1995
        $modellist = ModelePDFCommandes::liste_modeles($db);
1996
        if (count($modellist) == 0) {
1997
            // Aucun model par default.
1998
            $sql = " INSERT INTO " . MAIN_DB_PREFIX . "document_model(nom,type) values('einstein','order')";
1999
            $resql = $db->query($sql);
2000
            if (!$resql) {
2001
                dol_print_error($db);
2002
            }
2003
        }
2004
    }
2005
2006
    if (isModEnabled("shipping")) {
2007
        $modellist = ModelePdfExpedition::liste_modeles($db);
2008
        if (count($modellist) == 0) {
2009
            // Aucun model par default.
2010
            $sql = " INSERT INTO " . MAIN_DB_PREFIX . "document_model(nom,type) values('rouget','shipping')";
2011
            $resql = $db->query($sql);
2012
            if (!$resql) {
2013
                dol_print_error($db);
2014
            }
2015
        }
2016
    }
2017
2018
    //print $langs->trans("AlreadyDone");
2019
}
2020
2021
2022
/**
2023
 * Correspondence des expeditions et des commandes clients dans la table llx_co_exp
2024
 *
2025
 * @param DoliDB $db Database handler
2026
 * @param Translate $langs Object langs
2027
 * @param Conf $conf Object conf
2028
 * @return  void
2029
 */
2030
function migrate_commande_expedition($db, $langs, $conf)
2031
{
2032
    dolibarr_install_syslog("upgrade2::migrate_commande_expedition");
2033
2034
    print '<tr><td colspan="4">';
2035
2036
    print '<br>';
2037
    print '<b>' . $langs->trans('MigrationShipmentOrderMatching') . "</b><br>\n";
2038
2039
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "expedition", "fk_commande");
2040
    $obj = $db->fetch_object($result);
2041
    if ($obj) {
2042
        $error = 0;
2043
2044
        $db->begin();
2045
2046
        $sql = "SELECT e.rowid, e.fk_commande FROM " . MAIN_DB_PREFIX . "expedition as e";
2047
        $resql = $db->query($sql);
2048
        if ($resql) {
2049
            $i = 0;
2050
            $num = $db->num_rows($resql);
2051
2052
            if ($num) {
2053
                while ($i < $num) {
2054
                    $obj = $db->fetch_object($resql);
2055
2056
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "co_exp (fk_expedition,fk_commande)";
2057
                    $sql .= " VALUES (" . ((int)$obj->rowid) . ", " . ((int)$obj->fk_commande) . ")";
2058
                    $resql2 = $db->query($sql);
2059
2060
                    if (!$resql2) {
2061
                        $error++;
2062
                        dol_print_error($db);
2063
                    }
2064
                    print '. ';
2065
                    $i++;
2066
                }
2067
            }
2068
2069
            if ($error == 0) {
2070
                $db->commit();
2071
                $sql = "ALTER TABLE " . MAIN_DB_PREFIX . "expedition DROP COLUMN fk_commande";
2072
                print $langs->trans('FieldRenamed') . "<br>\n";
2073
                $db->query($sql);
2074
            } else {
2075
                $db->rollback();
2076
            }
2077
        } else {
2078
            dol_print_error($db);
2079
            $db->rollback();
2080
        }
2081
    } else {
2082
        print $langs->trans('AlreadyDone') . "<br>\n";
2083
    }
2084
    print '</td></tr>';
2085
}
2086
2087
/**
2088
 * Correspondence des livraisons et des commandes clients dans la table llx_co_liv
2089
 *
2090
 * @param DoliDB $db Database handler
2091
 * @param Translate $langs Object langs
2092
 * @param Conf $conf Object conf
2093
 * @return  void
2094
 */
2095
function migrate_commande_livraison($db, $langs, $conf)
2096
{
2097
    dolibarr_install_syslog("upgrade2::migrate_commande_livraison");
2098
2099
    print '<tr><td colspan="4">';
2100
2101
    print '<br>';
2102
    print '<b>' . $langs->trans('MigrationDeliveryOrderMatching') . "</b><br>\n";
2103
2104
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "livraison", "fk_commande");
2105
    $obj = $db->fetch_object($result);
2106
    if ($obj) {
2107
        $error = 0;
2108
2109
        $db->begin();
2110
2111
        $sql = "SELECT l.rowid, l.fk_commande,";
2112
        $sql .= " c.ref_client, c.date_livraison as delivery_date";
2113
        $sql .= " FROM " . MAIN_DB_PREFIX . "livraison as l, " . MAIN_DB_PREFIX . "commande as c";
2114
        $sql .= " WHERE c.rowid = l.fk_commande";
2115
        $resql = $db->query($sql);
2116
        if ($resql) {
2117
            $i = 0;
2118
            $num = $db->num_rows($resql);
2119
2120
            if ($num) {
2121
                while ($i < $num) {
2122
                    $obj = $db->fetch_object($resql);
2123
2124
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "co_liv (fk_livraison,fk_commande)";
2125
                    $sql .= " VALUES (" . ((int)$obj->rowid) . ", " . ((int)$obj->fk_commande) . ")";
2126
                    $resql2 = $db->query($sql);
2127
2128
                    if ($resql2) {
2129
                        $delivery_date = $db->jdate($obj->delivery_date);
2130
2131
                        $sqlu = "UPDATE " . MAIN_DB_PREFIX . "livraison SET";
2132
                        $sqlu .= " ref_client = '" . $db->escape($obj->ref_client) . "'";
2133
                        $sqlu .= ", date_livraison = '" . $db->idate($delivery_date) . "'";
2134
                        $sqlu .= " WHERE rowid = " . ((int)$obj->rowid);
2135
                        $resql3 = $db->query($sqlu);
2136
                        if (!$resql3) {
2137
                            $error++;
2138
                            dol_print_error($db);
2139
                        }
2140
                    } else {
2141
                        $error++;
2142
                        dol_print_error($db);
2143
                    }
2144
                    print '. ';
2145
                    $i++;
2146
                }
2147
            }
2148
2149
            if ($error == 0) {
2150
                $db->commit();
2151
                $sql = "ALTER TABLE " . MAIN_DB_PREFIX . "livraison DROP COLUMN fk_commande";
2152
                print $langs->trans('FieldRenamed') . "<br>\n";
2153
                $db->query($sql);
2154
            } else {
2155
                $db->rollback();
2156
            }
2157
        } else {
2158
            dol_print_error($db);
2159
            $db->rollback();
2160
        }
2161
    } else {
2162
        print $langs->trans('AlreadyDone') . "<br>\n";
2163
    }
2164
    print '</td></tr>';
2165
}
2166
2167
/**
2168
 * Migration des details commandes dans les details livraisons
2169
 *
2170
 * @param DoliDB $db Database handler
2171
 * @param Translate $langs Object langs
2172
 * @param Conf $conf Object conf
2173
 * @return  void
2174
 */
2175
function migrate_detail_livraison($db, $langs, $conf)
2176
{
2177
    dolibarr_install_syslog("upgrade2::migrate_detail_livraison");
2178
2179
    print '<tr><td colspan="4">';
2180
2181
    print '<br>';
2182
    print '<b>' . $langs->trans('MigrationDeliveryDetail') . "</b><br>\n";
2183
2184
    // This is done if field fk_commande_ligne exists.
2185
    // If not this means migration was already done.
2186
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "livraisondet", "fk_commande_ligne");
2187
    $obj = $db->fetch_object($result);
2188
    if ($obj) {
2189
        $error = 0;
2190
2191
        $db->begin();
2192
2193
        $sql = "SELECT cd.rowid, cd.fk_product, cd.description, cd.subprice, cd.total_ht";
2194
        $sql .= ", ld.fk_livraison";
2195
        $sql .= " FROM " . MAIN_DB_PREFIX . "commandedet as cd, " . MAIN_DB_PREFIX . "livraisondet as ld";
2196
        $sql .= " WHERE ld.fk_commande_ligne = cd.rowid";
2197
        $resql = $db->query($sql);
2198
        if ($resql) {
2199
            $i = 0;
2200
            $num = $db->num_rows($resql);
2201
2202
            if ($num) {
2203
                while ($i < $num) {
2204
                    $obj = $db->fetch_object($resql);
2205
2206
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "livraisondet SET";
2207
                    $sql .= " fk_product = " . ((int)$obj->fk_product);
2208
                    $sql .= ",description = '" . $db->escape($obj->description) . "'";
2209
                    $sql .= ",subprice = " . price2num($obj->subprice);
2210
                    $sql .= ",total_ht = " . price2num($obj->total_ht);
2211
                    $sql .= " WHERE fk_commande_ligne = " . ((int)$obj->rowid);
2212
                    $resql2 = $db->query($sql);
2213
2214
                    if ($resql2) {
2215
                        $sql = "SELECT total_ht";
2216
                        $sql .= " FROM " . MAIN_DB_PREFIX . "livraison";
2217
                        $sql .= " WHERE rowid = " . ((int)$obj->fk_livraison);
2218
                        $resql3 = $db->query($sql);
2219
2220
                        if ($resql3) {
2221
                            $obju = $db->fetch_object($resql3);
2222
                            $total_ht = $obju->total_ht + $obj->total_ht;
2223
2224
                            $sqlu = "UPDATE " . MAIN_DB_PREFIX . "livraison SET";
2225
                            $sqlu .= " total_ht = " . price2num($total_ht, 'MT');
2226
                            $sqlu .= " WHERE rowid = " . ((int)$obj->fk_livraison);
2227
                            $resql4 = $db->query($sqlu);
2228
                            if (!$resql4) {
2229
                                $error++;
2230
                                dol_print_error($db);
2231
                            }
2232
                        } else {
2233
                            $error++;
2234
                            dol_print_error($db);
2235
                        }
2236
                    } else {
2237
                        $error++;
2238
                        dol_print_error($db);
2239
                    }
2240
                    print '. ';
2241
                    $i++;
2242
                }
2243
            }
2244
2245
            if ($error == 0) {
2246
                $db->commit();
2247
                $sql = "ALTER TABLE " . MAIN_DB_PREFIX . "livraisondet CHANGE fk_commande_ligne fk_origin_line integer";
2248
                print $langs->trans('FieldRenamed') . "<br>\n";
2249
                $db->query($sql);
2250
            } else {
2251
                $db->rollback();
2252
            }
2253
        } else {
2254
            dol_print_error($db);
2255
            $db->rollback();
2256
        }
2257
    } else {
2258
        $result = $db->DDLDescTable(MAIN_DB_PREFIX . "livraisondet", "fk_origin_line");
2259
        $obj = $db->fetch_object($result);
2260
        if (!$obj) {
2261
            $sql = "ALTER TABLE " . MAIN_DB_PREFIX . "livraisondet ADD COLUMN fk_origin_line integer after fk_livraison";
2262
            $db->query($sql);
2263
        }
2264
        print $langs->trans('AlreadyDone') . "<br>\n";
2265
    }
2266
    print '</td></tr>';
2267
}
2268
2269
/**
2270
 * Migration du champ stock dans produits
2271
 *
2272
 * @param DoliDB $db Database handler
2273
 * @param Translate $langs Object langs
2274
 * @param Conf $conf Object conf
2275
 * @return  void
2276
 */
2277
function migrate_stocks($db, $langs, $conf)
2278
{
2279
    dolibarr_install_syslog("upgrade2::migrate_stocks");
2280
2281
    print '<tr><td colspan="4">';
2282
2283
    print '<br>';
2284
    print '<b>' . $langs->trans('MigrationStockDetail') . "</b><br>\n";
2285
2286
    $error = 0;
2287
2288
    $db->begin();
2289
2290
    $sql = "SELECT SUM(reel) as total, fk_product";
2291
    $sql .= " FROM " . MAIN_DB_PREFIX . "product_stock as ps";
2292
    $sql .= " GROUP BY fk_product";
2293
    $resql = $db->query($sql);
2294
    if ($resql) {
2295
        $i = 0;
2296
        $num = $db->num_rows($resql);
2297
2298
        if ($num) {
2299
            while ($i < $num) {
2300
                $obj = $db->fetch_object($resql);
2301
2302
                $sql = "UPDATE " . MAIN_DB_PREFIX . "product SET";
2303
                $sql .= " stock = " . price2num($obj->total, 'MS');
2304
                $sql .= " WHERE rowid = " . ((int)$obj->fk_product);
2305
2306
                $resql2 = $db->query($sql);
2307
                if ($resql2) {
2308
                } else {
2309
                    $error++;
2310
                    dol_print_error($db);
2311
                }
2312
                print '. ';
2313
                $i++;
2314
            }
2315
        }
2316
2317
        if ($error == 0) {
2318
            $db->commit();
2319
        } else {
2320
            $db->rollback();
2321
        }
2322
    } else {
2323
        dol_print_error($db);
2324
        $db->rollback();
2325
    }
2326
2327
    print '</td></tr>';
2328
}
2329
2330
/**
2331
 * Migration of menus (use only 1 table instead of 3)
2332
 * 2.6 -> 2.7
2333
 *
2334
 * @param DoliDB $db Database handler
2335
 * @param Translate $langs Object langs
2336
 * @param Conf $conf Object conf
2337
 * @return  void
2338
 */
2339
function migrate_menus($db, $langs, $conf)
2340
{
2341
    dolibarr_install_syslog("upgrade2::migrate_menus");
2342
2343
    print '<tr><td colspan="4">';
2344
2345
    print '<br>';
2346
    print '<b>' . $langs->trans('MigrationMenusDetail') . "</b><br>\n";
2347
2348
    $error = 0;
2349
2350
    if ($db->DDLInfoTable(MAIN_DB_PREFIX . "menu_constraint")) {
2351
        $db->begin();
2352
2353
        $sql = "SELECT m.rowid, mc.action";
2354
        $sql .= " FROM " . MAIN_DB_PREFIX . "menu_constraint as mc, " . MAIN_DB_PREFIX . "menu_const as md, " . MAIN_DB_PREFIX . "menu as m";
2355
        $sql .= " WHERE md.fk_menu = m.rowid AND md.fk_constraint = mc.rowid";
2356
        $sql .= " AND m.enabled = '1'";
2357
        $resql = $db->query($sql);
2358
        if ($resql) {
2359
            $i = 0;
2360
            $num = $db->num_rows($resql);
2361
            if ($num) {
2362
                while ($i < $num) {
2363
                    $obj = $db->fetch_object($resql);
2364
2365
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "menu SET";
2366
                    $sql .= " enabled = '" . $db->escape($obj->action) . "'";
2367
                    $sql .= " WHERE rowid = " . ((int)$obj->rowid);
2368
                    $sql .= " AND enabled = '1'";
2369
2370
                    $resql2 = $db->query($sql);
2371
                    if ($resql2) {
2372
                    } else {
2373
                        $error++;
2374
                        dol_print_error($db);
2375
                    }
2376
                    print '. ';
2377
                    $i++;
2378
                }
2379
            }
2380
2381
            if ($error == 0) {
2382
                $db->commit();
2383
            } else {
2384
                $db->rollback();
2385
            }
2386
        } else {
2387
            dol_print_error($db);
2388
            $db->rollback();
2389
        }
2390
    } else {
2391
        print $langs->trans('AlreadyDone') . "<br>\n";
2392
    }
2393
2394
    print '</td></tr>';
2395
}
2396
2397
/**
2398
 * Migration du champ fk_adresse_livraison dans expedition
2399
 * 2.6 -> 2.7
2400
 *
2401
 * @param DoliDB $db Database handler
2402
 * @param Translate $langs Object langs
2403
 * @param Conf $conf Object conf
2404
 * @return  void
2405
 */
2406
function migrate_commande_deliveryaddress($db, $langs, $conf)
2407
{
2408
    dolibarr_install_syslog("upgrade2::migrate_commande_deliveryaddress");
2409
2410
    print '<tr><td colspan="4">';
2411
2412
    print '<br>';
2413
    print '<b>' . $langs->trans('MigrationDeliveryAddress') . "</b><br>\n";
2414
2415
    $error = 0;
2416
2417
    if ($db->DDLInfoTable(MAIN_DB_PREFIX . "co_exp")) {
2418
        $db->begin();
2419
2420
        $sql = "SELECT c.fk_adresse_livraison, ce.fk_expedition";
2421
        $sql .= " FROM " . MAIN_DB_PREFIX . "commande as c";
2422
        $sql .= ", " . MAIN_DB_PREFIX . "co_exp as ce";
2423
        $sql .= " WHERE c.rowid = ce.fk_commande";
2424
        $sql .= " AND c.fk_adresse_livraison IS NOT NULL AND c.fk_adresse_livraison != 0";
2425
2426
        $resql = $db->query($sql);
2427
        if ($resql) {
2428
            $i = 0;
2429
            $num = $db->num_rows($resql);
2430
2431
            if ($num) {
2432
                while ($i < $num) {
2433
                    $obj = $db->fetch_object($resql);
2434
2435
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "expedition SET";
2436
                    $sql .= " fk_adresse_livraison = '" . $db->escape($obj->fk_adresse_livraison) . "'";
2437
                    $sql .= " WHERE rowid = " . ((int)$obj->fk_expedition);
2438
2439
                    $resql2 = $db->query($sql);
2440
                    if (!$resql2) {
2441
                        $error++;
2442
                        dol_print_error($db);
2443
                    }
2444
                    print '. ';
2445
                    $i++;
2446
                }
2447
            } else {
2448
                print $langs->trans('AlreadyDone') . "<br>\n";
2449
            }
2450
2451
            if ($error == 0) {
2452
                $db->commit();
2453
            } else {
2454
                $db->rollback();
2455
            }
2456
        } else {
2457
            dol_print_error($db);
2458
            $db->rollback();
2459
        }
2460
    } else {
2461
        print $langs->trans('AlreadyDone') . "<br>\n";
2462
    }
2463
2464
    print '</td></tr>';
2465
}
2466
2467
/**
2468
 * Migration du champ fk_remise_except dans llx_facturedet doit correspondre a
2469
 * lien dans llx_societe_remise_except vers llx_facturedet
2470
 *
2471
 * @param DoliDB $db Database handler
2472
 * @param Translate $langs Object langs
2473
 * @param Conf $conf Object conf
2474
 * @return  integer             Return integer <0 if KO, 0=Bad version, >0 if OK
2475
 */
2476
function migrate_restore_missing_links($db, $langs, $conf)
2477
{
2478
    dolibarr_install_syslog("upgrade2::migrate_restore_missing_links");
2479
2480
    if (($db->type == 'mysql' || $db->type == 'mysqli')) {
2481
        if (Version::compare($db->getVersionArray(), array(4, 0)) < 0) {
2482
            dolibarr_install_syslog("upgrade2::migrate_restore_missing_links Version of database too old to make this migrate action");
2483
            return 0;
2484
        }
2485
    }
2486
    print '<tr><td colspan="4">';
2487
2488
    print '<br>';
2489
    print '<b>' . $langs->trans('MigrationFixData') . "</b> (1)<br>\n";
2490
2491
    $error = 0;
2492
2493
2494
    // Restore missing link for this cross foreign key (link 1 <=> 1). Direction 1.
2495
    $table1 = 'facturedet';
2496
    $field1 = 'fk_remise_except';
2497
    $table2 = 'societe_remise_except';
2498
    $field2 = 'fk_facture_line';
2499
2500
    $db->begin();
2501
2502
    $sql = "SELECT t1.rowid, t1." . $field1 . " as field";
2503
    $sql .= " FROM " . MAIN_DB_PREFIX . $table1 . " as t1";
2504
    $sql .= " WHERE t1." . $field1 . " IS NOT NULL AND t1." . $field1 . " NOT IN";
2505
    $sql .= " (SELECT t2.rowid FROM " . MAIN_DB_PREFIX . $table2 . " as t2";
2506
    $sql .= " WHERE t1.rowid = t2." . $field2 . ")";
2507
2508
    dolibarr_install_syslog("upgrade2::migrate_restore_missing_links DIRECTION 1");
2509
    $resql = $db->query($sql);
2510
    if ($resql) {
2511
        $i = 0;
2512
        $num = $db->num_rows($resql);
2513
2514
        if ($num) {
2515
            while ($i < $num) {
2516
                $obj = $db->fetch_object($resql);
2517
2518
                print 'Line ' . $obj->rowid . ' in ' . $table1 . ' is linked to record ' . $obj->field . ' in ' . $table2 . ' that has no link to ' . $table1 . '. We fix this.<br>';
2519
                $sql = "UPDATE " . MAIN_DB_PREFIX . $table2 . " SET";
2520
                $sql .= " " . $field2 . " = '" . $db->escape($obj->rowid) . "'";
2521
                $sql .= " WHERE rowid = " . ((int)$obj->field);
2522
2523
                $resql2 = $db->query($sql);
2524
                if (!$resql2) {
2525
                    $error++;
2526
                    dol_print_error($db);
2527
                }
2528
                //print '. ';
2529
                $i++;
2530
            }
2531
        } else {
2532
            print $langs->trans('AlreadyDone') . "<br>\n";
2533
        }
2534
2535
        if ($error == 0) {
2536
            $db->commit();
2537
        } else {
2538
            $db->rollback();
2539
        }
2540
    } else {
2541
        dol_print_error($db);
2542
        $db->rollback();
2543
    }
2544
2545
    print '</td></tr>';
2546
2547
2548
    print '<tr><td colspan="4">';
2549
2550
    print '<br>';
2551
    print '<b>' . $langs->trans('MigrationFixData') . "</b> (2)<br>\n";
2552
2553
    // Restore missing link for this cross foreign key (link 1 <=> 1). Direction 2.
2554
    $table2 = 'facturedet';
2555
    $field2 = 'fk_remise_except';
2556
    $table1 = 'societe_remise_except';
2557
    $field1 = 'fk_facture_line';
2558
2559
    $db->begin();
2560
2561
    $sql = "SELECT t1.rowid, t1." . $field1 . " as field";
2562
    $sql .= " FROM " . MAIN_DB_PREFIX . $table1 . " as t1";
2563
    $sql .= " WHERE t1." . $field1 . " IS NOT NULL AND t1." . $field1 . " NOT IN";
2564
    $sql .= " (SELECT t2.rowid FROM " . MAIN_DB_PREFIX . $table2 . " as t2";
2565
    $sql .= " WHERE t1.rowid = t2." . $field2 . ")";
2566
2567
    dolibarr_install_syslog("upgrade2::migrate_restore_missing_links DIRECTION 2");
2568
    $resql = $db->query($sql);
2569
    if ($resql) {
2570
        $i = 0;
2571
        $num = $db->num_rows($resql);
2572
2573
        if ($num) {
2574
            while ($i < $num) {
2575
                $obj = $db->fetch_object($resql);
2576
2577
                print 'Line ' . $obj->rowid . ' in ' . $table1 . ' is linked to record ' . $obj->field . ' in ' . $table2 . ' that has no link to ' . $table1 . '. We fix this.<br>';
2578
                $sql = "UPDATE " . MAIN_DB_PREFIX . $table2 . " SET";
2579
                $sql .= " " . $field2 . " = '" . $db->escape($obj->rowid) . "'";
2580
                $sql .= " WHERE rowid = " . ((int)$obj->field);
2581
2582
                $resql2 = $db->query($sql);
2583
                if (!$resql2) {
2584
                    $error++;
2585
                    dol_print_error($db);
2586
                }
2587
                //print '. ';
2588
                $i++;
2589
            }
2590
        } else {
2591
            print $langs->trans('AlreadyDone') . "<br>\n";
2592
        }
2593
2594
        if ($error == 0) {
2595
            $db->commit();
2596
        } else {
2597
            $db->rollback();
2598
        }
2599
    } else {
2600
        dol_print_error($db);
2601
        $db->rollback();
2602
    }
2603
2604
    print '</td></tr>';
2605
2606
    return ($error ? -1 : 1);
2607
}
2608
2609
/**
2610
 * Migration du champ fk_user_resp de llx_projet vers llx_element_contact
2611
 *
2612
 * @param DoliDB $db Database handler
2613
 * @param Translate $langs Object langs
2614
 * @param Conf $conf Object conf
2615
 * @return  void
2616
 */
2617
function migrate_project_user_resp($db, $langs, $conf)
2618
{
2619
    dolibarr_install_syslog("upgrade2::migrate_project_user_resp");
2620
2621
    print '<tr><td colspan="4">';
2622
2623
    print '<br>';
2624
    print '<b>' . $langs->trans('MigrationProjectUserResp') . "</b><br>\n";
2625
2626
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "projet", "fk_user_resp");
2627
    $obj = $db->fetch_object($result);
2628
    if ($obj) {
2629
        $error = 0;
2630
2631
        $db->begin();
2632
2633
        $sql = "SELECT rowid, fk_user_resp FROM " . MAIN_DB_PREFIX . "projet";
2634
        $resql = $db->query($sql);
2635
        if ($resql) {
2636
            $i = 0;
2637
            $num = $db->num_rows($resql);
2638
2639
            if ($num) {
2640
                while ($i < $num) {
2641
                    $obj = $db->fetch_object($resql);
2642
2643
                    $sql2 = "INSERT INTO " . MAIN_DB_PREFIX . "element_contact (";
2644
                    $sql2 .= "datecreate";
2645
                    $sql2 .= ", statut";
2646
                    $sql2 .= ", element_id";
2647
                    $sql2 .= ", fk_c_type_contact";
2648
                    $sql2 .= ", fk_socpeople";
2649
                    $sql2 .= ") VALUES (";
2650
                    $sql2 .= "'" . $db->idate(dol_now()) . "'";
2651
                    $sql2 .= ", '4'";
2652
                    $sql2 .= ", " . $obj->rowid;
2653
                    $sql2 .= ", '160'";
2654
                    $sql2 .= ", " . $obj->fk_user_resp;
2655
                    $sql2 .= ")";
2656
2657
                    if ($obj->fk_user_resp > 0) {
2658
                        $resql2 = $db->query($sql2);
2659
                        if (!$resql2) {
2660
                            $error++;
2661
                            dol_print_error($db);
2662
                        }
2663
                    }
2664
                    print '. ';
2665
2666
                    $i++;
2667
                }
2668
            }
2669
2670
            if ($error == 0) {
2671
                $sqlDrop = "ALTER TABLE " . MAIN_DB_PREFIX . "projet DROP COLUMN fk_user_resp";
2672
                if ($db->query($sqlDrop)) {
2673
                    $db->commit();
2674
                } else {
2675
                    $db->rollback();
2676
                }
2677
            } else {
2678
                $db->rollback();
2679
            }
2680
        } else {
2681
            dol_print_error($db);
2682
            $db->rollback();
2683
        }
2684
    } else {
2685
        print $langs->trans('AlreadyDone') . "<br>\n";
2686
    }
2687
    print '</td></tr>';
2688
}
2689
2690
/**
2691
 * Migration de la table llx_projet_task_actors vers llx_element_contact
2692
 *
2693
 * @param DoliDB $db Database handler
2694
 * @param Translate $langs Object langs
2695
 * @param Conf $conf Object conf
2696
 * @return  void
2697
 */
2698
function migrate_project_task_actors($db, $langs, $conf)
2699
{
2700
    dolibarr_install_syslog("upgrade2::migrate_project_task_actors");
2701
2702
    print '<tr><td colspan="4">';
2703
2704
    print '<br>';
2705
    print '<b>' . $langs->trans('MigrationProjectTaskActors') . "</b><br>\n";
2706
2707
    if ($db->DDLInfoTable(MAIN_DB_PREFIX . "projet_task_actors")) {
2708
        $error = 0;
2709
2710
        $db->begin();
2711
2712
        $sql = "SELECT fk_projet_task as fk_project_task, fk_user FROM " . MAIN_DB_PREFIX . "projet_task_actors";
2713
        $resql = $db->query($sql);
2714
        if ($resql) {
2715
            $i = 0;
2716
            $num = $db->num_rows($resql);
2717
2718
            if ($num) {
2719
                while ($i < $num) {
2720
                    $obj = $db->fetch_object($resql);
2721
2722
                    $sql2 = "INSERT INTO " . MAIN_DB_PREFIX . "element_contact (";
2723
                    $sql2 .= "datecreate";
2724
                    $sql2 .= ", statut";
2725
                    $sql2 .= ", element_id";
2726
                    $sql2 .= ", fk_c_type_contact";
2727
                    $sql2 .= ", fk_socpeople";
2728
                    $sql2 .= ") VALUES (";
2729
                    $sql2 .= "'" . $db->idate(dol_now()) . "'";
2730
                    $sql2 .= ", '4'";
2731
                    $sql2 .= ", " . $obj->fk_project_task;
2732
                    $sql2 .= ", '180'";
2733
                    $sql2 .= ", " . $obj->fk_user;
2734
                    $sql2 .= ")";
2735
2736
                    $resql2 = $db->query($sql2);
2737
2738
                    if (!$resql2) {
2739
                        $error++;
2740
                        dol_print_error($db);
2741
                    }
2742
                    print '. ';
2743
                    $i++;
2744
                }
2745
            }
2746
2747
            if ($error == 0) {
2748
                $sqlDrop = "DROP TABLE " . MAIN_DB_PREFIX . "projet_task_actors";
2749
                if ($db->query($sqlDrop)) {
2750
                    $db->commit();
2751
                } else {
2752
                    $db->rollback();
2753
                }
2754
            } else {
2755
                $db->rollback();
2756
            }
2757
        } else {
2758
            dol_print_error($db);
2759
            $db->rollback();
2760
        }
2761
    } else {
2762
        print $langs->trans('AlreadyDone') . "<br>\n";
2763
    }
2764
    print '</td></tr>';
2765
}
2766
2767
/**
2768
 * Migration des tables de relation
2769
 *
2770
 * @param DoliDB $db Database handler
2771
 * @param Translate $langs Object langs
2772
 * @param Conf $conf Object conf
2773
 * @param string $table Table name
2774
 * @param string $fk_source Id of element source (name of field)
2775
 * @param string $sourcetype Type of element source
2776
 * @param string $fk_target Id of element target
2777
 * @param string $targettype Type of element target
2778
 * @return  void
2779
 */
2780
function migrate_relationship_tables($db, $langs, $conf, $table, $fk_source, $sourcetype, $fk_target, $targettype)
2781
{
2782
    print '<tr><td colspan="4">';
2783
2784
    print '<br>';
2785
    print '<b>' . $langs->trans('MigrationRelationshipTables', MAIN_DB_PREFIX . $table) . "</b><br>\n";
2786
2787
    $error = 0;
2788
2789
    if ($db->DDLInfoTable(MAIN_DB_PREFIX . $table)) {
2790
        dolibarr_install_syslog("upgrade2::migrate_relationship_tables table = " . MAIN_DB_PREFIX . $table);
2791
2792
        $db->begin();
2793
2794
        $sqlSelect = "SELECT " . $fk_source . ", " . $fk_target;
2795
        $sqlSelect .= " FROM " . MAIN_DB_PREFIX . $table;
2796
2797
        $resql = $db->query($sqlSelect);
2798
        if ($resql) {
2799
            $i = 0;
2800
            $num = $db->num_rows($resql);
2801
2802
            if ($num) {
2803
                while ($i < $num) {
2804
                    $obj = $db->fetch_object($resql);
2805
2806
                    $sqlInsert = "INSERT INTO " . MAIN_DB_PREFIX . "element_element (";
2807
                    $sqlInsert .= "fk_source";
2808
                    $sqlInsert .= ", sourcetype";
2809
                    $sqlInsert .= ", fk_target";
2810
                    $sqlInsert .= ", targettype";
2811
                    $sqlInsert .= ") VALUES (";
2812
                    $sqlInsert .= $obj->$fk_source;
2813
                    $sqlInsert .= ", '" . $db->escape($sourcetype) . "'";
2814
                    $sqlInsert .= ", " . $obj->$fk_target;
2815
                    $sqlInsert .= ", '" . $db->escape($targettype) . "'";
2816
                    $sqlInsert .= ")";
2817
2818
                    $result = $db->query($sqlInsert);
2819
                    if (!$result) {
2820
                        $error++;
2821
                        dol_print_error($db);
2822
                    }
2823
                    print '. ';
2824
                    $i++;
2825
                }
2826
            } else {
2827
                print $langs->trans('AlreadyDone') . "<br>\n";
2828
            }
2829
2830
            if ($error == 0) {
2831
                $sqlDrop = "DROP TABLE " . MAIN_DB_PREFIX . $table;
2832
                if ($db->query($sqlDrop)) {
2833
                    $db->commit();
2834
                } else {
2835
                    $db->rollback();
2836
                }
2837
            } else {
2838
                $db->rollback();
2839
            }
2840
        } else {
2841
            dol_print_error($db);
2842
            $db->rollback();
2843
        }
2844
    } else {
2845
        print $langs->trans('AlreadyDone') . "<br>\n";
2846
    }
2847
2848
    print '</td></tr>';
2849
}
2850
2851
/**
2852
 * Migrate duration in seconds
2853
 *
2854
 * @param DoliDB $db Database handler
2855
 * @param Translate $langs Object langs
2856
 * @param Conf $conf Object conf
2857
 * @return  void
2858
 */
2859
function migrate_element_time($db, $langs, $conf)
2860
{
2861
    dolibarr_install_syslog("upgrade2::migrate_element_time");
2862
2863
    print '<tr><td colspan="4">';
2864
2865
    print '<br>';
2866
    print '<b>' . $langs->trans('MigrationProjectTaskTime') . "</b><br>\n";
2867
2868
    $error = 0;
2869
2870
    $db->begin();
2871
2872
    $sql = "SELECT rowid, fk_element, element_duration";
2873
    $sql .= " FROM " . MAIN_DB_PREFIX . "element_time";
2874
    $resql = $db->query($sql);
2875
    if ($resql) {
2876
        $i = 0;
2877
        $num = $db->num_rows($resql);
2878
2879
        if ($num) {
2880
            $totaltime = array();
2881
            $oldtime = 0;
2882
2883
            while ($i < $num) {
2884
                $obj = $db->fetch_object($resql);
2885
2886
                if ($obj->element_duration > 0) {
2887
                    // convert to second
2888
                    // only for int time and float time ex: 1,75 for 1h45
2889
                    list($hour, $min) = explode('.', $obj->element_duration);
2890
                    $hour = $hour * 60 * 60;
2891
                    $min = ($min / 100) * 60 * 60;
2892
                    $newtime = $hour + $min;
2893
2894
                    $sql2 = "UPDATE " . MAIN_DB_PREFIX . "element_time SET";
2895
                    $sql2 .= " element_duration = " . ((int)$newtime);
2896
                    $sql2 .= " WHERE rowid = " . ((int)$obj->rowid);
2897
2898
                    $resql2 = $db->query($sql2);
2899
                    if (!$resql2) {
2900
                        $error++;
2901
                        dol_print_error($db);
2902
                    }
2903
                    print '. ';
2904
                    $oldtime++;
2905
                    if (!empty($totaltime[$obj->fk_element])) {
2906
                        $totaltime[$obj->fk_element] += $newtime;
2907
                    } else {
2908
                        $totaltime[$obj->fk_element] = $newtime;
2909
                    }
2910
                } else {
2911
                    if (!empty($totaltime[$obj->fk_element])) {
2912
                        $totaltime[$obj->fk_element] += $obj->element_duration;
2913
                    } else {
2914
                        $totaltime[$obj->fk_element] = $obj->element_duration;
2915
                    }
2916
                }
2917
2918
                $i++;
2919
            }
2920
2921
            if ($error == 0) {
2922
                if ($oldtime > 0) {
2923
                    foreach ($totaltime as $taskid => $total_duration) {
2924
                        $sql = "UPDATE " . MAIN_DB_PREFIX . "projet_task SET";
2925
                        $sql .= " duration_effective = " . ((int)$total_duration);
2926
                        $sql .= " WHERE rowid = " . ((int)$taskid);
2927
2928
                        $resql = $db->query($sql);
2929
                        if (!$resql) {
2930
                            $error++;
2931
                            dol_print_error($db);
2932
                        }
2933
                    }
2934
                } else {
2935
                    print $langs->trans('AlreadyDone') . "<br>\n";
2936
                }
2937
            } else {
2938
                dol_print_error($db);
2939
            }
2940
        } else {
2941
            print $langs->trans('AlreadyDone') . "<br>\n";
2942
        }
2943
    } else {
2944
        dol_print_error($db);
2945
    }
2946
2947
    if ($error == 0) {
2948
        $db->commit();
2949
    } else {
2950
        $db->rollback();
2951
    }
2952
2953
    print '</td></tr>';
2954
}
2955
2956
/**
2957
 * Migrate order ref_customer and date_delivery fields to llx_expedition
2958
 *
2959
 * @param DoliDB $db Database handler
2960
 * @param Translate $langs Object langs
2961
 * @param Conf $conf Object conf
2962
 * @return  void
2963
 */
2964
function migrate_customerorder_shipping($db, $langs, $conf)
2965
{
2966
    print '<tr><td colspan="4">';
2967
2968
    print '<br>';
2969
    print '<b>' . $langs->trans('MigrationCustomerOrderShipping') . "</b><br>\n";
2970
2971
    $error = 0;
2972
2973
    $result1 = $db->DDLDescTable(MAIN_DB_PREFIX . "expedition", "ref_customer");
2974
    $result2 = $db->DDLDescTable(MAIN_DB_PREFIX . "expedition", "date_delivery");
2975
    $obj1 = $db->fetch_object($result1);
2976
    $obj2 = $db->fetch_object($result2);
2977
    if (!$obj1 && !$obj2) {
2978
        dolibarr_install_syslog("upgrade2::migrate_customerorder_shipping");
2979
2980
        $db->begin();
2981
2982
        $sqlAdd1 = "ALTER TABLE " . MAIN_DB_PREFIX . "expedition ADD COLUMN ref_customer varchar(30) AFTER entity";
2983
        $sqlAdd2 = "ALTER TABLE " . MAIN_DB_PREFIX . "expedition ADD COLUMN date_delivery date DEFAULT NULL AFTER date_expedition";
2984
2985
        if ($db->query($sqlAdd1) && $db->query($sqlAdd2)) {
2986
            $sqlSelect = "SELECT e.rowid as shipping_id, c.ref_client, c.date_livraison as delivery_date";
2987
            $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "expedition as e";
2988
            $sqlSelect .= ", " . MAIN_DB_PREFIX . "element_element as el";
2989
            $sqlSelect .= " LEFT JOIN " . MAIN_DB_PREFIX . "commande as c ON c.rowid = el.fk_source AND el.sourcetype = 'commande'";
2990
            $sqlSelect .= " WHERE e.rowid = el.fk_target";
2991
            $sqlSelect .= " AND el.targettype = 'shipping'";
2992
2993
            $resql = $db->query($sqlSelect);
2994
            if ($resql) {
2995
                $i = 0;
2996
                $num = $db->num_rows($resql);
2997
2998
                if ($num) {
2999
                    while ($i < $num) {
3000
                        $obj = $db->fetch_object($resql);
3001
3002
                        $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "expedition SET";
3003
                        $sqlUpdate .= " ref_customer = '" . $db->escape($obj->ref_client) . "'";
3004
                        $sqlUpdate .= ", date_delivery = '" . $db->escape($obj->delivery_date ? $obj->delivery_date : 'null') . "'";
3005
                        $sqlUpdate .= " WHERE rowid = " . ((int)$obj->shipping_id);
3006
3007
                        $result = $db->query($sqlUpdate);
3008
                        if (!$result) {
3009
                            $error++;
3010
                            dol_print_error($db);
3011
                        }
3012
                        print '. ';
3013
                        $i++;
3014
                    }
3015
                } else {
3016
                    print $langs->trans('AlreadyDone') . "<br>\n";
3017
                }
3018
3019
                if ($error == 0) {
3020
                    $db->commit();
3021
                } else {
3022
                    dol_print_error($db);
3023
                    $db->rollback();
3024
                }
3025
            } else {
3026
                dol_print_error($db);
3027
                $db->rollback();
3028
            }
3029
        } else {
3030
            dol_print_error($db);
3031
            $db->rollback();
3032
        }
3033
    } else {
3034
        print $langs->trans('AlreadyDone') . "<br>\n";
3035
    }
3036
3037
    print '</td></tr>';
3038
}
3039
3040
/**
3041
 * Migrate link stored into fk_expedition into llx_element_element
3042
 *
3043
 * @param DoliDB $db Database handler
3044
 * @param Translate $langs Object langs
3045
 * @param Conf $conf Object conf
3046
 * @return  void
3047
 */
3048
function migrate_shipping_delivery($db, $langs, $conf)
3049
{
3050
    print '<tr><td colspan="4">';
3051
3052
    print '<br>';
3053
    print '<b>' . $langs->trans('MigrationShippingDelivery') . "</b><br>\n";
3054
3055
    $error = 0;
3056
3057
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "livraison", "fk_expedition");
3058
    $obj = $db->fetch_object($result);
3059
    if ($obj) {
3060
        dolibarr_install_syslog("upgrade2::migrate_shipping_delivery");
3061
3062
        $db->begin();
3063
3064
        $sqlSelect = "SELECT rowid, fk_expedition";
3065
        $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "livraison";
3066
        $sqlSelect .= " WHERE fk_expedition is not null";
3067
3068
        $resql = $db->query($sqlSelect);
3069
        if ($resql) {
3070
            $i = 0;
3071
            $num = $db->num_rows($resql);
3072
3073
            if ($num) {
3074
                while ($i < $num) {
3075
                    $obj = $db->fetch_object($resql);
3076
3077
                    $sqlInsert = "INSERT INTO " . MAIN_DB_PREFIX . "element_element (";
3078
                    $sqlInsert .= "fk_source";
3079
                    $sqlInsert .= ", sourcetype";
3080
                    $sqlInsert .= ", fk_target";
3081
                    $sqlInsert .= ", targettype";
3082
                    $sqlInsert .= ") VALUES (";
3083
                    $sqlInsert .= $obj->fk_expedition;
3084
                    $sqlInsert .= ", 'shipping'";
3085
                    $sqlInsert .= ", " . $obj->rowid;
3086
                    $sqlInsert .= ", 'delivery'";
3087
                    $sqlInsert .= ")";
3088
3089
                    $result = $db->query($sqlInsert);
3090
                    if ($result) {
3091
                        $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "livraison SET fk_expedition = NULL";
3092
                        $sqlUpdate .= " WHERE rowid = " . ((int)$obj->rowid);
3093
3094
                        $result = $db->query($sqlUpdate);
3095
                        if (!$result) {
3096
                            $error++;
3097
                            dol_print_error($db);
3098
                        }
3099
                        print '. ';
3100
                    } else {
3101
                        $error++;
3102
                        dol_print_error($db);
3103
                    }
3104
                    $i++;
3105
                }
3106
            } else {
3107
                print $langs->trans('AlreadyDone') . "<br>\n";
3108
            }
3109
3110
            if ($error == 0) {
3111
                $sqlDelete = "DELETE FROM " . MAIN_DB_PREFIX . "element_element WHERE sourcetype = 'commande' AND targettype = 'delivery'";
3112
                $db->query($sqlDelete);
3113
3114
                $db->commit();
3115
3116
                // DDL commands must not be inside a transaction
3117
                $sqlDrop = "ALTER TABLE " . MAIN_DB_PREFIX . "livraison DROP COLUMN fk_expedition";
3118
                $db->query($sqlDrop);
3119
            } else {
3120
                dol_print_error($db);
3121
                $db->rollback();
3122
            }
3123
        } else {
3124
            dol_print_error($db);
3125
            $db->rollback();
3126
        }
3127
    } else {
3128
        print $langs->trans('AlreadyDone') . "<br>\n";
3129
    }
3130
3131
    print '</td></tr>';
3132
}
3133
3134
/**
3135
 * We try to complete field ref_customer and date_delivery that are empty into llx_livraison.
3136
 * We set them with value from llx_expedition.
3137
 *
3138
 * @param DoliDB $db Database handler
3139
 * @param Translate $langs Object langs
3140
 * @param Conf $conf Object conf
3141
 * @return  void
3142
 */
3143
function migrate_shipping_delivery2($db, $langs, $conf)
3144
{
3145
    print '<tr><td colspan="4">';
3146
3147
    print '<br>';
3148
    print '<b>' . $langs->trans('MigrationShippingDelivery2') . "</b><br>\n";
3149
3150
    $error = 0;
3151
3152
    dolibarr_install_syslog("upgrade2::migrate_shipping_delivery2");
3153
3154
    $db->begin();
3155
3156
    $sqlSelect = "SELECT l.rowid as delivery_id, e.ref_customer, e.date_delivery";
3157
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "livraison as l,";
3158
    $sqlSelect .= " " . MAIN_DB_PREFIX . "element_element as el,";
3159
    $sqlSelect .= " " . MAIN_DB_PREFIX . "expedition as e";
3160
    $sqlSelect .= " WHERE l.rowid = el.fk_target";
3161
    $sqlSelect .= " AND el.targettype = 'delivery'";
3162
    $sqlSelect .= " AND e.rowid = el.fk_source AND el.sourcetype = 'shipping'";
3163
    $sqlSelect .= " AND (e.ref_customer IS NOT NULL OR e.date_delivery IS NOT NULL)"; // Useless to process this record if both are null
3164
    // Add condition to know if we never migrate this record
3165
    $sqlSelect .= " AND (l.ref_customer IS NULL" . ($db->type != 'pgsql' ? " or l.ref_customer = ''" : "") . ")";
3166
    $sqlSelect .= " AND (l.date_delivery IS NULL" . ($db->type != 'pgsql' ? " or l.date_delivery = ''" : "") . ")";
3167
3168
    $resql = $db->query($sqlSelect);
3169
    if ($resql) {
3170
        $i = 0;
3171
        $num = $db->num_rows($resql);
3172
3173
        if ($num) {
3174
            while ($i < $num) {
3175
                $obj = $db->fetch_object($resql);
3176
3177
                $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "livraison SET";
3178
                $sqlUpdate .= " ref_customer = '" . $db->escape($obj->ref_customer) . "',";
3179
                $sqlUpdate .= " date_delivery = " . ($obj->date_delivery ? "'" . $db->escape($obj->date_delivery) . "'" : 'null');
3180
                $sqlUpdate .= " WHERE rowid = " . ((int)$obj->delivery_id);
3181
3182
                $result = $db->query($sqlUpdate);
3183
                if (!$result) {
3184
                    $error++;
3185
                    dol_print_error($db);
3186
                }
3187
                print '. ';
3188
                $i++;
3189
            }
3190
        } else {
3191
            print $langs->trans('AlreadyDone') . "<br>\n";
3192
        }
3193
3194
        if ($error == 0) {
3195
            $db->commit();
3196
        } else {
3197
            dol_print_error($db);
3198
            $db->rollback();
3199
        }
3200
    } else {
3201
        dol_print_error($db);
3202
        $db->rollback();
3203
    }
3204
3205
    print '</td></tr>';
3206
}
3207
3208
/**
3209
 * Migrate link stored into fk_xxxx into fk_element and elementtype
3210
 *
3211
 * @param DoliDB $db Database handler
3212
 * @param Translate $langs Object langs
3213
 * @param Conf $conf Object conf
3214
 * @return  void
3215
 */
3216
function migrate_actioncomm_element($db, $langs, $conf)
3217
{
3218
    print '<tr><td colspan="4">';
3219
3220
    print '<br>';
3221
    print '<b>' . $langs->trans('MigrationActioncommElement') . "</b><br>\n";
3222
3223
    $elements = array(
3224
        'propal' => 'propalrowid',
3225
        'order' => 'fk_commande',
3226
        'invoice' => 'fk_facture',
3227
        'contract' => 'fk_contract',
3228
        'order_supplier' => 'fk_supplier_order',
3229
        'invoice_supplier' => 'fk_supplier_invoice'
3230
    );
3231
3232
    foreach ($elements as $type => $field) {
3233
        $result = $db->DDLDescTable(MAIN_DB_PREFIX . "actioncomm", $field);
3234
        $obj = $db->fetch_object($result);
3235
        if ($obj) {
3236
            dolibarr_install_syslog("upgrade2::migrate_actioncomm_element field=" . $field);
3237
3238
            $db->begin();
3239
3240
            $sql = "UPDATE " . MAIN_DB_PREFIX . "actioncomm SET ";
3241
            $sql .= "fk_element = " . $field . ", elementtype = '" . $db->escape($type) . "'";
3242
            $sql .= " WHERE " . $field . " IS NOT NULL";
3243
            $sql .= " AND fk_element IS NULL";
3244
            $sql .= " AND elementtype IS NULL";
3245
3246
            $resql = $db->query($sql);
3247
            if ($resql) {
3248
                $db->commit();
3249
3250
                // DDL commands must not be inside a transaction
3251
                // We will drop at next version because a migrate should be runnable several times if it fails.
3252
                //$sqlDrop = "ALTER TABLE ".MAIN_DB_PREFIX."actioncomm DROP COLUMN ".$field;
3253
                //$db->query($sqlDrop);
3254
                //print '. ';
3255
            } else {
3256
                dol_print_error($db);
3257
                $db->rollback();
3258
            }
3259
        } else {
3260
            print $langs->trans('AlreadyDone') . "<br>\n";
3261
        }
3262
    }
3263
3264
    print '</td></tr>';
3265
}
3266
3267
/**
3268
 * Migrate link stored into fk_mode_reglement
3269
 *
3270
 * @param DoliDB $db Database handler
3271
 * @param Translate $langs Object langs
3272
 * @param Conf $conf Object conf
3273
 * @return  void
3274
 */
3275
function migrate_mode_reglement($db, $langs, $conf)
3276
{
3277
    print '<tr><td colspan="4">';
3278
3279
    print '<br>';
3280
    print '<b>' . $langs->trans('MigrationPaymentMode') . "</b><br>\n";
3281
3282
    $elements = array(
3283
        'old_id' => array(5, 8, 9, 10, 11),
3284
        'new_id' => array(50, 51, 52, 53, 54),
3285
        'code' => array('VAD', 'TRA', 'LCR', 'FAC', 'PRO'),
3286
        'tables' => array('commande_fournisseur', 'commande', 'facture_rec', 'facture', 'propal')
3287
    );
3288
    $count = 0;
3289
3290
    foreach ($elements['old_id'] as $key => $old_id) {
3291
        $error = 0;
3292
3293
        dolibarr_install_syslog("upgrade2::migrate_mode_reglement code=" . $elements['code'][$key]);
3294
3295
        $sqlSelect = "SELECT id";
3296
        $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "c_paiement";
3297
        $sqlSelect .= " WHERE id = " . ((int)$old_id);
3298
        $sqlSelect .= " AND code = '" . $db->escape($elements['code'][$key]) . "'";
3299
3300
        $resql = $db->query($sqlSelect);
3301
        if ($resql) {
3302
            $num = $db->num_rows($resql);
3303
            if ($num) {
3304
                $count++;
3305
3306
                $db->begin();
3307
3308
                $sqla = "UPDATE " . MAIN_DB_PREFIX . "paiement SET";
3309
                $sqla .= " fk_paiement = " . ((int)$elements['new_id'][$key]);
3310
                $sqla .= " WHERE fk_paiement = " . ((int)$old_id);
3311
                $sqla .= " AND fk_paiement IN (SELECT id FROM " . MAIN_DB_PREFIX . "c_paiement WHERE id = " . ((int)$old_id) . " AND code = '" . $db->escape($elements['code'][$key]) . "')";
3312
                $resqla = $db->query($sqla);
3313
3314
                $sql = "UPDATE " . MAIN_DB_PREFIX . "c_paiement SET";
3315
                $sql .= " id = " . ((int)$elements['new_id'][$key]);
3316
                $sql .= " WHERE id = " . ((int)$old_id);
3317
                $sql .= " AND code = '" . $db->escape($elements['code'][$key]) . "'";
3318
                $resql = $db->query($sql);
3319
3320
                if ($resqla && $resql) {
3321
                    foreach ($elements['tables'] as $table) {
3322
                        $sql = "UPDATE " . MAIN_DB_PREFIX . $table . " SET ";
3323
                        $sql .= "fk_mode_reglement = " . ((int)$elements['new_id'][$key]);
3324
                        $sql .= " WHERE fk_mode_reglement = " . ((int)$old_id);
3325
3326
                        $resql = $db->query($sql);
3327
                        if (!$resql) {
3328
                            dol_print_error($db);
3329
                            $error++;
3330
                        }
3331
                        print '. ';
3332
                    }
3333
3334
                    if (!$error) {
3335
                        $db->commit();
3336
                    } else {
3337
                        dol_print_error($db);
3338
                        $db->rollback();
3339
                    }
3340
                } else {
3341
                    dol_print_error($db);
3342
                    $db->rollback();
3343
                }
3344
            }
3345
        }
3346
    }
3347
3348
    if ($count == 0) {
3349
        print $langs->trans('AlreadyDone') . "<br>\n";
3350
    }
3351
3352
3353
    print '</td></tr>';
3354
}
3355
3356
3357
/**
3358
 * Delete duplicates in table categorie_association
3359
 *
3360
 * @param DoliDB $db Database handler
3361
 * @param Translate $langs Object langs
3362
 * @param Conf $conf Object conf
3363
 * @return  void
3364
 */
3365
function migrate_clean_association($db, $langs, $conf)
3366
{
3367
    $result = $db->DDLDescTable(MAIN_DB_PREFIX . "categorie_association");
3368
    if ($result) {  // result defined for version 3.2 or -
3369
        $obj = $db->fetch_object($result);
3370
        if ($obj) { // It table categorie_association exists
3371
            $couples = array();
3372
            $children = array();
3373
            $sql = "SELECT fk_categorie_mere, fk_categorie_fille";
3374
            $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_association";
3375
            dolibarr_install_syslog("upgrade: search duplicate");
3376
            $resql = $db->query($sql);
3377
            if ($resql) {
3378
                $num = $db->num_rows($resql);
3379
                while ($obj = $db->fetch_object($resql)) {
3380
                    if (!isset($children[$obj->fk_categorie_fille])) {  // Only one record as child (a child has only on parent).
3381
                        if ($obj->fk_categorie_mere != $obj->fk_categorie_fille) {
3382
                            $children[$obj->fk_categorie_fille] = 1; // Set record for this child
3383
                            $couples[$obj->fk_categorie_mere . '_' . $obj->fk_categorie_fille] = array('mere' => $obj->fk_categorie_mere, 'fille' => $obj->fk_categorie_fille);
3384
                        }
3385
                    }
3386
                }
3387
3388
                dolibarr_install_syslog("upgrade: result is num=" . $num . " count(couples)=" . count($couples));
3389
3390
                // If there is duplicates couples or child with two parents
3391
                if (count($couples) > 0 && $num > count($couples)) {
3392
                    $error = 0;
3393
3394
                    $db->begin();
3395
3396
                    // We delete all
3397
                    $sql = "DELETE FROM " . MAIN_DB_PREFIX . "categorie_association";
3398
                    dolibarr_install_syslog("upgrade: delete association");
3399
                    $resqld = $db->query($sql);
3400
                    if ($resqld) {
3401
                        // And we insert only each record once
3402
                        foreach ($couples as $key => $val) {
3403
                            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "categorie_association(fk_categorie_mere,fk_categorie_fille)";
3404
                            $sql .= " VALUES(" . ((int)$val['mere']) . ", " . ((int)$val['fille']) . ")";
3405
                            dolibarr_install_syslog("upgrade: insert association");
3406
                            $resqli = $db->query($sql);
3407
                            if (!$resqli) {
3408
                                $error++;
3409
                            }
3410
                        }
3411
                    }
3412
3413
                    if (!$error) {
3414
                        print '<tr><td>' . $langs->trans("MigrationCategorieAssociation") . '</td>';
3415
                        print '<td class="right">' . $langs->trans("RemoveDuplicates") . ' ' . $langs->trans("Success") . ' (' . $num . '=>' . count($couples) . ')</td></tr>';
3416
                        $db->commit();
3417
                    } else {
3418
                        print '<tr><td>' . $langs->trans("MigrationCategorieAssociation") . '</td>';
3419
                        print '<td class="right">' . $langs->trans("RemoveDuplicates") . ' ' . $langs->trans("Failed") . '</td></tr>';
3420
                        $db->rollback();
3421
                    }
3422
                }
3423
            } else {
3424
                print '<tr><td>' . $langs->trans("Error") . '</td>';
3425
                print '<td class="right"><div class="error">' . $db->lasterror() . '</div></td></tr>';
3426
            }
3427
        }
3428
    }
3429
}
3430
3431
3432
/**
3433
 * Migrate categorie association
3434
 *
3435
 * @param DoliDB $db Database handler
3436
 * @param Translate $langs Object langs
3437
 * @param Conf $conf Object conf
3438
 * @return  void
3439
 */
3440
function migrate_categorie_association($db, $langs, $conf)
3441
{
3442
    print '<tr><td colspan="4">';
3443
3444
    print '<br>';
3445
    print '<b>' . $langs->trans('MigrationCategorieAssociation') . "</b><br>\n";
3446
3447
    $error = 0;
3448
3449
    if ($db->DDLInfoTable(MAIN_DB_PREFIX . "categorie_association")) {
3450
        dolibarr_install_syslog("upgrade2::migrate_categorie_association");
3451
3452
        $db->begin();
3453
3454
        $sqlSelect = "SELECT fk_categorie_mere, fk_categorie_fille";
3455
        $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "categorie_association";
3456
3457
        $resql = $db->query($sqlSelect);
3458
        if ($resql) {
3459
            $i = 0;
3460
            $num = $db->num_rows($resql);
3461
3462
            if ($num) {
3463
                while ($i < $num) {
3464
                    $obj = $db->fetch_object($resql);
3465
3466
                    $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "categorie SET ";
3467
                    $sqlUpdate .= "fk_parent = " . ((int)$obj->fk_categorie_mere);
3468
                    $sqlUpdate .= " WHERE rowid = " . ((int)$obj->fk_categorie_fille);
3469
3470
                    $result = $db->query($sqlUpdate);
3471
                    if (!$result) {
3472
                        $error++;
3473
                        dol_print_error($db);
3474
                    }
3475
                    print '. ';
3476
                    $i++;
3477
                }
3478
            } else {
3479
                print $langs->trans('AlreadyDone') . "<br>\n";
3480
            }
3481
3482
            if (!$error) {
3483
                $db->commit();
3484
            } else {
3485
                $db->rollback();
3486
            }
3487
        } else {
3488
            dol_print_error($db);
3489
            $db->rollback();
3490
        }
3491
    } else {
3492
        print $langs->trans('AlreadyDone') . "<br>\n";
3493
    }
3494
3495
    print '</td></tr>';
3496
}
3497
3498
/**
3499
 * Migrate event assignment to owner
3500
 *
3501
 * @param DoliDB $db Database handler
3502
 * @param Translate $langs Object langs
3503
 * @param Conf $conf Object conf
3504
 * @return  void
3505
 */
3506
function migrate_event_assignement($db, $langs, $conf)
3507
{
3508
    print '<tr><td colspan="4">';
3509
3510
    print '<br>';
3511
    print '<b>' . $langs->trans('MigrationEvents') . "</b><br>\n";
3512
3513
    $error = 0;
3514
3515
    dolibarr_install_syslog("upgrade2::migrate_event_assignement");
3516
3517
    $db->begin();
3518
3519
    $sqlSelect = "SELECT a.id, a.fk_user_action";
3520
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "actioncomm as a";
3521
    $sqlSelect .= " LEFT JOIN " . MAIN_DB_PREFIX . "actioncomm_resources as ar ON ar.fk_actioncomm = a.id AND ar.element_type = 'user' AND ar.fk_element = a.fk_user_action";
3522
    $sqlSelect .= " WHERE fk_user_action > 0 AND fk_user_action NOT IN (SELECT fk_element FROM " . MAIN_DB_PREFIX . "actioncomm_resources as ar WHERE ar.fk_actioncomm = a.id AND ar.element_type = 'user')";
3523
    $sqlSelect .= " ORDER BY a.id";
3524
    //print $sqlSelect;
3525
3526
    $resql = $db->query($sqlSelect);
3527
    if ($resql) {
3528
        $i = 0;
3529
        $num = $db->num_rows($resql);
3530
3531
        if ($num) {
3532
            while ($i < $num) {
3533
                $obj = $db->fetch_object($resql);
3534
3535
                $sqlUpdate = "INSERT INTO " . MAIN_DB_PREFIX . "actioncomm_resources(fk_actioncomm, element_type, fk_element) ";
3536
                $sqlUpdate .= "VALUES(" . ((int)$obj->id) . ", 'user', " . ((int)$obj->fk_user_action) . ")";
3537
3538
                $result = $db->query($sqlUpdate);
3539
                if (!$result) {
3540
                    $error++;
3541
                    dol_print_error($db);
3542
                }
3543
                print '. ';
3544
                $i++;
3545
            }
3546
        } else {
3547
            print $langs->trans('AlreadyDone') . "<br>\n";
3548
        }
3549
3550
        if (!$error) {
3551
            $db->commit();
3552
        } else {
3553
            $db->rollback();
3554
        }
3555
    } else {
3556
        dol_print_error($db);
3557
        $db->rollback();
3558
    }
3559
3560
3561
    print '</td></tr>';
3562
}
3563
3564
/**
3565
 * Migrate event assignment to owner
3566
 *
3567
 * @param DoliDB $db Database handler
3568
 * @param Translate $langs Object langs
3569
 * @param Conf $conf Object conf
3570
 * @return  void
3571
 */
3572
function migrate_event_assignement_contact($db, $langs, $conf)
3573
{
3574
    print '<tr><td colspan="4">';
3575
3576
    print '<br>';
3577
    print '<b>' . $langs->trans('MigrationEventsContact') . "</b><br>\n";
3578
3579
    $error = 0;
3580
3581
    dolibarr_install_syslog("upgrade2::migrate_event_assignement");
3582
3583
    $db->begin();
3584
3585
    $sqlSelect = "SELECT a.id, a.fk_contact";
3586
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "actioncomm as a";
3587
    $sqlSelect .= " LEFT JOIN " . MAIN_DB_PREFIX . "actioncomm_resources as ar ON ar.fk_actioncomm = a.id AND ar.element_type = 'socpeople' AND ar.fk_element = a.fk_contact";
3588
    $sqlSelect .= " WHERE fk_contact > 0 AND fk_contact NOT IN (SELECT fk_element FROM " . MAIN_DB_PREFIX . "actioncomm_resources as ar WHERE ar.fk_actioncomm = a.id AND ar.element_type = 'socpeople')";
3589
    $sqlSelect .= " ORDER BY a.id";
3590
    //print $sqlSelect;
3591
3592
    $resql = $db->query($sqlSelect);
3593
    if ($resql) {
3594
        $i = 0;
3595
        $num = $db->num_rows($resql);
3596
3597
        if ($num) {
3598
            while ($i < $num) {
3599
                $obj = $db->fetch_object($resql);
3600
3601
                $sqlUpdate = "INSERT INTO " . MAIN_DB_PREFIX . "actioncomm_resources(fk_actioncomm, element_type, fk_element) ";
3602
                $sqlUpdate .= "VALUES(" . ((int)$obj->id) . ", 'socpeople', " . ((int)$obj->fk_contact) . ")";
3603
3604
                $result = $db->query($sqlUpdate);
3605
                if (!$result) {
3606
                    $error++;
3607
                    dol_print_error($db);
3608
                }
3609
                print '. ';
3610
                $i++;
3611
            }
3612
        } else {
3613
            print $langs->trans('AlreadyDone') . "<br>\n";
3614
        }
3615
3616
        if (!$error) {
3617
            $db->commit();
3618
        } else {
3619
            $db->rollback();
3620
        }
3621
    } else {
3622
        dol_print_error($db);
3623
        $db->rollback();
3624
    }
3625
3626
3627
    print '</td></tr>';
3628
}
3629
3630
3631
/**
3632
 * Migrate to reset the blocked log for V7+ algorithm
3633
 *
3634
 * @param DoliDB $db Database handler
3635
 * @param Translate $langs Object langs
3636
 * @param Conf $conf Object conf
3637
 * @return  void
3638
 */
3639
function migrate_reset_blocked_log($db, $langs, $conf)
3640
{
3641
    global $user;
3642
3643
    print '<tr><td colspan="4">';
3644
3645
    print '<br>';
3646
    print '<b>' . $langs->trans('MigrationResetBlockedLog') . "</b><br>\n";
3647
3648
    $error = 0;
3649
3650
    dolibarr_install_syslog("upgrade2::migrate_reset_blocked_log");
3651
3652
    $db->begin();
3653
3654
    $sqlSelect = "SELECT DISTINCT entity";
3655
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "blockedlog";
3656
3657
    //print $sqlSelect;
3658
3659
    $resql = $db->query($sqlSelect);
3660
    if ($resql) {
3661
        $i = 0;
3662
        $num = $db->num_rows($resql);
3663
3664
        if ($num) {
3665
            while ($i < $num) {
3666
                $obj = $db->fetch_object($resql);
3667
3668
                print 'Process entity ' . $obj->entity;
3669
3670
                $sqlSearch = "SELECT count(rowid) as nb FROM " . MAIN_DB_PREFIX . "blockedlog WHERE action = 'MODULE_SET' and entity = " . ((int)$obj->entity);
3671
                $resqlSearch = $db->query($sqlSearch);
3672
                if ($resqlSearch) {
3673
                    $objSearch = $db->fetch_object($resqlSearch);
3674
                    //var_dump($objSearch);
3675
                    if ($objSearch && $objSearch->nb == 0) {
3676
                        print ' - Record for entity must be reset...';
3677
3678
                        $sqlUpdate = "DELETE FROM " . MAIN_DB_PREFIX . "blockedlog";
3679
                        $sqlUpdate .= " WHERE entity = " . ((int)$obj->entity);
3680
                        $resqlUpdate = $db->query($sqlUpdate);
3681
                        if (!$resqlUpdate) {
3682
                            $error++;
3683
                            dol_print_error($db);
3684
                        } else {
3685
                            // Add set line
3686
                            $object = new stdClass();
3687
                            $object->id = 1;
3688
                            $object->element = 'module';
3689
                            $object->ref = 'systemevent';
3690
                            $object->entity = $obj->entity;
3691
                            $object->date = dol_now();
3692
3693
                            $b = new BlockedLog($db);
3694
                            $b->setObjectData($object, 'MODULE_SET', 0);
3695
3696
                            $res = $b->create($user);
3697
                            if ($res <= 0) {
3698
                                $error++;
3699
                            }
3700
                        }
3701
                    } else {
3702
                        print ' - ' . $langs->trans('AlreadyInV7') . '<br>';
3703
                    }
3704
                } else {
3705
                    dol_print_error($db);
3706
                }
3707
3708
                $i++;
3709
            }
3710
        } else {
3711
            print $langs->trans('NothingToDo') . "<br>\n";
3712
        }
3713
3714
        if (!$error) {
3715
            $db->commit();
3716
        } else {
3717
            $db->rollback();
3718
        }
3719
    } else {
3720
        dol_print_error($db);
3721
        $db->rollback();
3722
    }
3723
3724
    print '</td></tr>';
3725
}
3726
3727
3728
/**
3729
 * Migrate to add entity value into llx_societe_remise
3730
 *
3731
 * @param DoliDB $db Database handler
3732
 * @param Translate $langs Object langs
3733
 * @param Conf $conf Object conf
3734
 * @return  void
3735
 */
3736
function migrate_remise_entity($db, $langs, $conf)
3737
{
3738
    print '<tr><td colspan="4">';
3739
3740
    print '<br>';
3741
    print '<b>' . $langs->trans('MigrationRemiseEntity') . "</b><br>\n";
3742
3743
    $error = 0;
3744
3745
    dolibarr_install_syslog("upgrade2::migrate_remise_entity");
3746
3747
    $db->begin();
3748
3749
    $sqlSelect = "SELECT sr.rowid, s.entity";
3750
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "societe_remise as sr, " . MAIN_DB_PREFIX . "societe as s";
3751
    $sqlSelect .= " WHERE sr.fk_soc = s.rowid and sr.entity != s.entity";
3752
3753
    //print $sqlSelect;
3754
3755
    $resql = $db->query($sqlSelect);
3756
    if ($resql) {
3757
        $i = 0;
3758
        $num = $db->num_rows($resql);
3759
3760
        if ($num) {
3761
            while ($i < $num) {
3762
                $obj = $db->fetch_object($resql);
3763
3764
                $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "societe_remise SET";
3765
                $sqlUpdate .= " entity = " . $obj->entity;
3766
                $sqlUpdate .= " WHERE rowid = " . ((int)$obj->rowid);
3767
3768
                $result = $db->query($sqlUpdate);
3769
                if (!$result) {
3770
                    $error++;
3771
                    dol_print_error($db);
3772
                }
3773
3774
                print '. ';
3775
                $i++;
3776
            }
3777
        } else {
3778
            print $langs->trans('AlreadyDone') . "<br>\n";
3779
        }
3780
3781
        if (!$error) {
3782
            $db->commit();
3783
        } else {
3784
            $db->rollback();
3785
        }
3786
    } else {
3787
        dol_print_error($db);
3788
        $db->rollback();
3789
    }
3790
3791
    print '</td></tr>';
3792
}
3793
3794
/**
3795
 * Migrate to add entity value into llx_societe_remise_except
3796
 *
3797
 * @param DoliDB $db Database handler
3798
 * @param Translate $langs Object langs
3799
 * @param Conf $conf Object conf
3800
 * @return  void
3801
 */
3802
function migrate_remise_except_entity($db, $langs, $conf)
3803
{
3804
    print '<tr><td colspan="4">';
3805
3806
    print '<br>';
3807
    print '<b>' . $langs->trans('MigrationRemiseExceptEntity') . "</b><br>\n";
3808
3809
    $error = 0;
3810
3811
    dolibarr_install_syslog("upgrade2::migrate_remise_except_entity");
3812
3813
    $db->begin();
3814
3815
    $sqlSelect = "SELECT sr.rowid, sr.fk_soc, sr.fk_facture_source, sr.fk_facture, sr.fk_facture_line";
3816
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as sr";
3817
    //print $sqlSelect;
3818
3819
    $resql = $db->query($sqlSelect);
3820
    if ($resql) {
3821
        $i = 0;
3822
        $num = $db->num_rows($resql);
3823
3824
        if ($num) {
3825
            while ($i < $num) {
3826
                $obj = $db->fetch_object($resql);
3827
3828
                if (!empty($obj->fk_facture_source) || !empty($obj->fk_facture)) {
3829
                    $fk_facture = (!empty($obj->fk_facture_source) ? $obj->fk_facture_source : $obj->fk_facture);
3830
3831
                    $sqlSelect2 = "SELECT f.entity";
3832
                    $sqlSelect2 .= " FROM " . MAIN_DB_PREFIX . "facture as f";
3833
                    $sqlSelect2 .= " WHERE f.rowid = " . ((int)$fk_facture);
3834
                } elseif (!empty($obj->fk_facture_line)) {
3835
                    $sqlSelect2 = "SELECT f.entity";
3836
                    $sqlSelect2 .= " FROM " . MAIN_DB_PREFIX . "facture as f, " . MAIN_DB_PREFIX . "facturedet as fd";
3837
                    $sqlSelect2 .= " WHERE fd.rowid = " . ((int)$obj->fk_facture_line);
3838
                    $sqlSelect2 .= " AND fd.fk_facture = f.rowid";
3839
                } else {
3840
                    $sqlSelect2 = "SELECT s.entity";
3841
                    $sqlSelect2 .= " FROM " . MAIN_DB_PREFIX . "societe as s";
3842
                    $sqlSelect2 .= " WHERE s.rowid = " . ((int)$obj->fk_soc);
3843
                }
3844
3845
                $resql2 = $db->query($sqlSelect2);
3846
                if ($resql2) {
3847
                    if ($db->num_rows($resql2) > 0) {
3848
                        $obj2 = $db->fetch_object($resql2);
3849
3850
                        $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "societe_remise_except SET";
3851
                        $sqlUpdate .= " entity = " . ((int)$obj2->entity);
3852
                        $sqlUpdate .= " WHERE rowid = " . ((int)$obj->rowid);
3853
3854
                        $result = $db->query($sqlUpdate);
3855
                        if (!$result) {
3856
                            $error++;
3857
                            dol_print_error($db);
3858
                        }
3859
                    }
3860
                } else {
3861
                    $error++;
3862
                    dol_print_error($db);
3863
                }
3864
3865
                print '. ';
3866
                $i++;
3867
            }
3868
        } else {
3869
            print $langs->trans('AlreadyDone') . "<br>\n";
3870
        }
3871
3872
        if (!$error) {
3873
            $db->commit();
3874
        } else {
3875
            $db->rollback();
3876
        }
3877
    } else {
3878
        dol_print_error($db);
3879
        $db->rollback();
3880
    }
3881
3882
3883
    print '</td></tr>';
3884
}
3885
3886
/**
3887
 * Migrate to add entity value into llx_user_rights
3888
 *
3889
 * @param DoliDB $db Database handler
3890
 * @param Translate $langs Object langs
3891
 * @param Conf $conf Object conf
3892
 * @return  void
3893
 */
3894
function migrate_user_rights_entity($db, $langs, $conf)
3895
{
3896
    print '<tr><td colspan="4">';
3897
3898
    print '<b>' . $langs->trans('MigrationUserRightsEntity') . "</b><br>\n";
3899
3900
    $error = 0;
3901
3902
    dolibarr_install_syslog("upgrade2::migrate_user_rights_entity");
3903
3904
    $db->begin();
3905
3906
    $sqlSelect = "SELECT u.rowid, u.entity";
3907
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "user as u";
3908
    $sqlSelect .= " WHERE u.entity > 1";
3909
    //print $sqlSelect;
3910
3911
    $resql = $db->query($sqlSelect);
3912
    if ($resql) {
3913
        $i = 0;
3914
        $num = $db->num_rows($resql);
3915
3916
        if ($num) {
3917
            while ($i < $num) {
3918
                $obj = $db->fetch_object($resql);
3919
3920
                $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "user_rights SET";
3921
                $sqlUpdate .= " entity = " . ((int)$obj->entity);
3922
                $sqlUpdate .= " WHERE fk_user = " . ((int)$obj->rowid);
3923
3924
                $result = $db->query($sqlUpdate);
3925
                if (!$result) {
3926
                    $error++;
3927
                    dol_print_error($db);
3928
                }
3929
3930
                print '. ';
3931
                $i++;
3932
            }
3933
        } else {
3934
            print $langs->trans('AlreadyDone') . "<br>\n";
3935
        }
3936
3937
        if (!$error) {
3938
            $db->commit();
3939
        } else {
3940
            $db->rollback();
3941
        }
3942
    } else {
3943
        dol_print_error($db);
3944
        $db->rollback();
3945
    }
3946
3947
3948
    print '</td></tr>';
3949
}
3950
3951
/**
3952
 * Migrate to add entity value into llx_usergroup_rights
3953
 *
3954
 * @param DoliDB $db Database handler
3955
 * @param Translate $langs Object langs
3956
 * @param Conf $conf Object conf
3957
 * @return  void
3958
 */
3959
function migrate_usergroup_rights_entity($db, $langs, $conf)
3960
{
3961
    print '<tr><td colspan="4">';
3962
3963
    print '<b>' . $langs->trans('MigrationUserGroupRightsEntity') . "</b><br>\n";
3964
3965
    $error = 0;
3966
3967
    dolibarr_install_syslog("upgrade2::migrate_usergroup_rights_entity");
3968
3969
    $db->begin();
3970
3971
    $sqlSelect = "SELECT u.rowid, u.entity";
3972
    $sqlSelect .= " FROM " . MAIN_DB_PREFIX . "usergroup as u";
3973
    $sqlSelect .= " WHERE u.entity > 1";
3974
    //print $sqlSelect;
3975
3976
    $resql = $db->query($sqlSelect);
3977
    if ($resql) {
3978
        $i = 0;
3979
        $num = $db->num_rows($resql);
3980
3981
        if ($num) {
3982
            while ($i < $num) {
3983
                $obj = $db->fetch_object($resql);
3984
3985
                $sqlUpdate = "UPDATE " . MAIN_DB_PREFIX . "usergroup_rights SET";
3986
                $sqlUpdate .= " entity = " . ((int)$obj->entity);
3987
                $sqlUpdate .= " WHERE fk_usergroup = " . ((int)$obj->rowid);
3988
3989
                $result = $db->query($sqlUpdate);
3990
                if (!$result) {
3991
                    $error++;
3992
                    dol_print_error($db);
3993
                }
3994
3995
                print '. ';
3996
                $i++;
3997
            }
3998
        } else {
3999
            print $langs->trans('AlreadyDone') . "<br>\n";
4000
        }
4001
4002
        if (!$error) {
4003
            $db->commit();
4004
        } else {
4005
            $db->rollback();
4006
        }
4007
    } else {
4008
        dol_print_error($db);
4009
        $db->rollback();
4010
    }
4011
4012
4013
    print '</td></tr>';
4014
}
4015
4016
/**
4017
 * Migration directory
4018
 *
4019
 * @param DoliDB $db Database handler
4020
 * @param Translate $langs Object langs
4021
 * @param Conf $conf Object conf
4022
 * @param string $oldname Old name (relative to DOL_DATA_ROOT)
4023
 * @param string $newname New name (relative to DOL_DATA_ROOT)
4024
 * @return  void
4025
 */
4026
function migrate_rename_directories($db, $langs, $conf, $oldname, $newname)
4027
{
4028
    dolibarr_install_syslog("upgrade2::migrate_rename_directories");
4029
4030
    if (is_dir(DOL_DATA_ROOT . $oldname) && !file_exists(DOL_DATA_ROOT . $newname)) {
4031
        dolibarr_install_syslog("upgrade2::migrate_rename_directories move " . DOL_DATA_ROOT . $oldname . ' into ' . DOL_DATA_ROOT . $newname);
4032
        @rename(DOL_DATA_ROOT . $oldname, DOL_DATA_ROOT . $newname);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rename(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

4032
        /** @scrutinizer ignore-unhandled */ @rename(DOL_DATA_ROOT . $oldname, DOL_DATA_ROOT . $newname);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
4033
    }
4034
}
4035
4036
4037
/**
4038
 * Delete deprecated files
4039
 *
4040
 * @param DoliDB $db Database handler
4041
 * @param Translate $langs Object langs
4042
 * @param Conf $conf Object conf
4043
 * @return  boolean
4044
 */
4045
function migrate_delete_old_files($db, $langs, $conf)
4046
{
4047
    $ret = true;
4048
4049
    dolibarr_install_syslog("upgrade2::migrate_delete_old_files");
4050
4051
    // List of files to delete
4052
    $filetodeletearray = array(
4053
        '/core/ajax/ajaxcompanies.php',
4054
        '/core/triggers/interface_demo.class.php',
4055
        '/core/menus/barre_left/default.php',
4056
        '/core/menus/barre_top/default.php',
4057
        '/core/modules/modComptabiliteExpert.class.php',
4058
        '/core/modules/modCommercial.class.php',
4059
        '/core/modules/modProduit.class.php',
4060
        '/core/modules/modSkype.class.php',
4061
        '/core/triggers/interface_modWebcalendar_Webcalsynchro.class.php',
4062
        '/core/triggers/interface_modCommande_Ecotax.class.php',
4063
        '/core/triggers/interface_modCommande_fraisport.class.php',
4064
        '/core/triggers/interface_modPropale_PropalWorkflow.class.php',
4065
        '/core/triggers/interface_99_modWebhook_WebhookTriggers.class.php',
4066
        '/core/triggers/interface_99_modZapier_ZapierTriggers.class.php',
4067
        '/core/menus/smartphone/iphone.lib.php',
4068
        '/core/menus/smartphone/iphone_backoffice.php',
4069
        '/core/menus/smartphone/iphone_frontoffice.php',
4070
        '/core/menus/standard/auguria_backoffice.php',
4071
        '/core/menus/standard/auguria_frontoffice.php',
4072
        '/core/menus/standard/eldy_backoffice.php',
4073
        '/core/menus/standard/eldy_frontoffice.php',
4074
        '/core/modules/export/export_excel.modules.php',
4075
        '/core/modules/export/export_csv.modules.php',
4076
        '/core/modules/export/exportcsv.modules.php',
4077
        '/core/modules/export/export_excel2007new.modules.php',
4078
        '/core/modules/facture/pdf_crabe.modules.php',
4079
        '/core/modules/facture/pdf_oursin.modules.php',
4080
        '/core/modules/mailings/contacts2.modules.php',
4081
        '/core/modules/mailings/contacts3.modules.php',
4082
        '/core/modules/mailings/contacts4.modules.php',
4083
        '/core/modules/mailings/framboise.modules.php',
4084
        '/core/modules/mailings/dolibarr_services_expired.modules.php',
4085
        '/core/modules/mailings/peche.modules.php',
4086
        '/core/modules/mailings/poire.modules.php',
4087
        '/core/modules/mailings/kiwi.modules.php',
4088
        '/core/boxes/box_members.php',
4089
4090
        '/includes/restler/framework/Luracast/Restler/Data/Object.php',
4091
        '/includes/nusoap/lib/class.*',
4092
        '/phenix/inc/triggers/interface_modPhenix_Phenixsynchro.class.php',
4093
        '/webcalendar/inc/triggers/interface_modWebcalendar_webcalsynchro.class.php',
4094
4095
        '/api/class/api_generic.class.php',
4096
        '/asterisk/cidlookup.php',
4097
        '/categories/class/api_category.class.php',
4098
        '/categories/class/api_deprecated_category.class.php',
4099
        '/compta/facture/class/api_invoice.class.php',
4100
        '/commande/class/api_commande.class.php',
4101
        '/partnership/class/api_partnership.class.php',
4102
        '/product/class/api_product.class.php',
4103
        '/recruitment/class/api_recruitment.class.php',
4104
        '/societe/class/api_contact.class.php',
4105
        '/societe/class/api_thirdparty.class.php',
4106
        '/support/online.php',
4107
        '/takepos/class/actions_takepos.class.php',
4108
        '/user/class/api_user.class.php',
4109
4110
        '/install/mysql/tables/llx_c_ticketsup_category.key.sql',
4111
        '/install/mysql/tables/llx_c_ticketsup_category.sql',
4112
        '/install/mysql/tables/llx_c_ticketsup_severity.key.sql',
4113
        '/install/mysql/tables/llx_c_ticketsup_severity.sql',
4114
        '/install/mysql/tables/llx_c_ticketsup_type.key.sql',
4115
        '/install/mysql/tables/llx_c_ticketsup_type.sql'
4116
    );
4117
4118
    /*
4119
    print '<tr><td colspan="4">';
4120
    print '<b>'.$langs->trans('DeleteOldFiles')."</b><br>\n";
4121
    print '</td></tr>';
4122
    */
4123
4124
    foreach ($filetodeletearray as $filetodelete) {
4125
        //print '<b>'DOL_DOCUMENT_ROOT.$filetodelete."</b><br>\n";
4126
        if (file_exists(DOL_DOCUMENT_ROOT . $filetodelete) || preg_match('/\*/', $filetodelete)) {
4127
            //print "Process file ".$filetodelete."\n";
4128
            $result = dol_delete_file(DOL_DOCUMENT_ROOT . $filetodelete, 0, 0, 0, null, true, false);
4129
            if (!$result) {
4130
                $langs->load("errors");
4131
                print '<div class="error">' . $langs->trans("Error") . ': ' . $langs->trans("ErrorFailToDeleteFile", DOL_DOCUMENT_ROOT . $filetodelete);
4132
                print ' ' . $langs->trans("RemoveItManuallyAndPressF5ToContinue") . '</div>';
4133
            } else {
4134
                //print $langs->trans("FileWasRemoved", $filetodelete).'<br>';
4135
            }
4136
        }
4137
    }
4138
4139
    return $ret;
4140
}
4141
4142
/**
4143
 * Remove deprecated directories
4144
 *
4145
 * @param DoliDB $db Database handler
4146
 * @param Translate $langs Object langs
4147
 * @param Conf $conf Object conf
4148
 * @return  boolean
4149
 */
4150
function migrate_delete_old_dir($db, $langs, $conf)
4151
{
4152
    $ret = true;
4153
4154
    dolibarr_install_syslog("upgrade2::migrate_delete_old_dir");
4155
4156
    // List of files to delete
4157
    $filetodeletearray = array(
4158
        DOL_DOCUMENT_ROOT . '/core/modules/facture/terre',
4159
        DOL_DOCUMENT_ROOT . '/core/modules/facture/mercure',
4160
    );
4161
4162
    // On linux, we can also removed old directory with a different case than new directory.
4163
    if (!empty($_SERVER["WINDIR"])) {
4164
        $filetodeletearray[] = DOL_DOCUMENT_ROOT . '/includes/phpoffice/PhpSpreadsheet';
4165
    }
4166
4167
    foreach ($filetodeletearray as $filetodelete) {
4168
        $result = 1;
4169
        if (file_exists($filetodelete)) {
4170
            $result = dol_delete_dir_recursive($filetodelete);
4171
        }
4172
        if (!$result) {
4173
            $langs->load("errors");
4174
            print '<div class="error">' . $langs->trans("Error") . ': ' . $langs->trans("ErrorFailToDeleteDir", $filetodelete);
4175
            print ' ' . $langs->trans("RemoveItManuallyAndPressF5ToContinue") . '</div>';
4176
        }
4177
    }
4178
4179
    return $ret;
4180
}
4181
4182
4183
/**
4184
 * Disable/Re-enable features modules.
4185
 * We must do this when internal menu of module or permissions has changed
4186
 * or when triggers have moved.
4187
 *
4188
 * @param DoliDB $db Database handler
4189
 * @param Translate $langs Object langs
4190
 * @param Conf $conf Object conf
4191
 * @param array $listofmodule List of modules, like array('MODULE_KEY_NAME'=>', $reloadmode)
4192
 * @param int $force 1=Reload module even if not already loaded
4193
 * @return  int                 Return integer <0 if KO, >0 if OK
4194
 */
4195
function migrate_reload_modules($db, $langs, $conf, $listofmodule = array(), $force = 0)
4196
{
4197
    global $user;
4198
4199
    if (count($listofmodule) == 0) {
4200
        return 0;
4201
    }
4202
4203
    if (!is_object($user)) {
4204
        $user = new User($db);  // To avoid error during migration
4205
    }
4206
4207
    dolibarr_install_syslog("upgrade2::migrate_reload_modules force=" . $force . ", listofmodule=" . implode(',', array_keys($listofmodule)));
4208
4209
    $reloadactionformodules = array(
4210
        'MAIN_MODULE_AGENDA' => array('class' => 'modAgenda', 'remove' => 1),
4211
        'MAIN_MODULE_API' => array('class' => 'modApi'),
4212
        'MAIN_MODULE_BARCODE' => array('class' => 'modBarcode', 'remove' => 1),
4213
        'MAIN_MODULE_BLOCKEDLOG' => array('class' => 'modBlockedLog', 'deleteinsertmenus' => 1),
4214
        'MAIN_MODULE_CRON' => array('class' => 'modCron', 'remove' => 1),
4215
        'MAIN_MODULE_EXTERNALSITE' => array('class' => 'modExternalSite', 'remove' => 1),
4216
        'MAIN_MODULE_SOCIETE' => array('class' => 'modSociete', 'remove' => 1),
4217
        'MAIN_MODULE_PRODUIT' => array('class' => 'modProduct'),
4218
        'MAIN_MODULE_SERVICE' => array('class' => 'modService'),
4219
        'MAIN_MODULE_COMMANDE' => array('class' => 'modCommande'),
4220
        'MAIN_MODULE_FACTURE' => array('class' => 'modFacture'),
4221
        'MAIN_MODULE_FICHEINTER' => array('class' => 'modFicheinter'),
4222
        'MAIN_MODULE_FOURNISSEUR' => array('class' => 'modFournisseur'),
4223
        'MAIN_MODULE_HOLIDAY' => array('class' => 'modHoliday', 'remove' => 1),
4224
        'MAIN_MODULE_EXPEDITION' => array('class' => 'modExpedition'),
4225
        'MAIN_MODULE_EXPENSEREPORT' => array('class' => 'modExpenseReport'),
4226
        'MAIN_MODULE_DON' => array('class' => 'modDon'),
4227
        'MAIN_MODULE_ECM' => array('class' => 'modECM', 'remove' => 1),
4228
        'MAIN_MODULE_KNOWLEDGEMANAGEMENT' => array('class' => 'modKnowledgeManagement', 'remove' => 1),
4229
        'MAIN_MODULE_EVENTORGANIZATION' => array('class' => 'modEventOrganization', 'remove' => 1),
4230
        'MAIN_MODULE_PAYBOX' => array('class' => 'modPaybox', 'remove' => 1),
4231
        'MAIN_MODULE_PROPAL' => array('class' => 'modPropale'),
4232
        'MAIN_MODULE_SUPPLIERPROPOSAL' => array('class' => 'modSupplierProposal', 'remove' => 1),
4233
        'MAIN_MODULE_OPENSURVEY' => array('class' => 'modOpenSurvey', 'remove' => 1),
4234
        'MAIN_MODULE_PRODUCTBATCH' => array('class' => 'modProductBatch', 'remove' => 1),
4235
        'MAIN_MODULE_TAKEPOS' => array('class' => 'modTakePos', 'remove' => 1),
4236
        'MAIN_MODULE_EMAILCOLLECTOR' => array('class' => 'modEmailCollector', 'remove' => 1),
4237
    );
4238
4239
    foreach ($listofmodule as $moduletoreload => $reloadmode) { // reloadmodule can be 'noboxes', 'newboxdefonly', 'forceactivate'
4240
        if (empty($moduletoreload) || (empty($conf->global->$moduletoreload) && !$force)) {
4241
            continue; // Discard reload if module not enabled
4242
        }
4243
4244
        $mod = null;
4245
4246
        if (!empty($reloadactionformodules[$moduletoreload])) {
4247
            dolibarr_install_syslog("upgrade2::migrate_reload_modules Reactivate module " . $moduletoreload . " with mode " . $reloadmode);
4248
4249
            $val = $reloadactionformodules[$moduletoreload];
4250
            $classformodule = $val['class'];
4251
            $res = @include_once DOL_DOCUMENT_ROOT . '/core/modules/' . $classformodule . '.class.php';
4252
            if ($res) {
4253
                $mod = new $classformodule($db);
4254
                if (!empty($val['remove'])) {
4255
                    $mod->remove('noboxes');
4256
                }
4257
                if (!empty($val['deleteinsertmenus'])) {
4258
                    // We only reload menus
4259
                    $mod->delete_menus();
4260
                    $mod->insert_menus();
4261
                } else {
4262
                    $mod->init($reloadmode);
4263
                }
4264
            }
4265
        } else {    // Other generic cases/modules
4266
            $reg = array();
4267
            $tmp = preg_match('/MAIN_MODULE_([a-zA-Z0-9]+)/', $moduletoreload, $reg);
4268
            if (!empty($reg[1])) {
4269
                if (strtoupper($moduletoreload) == $moduletoreload) {   // If key is un uppercase
4270
                    $moduletoreloadshort = ucfirst(strtolower($reg[1]));
4271
                } else { // If key is a mix of up and low case
4272
                    $moduletoreloadshort = $reg[1];
4273
                }
4274
4275
                dolibarr_install_syslog("upgrade2::migrate_reload_modules Reactivate module " . $moduletoreloadshort . " with mode " . $reloadmode . " (generic code)");
4276
4277
                $res = @include_once DOL_DOCUMENT_ROOT . '/core/modules/mod' . $moduletoreloadshort . '.class.php';
4278
                if ($res) {
4279
                    $classname = 'mod' . $moduletoreloadshort;
4280
                    $mod = new $classname($db);
4281
4282
                    //$mod->remove('noboxes');
4283
                    $mod->delete_menus(); // We must delete to be sure it is inserted with new values
4284
                    $mod->init($reloadmode);
4285
                } else {
4286
                    dolibarr_install_syslog('Failed to include ' . DOL_DOCUMENT_ROOT . '/core/modules/mod' . $moduletoreloadshort . '.class.php');
4287
4288
                    $res = @dol_include_once(strtolower($moduletoreloadshort) . '/core/modules/mod' . $moduletoreloadshort . '.class.php');
4289
                    if ($res) {
4290
                        $classname = 'mod' . $moduletoreloadshort;
4291
                        $mod = new $classname($db);
4292
                        $mod->init($reloadmode);
4293
                    } else {
4294
                        dolibarr_install_syslog('Failed to include ' . strtolower($moduletoreloadshort) . '/core/modules/mod' . $moduletoreloadshort . '.class.php', LOG_ERR);
4295
                        print "Error, can't find module with name " . $moduletoreload . "\n";
4296
                        return -1;
4297
                    }
4298
                }
4299
            } else {
4300
                dolibarr_install_syslog("Error, can't find module with name " . $moduletoreload, LOG_ERR);
4301
                print "Error, can't find module with name " . $moduletoreload . "\n";
4302
                return -1;
4303
            }
4304
        }
4305
4306
        if (!empty($mod) && is_object($mod)) {
4307
            print '<tr class="trforrunsql"><td colspan="4">';
4308
            print '<b>' . $langs->trans('Upgrade') . '</b>: ';
4309
            print $langs->trans('MigrationReloadModule') . ' ' . $mod->getName(); // We keep getName outside of trans because getName is already encoded/translated
4310
            print "<!-- (" . $reloadmode . ") -->";
4311
            print "<br>\n";
4312
            print '</td></tr>';
4313
        }
4314
    }
4315
4316
    return 1;
4317
}
4318
4319
4320
/**
4321
 * Reload SQL menu file (if dynamic menus, if modified by version)
4322
 *
4323
 * @param DoliDB $db Database handler
4324
 * @param Translate $langs Object langs
4325
 * @param Conf $conf Object conf
4326
 * @return  int                     Return integer <0 if KO, >0 if OK
4327
 */
4328
function migrate_reload_menu($db, $langs, $conf)
4329
{
4330
    global $conf;
4331
    dolibarr_install_syslog("upgrade2::migrate_reload_menu");
4332
4333
    // Define list of menu handlers to initialize
4334
    $listofmenuhandler = array();
4335
    if (
4336
        getDolGlobalString('MAIN_MENU_STANDARD') == 'auguria_menu' || getDolGlobalString('MAIN_MENU_SMARTPHONE') == 'auguria_menu'
4337
        || getDolGlobalString('MAIN_MENUFRONT_STANDARD') == 'auguria_menu' || getDolGlobalString('MAIN_MENUFRONT_SMARTPHONE') == 'auguria_menu'
4338
    ) {
4339
        $listofmenuhandler['auguria'] = 1; // We set here only dynamic menu handlers
4340
    }
4341
4342
    foreach ($listofmenuhandler as $key => $val) {
4343
        print '<tr class="trforrunsql"><td colspan="4">';
4344
4345
        //print "x".$key;
4346
        print '<br>';
4347
        print '<b>' . $langs->trans('Upgrade') . '</b>: ' . $langs->trans('MenuHandler') . " " . $key . "<br>\n";
4348
4349
        // Load sql ini_menu_handler.sql file
4350
        $dir = DOL_DOCUMENT_ROOT . "/core/menus/";
4351
        $file = 'init_menu_' . $key . '.sql';
4352
        if (file_exists($dir . $file)) {
4353
            $result = run_sql($dir . $file, 1, '', 1, $key);
4354
        }
4355
4356
        print '</td></tr>';
4357
    }
4358
4359
    return 1;
4360
}
4361
4362
/**
4363
 * Migrate file from old path to new one for users
4364
 *
4365
 * @return  void
4366
 */
4367
function migrate_user_photospath()
4368
{
4369
    global $conf, $db, $langs, $user;
4370
4371
    print '<tr><td colspan="4">';
4372
4373
    print '<b>' . $langs->trans('MigrationUserPhotoPath') . "</b><br>\n";
4374
4375
    include_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
4376
    $fuser = new User($db);
4377
    if (!is_object($user)) {
4378
        $user = $fuser; // To avoid error during migration
4379
    }
4380
4381
    $sql = "SELECT rowid as uid, entity from " . MAIN_DB_PREFIX . "user"; // Get list of all users
4382
    $resql = $db->query($sql);
4383
    if ($resql) {
4384
        while ($obj = $db->fetch_object($resql)) {
4385
            //$fuser->fetch($obj->uid);
4386
            $fuser->id = $obj->uid;
4387
            $fuser->entity = $obj->entity;
4388
4389
            //echo '<hr>'.$fuser->id.' -> '.$fuser->entity;
4390
            $entity = (empty($fuser->entity) ? 1 : $fuser->entity);
4391
            if ($entity > 1) {
4392
                $dir = DOL_DATA_ROOT . '/' . $entity . '/users';
4393
            } else {
4394
                $dir = $conf->user->multidir_output[$entity]; // $conf->user->multidir_output[] for each entity is construct by the multicompany module
4395
            }
4396
4397
            if ($dir) {
4398
                //print "Process user id ".$fuser->id."<br>\n";
4399
                $origin = $dir . '/' . get_exdir($fuser->id, 2, 0, 1, $fuser, 'user'); // Use old behaviour to get x/y path
4400
                $destin = $dir . '/' . $fuser->id;
4401
4402
                $origin_osencoded = dol_osencode($origin);
4403
4404
                dol_mkdir($destin);
4405
4406
                //echo '<hr>'.$origin.' -> '.$destin;
4407
                if (dol_is_dir($origin)) {
4408
                    $handle = opendir($origin_osencoded);
4409
                    if (is_resource($handle)) {
4410
                        while (($file = readdir($handle)) !== false) {
4411
                            if ($file == '.' || $file == '..') {
4412
                                continue;
4413
                            }
4414
4415
                            if (dol_is_dir($origin . '/' . $file)) {    // it is a dir (like 'thumbs')
4416
                                $thumbs = opendir($origin_osencoded . '/' . $file);
4417
                                if (is_resource($thumbs)) {
4418
                                    dol_mkdir($destin . '/' . $file);
4419
                                    while (($thumb = readdir($thumbs)) !== false) {
4420
                                        if (!dol_is_file($destin . '/' . $file . '/' . $thumb)) {
4421
                                            if ($thumb == '.' || $thumb == '..') {
4422
                                                continue;
4423
                                            }
4424
4425
                                            //print $origin.'/'.$file.'/'.$thumb.' -> '.$destin.'/'.$file.'/'.$thumb.'<br>'."\n";
4426
                                            print '.';
4427
                                            dol_copy($origin . '/' . $file . '/' . $thumb, $destin . '/' . $file . '/' . $thumb, 0, 0);
4428
                                            //var_dump('aaa');exit;
4429
                                        }
4430
                                    }
4431
                                    // dol_delete_dir($origin.'/'.$file);
4432
                                }
4433
                            } else { // it is a file
4434
                                if (!dol_is_file($destin . '/' . $file)) {
4435
                                    //print $origin.'/'.$file.' -> '.$destin.'/'.$file.'<br>'."\n";
4436
                                    print '.';
4437
                                    dol_copy($origin . '/' . $file, $destin . '/' . $file, 0, 0);
4438
                                    //var_dump('eee');exit;
4439
                                }
4440
                            }
4441
                        }
4442
                    }
4443
                }
4444
            }
4445
        }
4446
    }
4447
4448
    print '</td></tr>';
4449
}
4450
4451
/**
4452
 * Migrate file from old path users/99/file.jpg into users/99/photos/file.jpg
4453
 *
4454
 * @return  void
4455
 */
4456
function migrate_user_photospath2()
4457
{
4458
    global $db, $langs, $user;
4459
4460
    print '<tr><td colspan="4">';
4461
4462
    print '<b>' . $langs->trans('MigrationUserPhotoPath') . "</b><br>\n";
4463
4464
    include_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
4465
    $fuser = new User($db);
4466
    if (!is_object($user)) {
4467
        $user = $fuser; // To avoid error during migration
4468
    }
4469
4470
    $sql = "SELECT rowid as uid, entity, photo from " . MAIN_DB_PREFIX . "user"; // Get list of all users
4471
    $resql = $db->query($sql);
4472
    if ($resql) {
4473
        while ($obj = $db->fetch_object($resql)) {
4474
            //$fuser->fetch($obj->uid);
4475
            $fuser->id = $obj->uid;
4476
            $fuser->entity = $obj->entity;
4477
            $fuser->photo = $obj->photo;
4478
4479
            //echo '<hr>'.$fuser->id.' -> '.$fuser->entity;
4480
            $entity = (empty($fuser->entity) ? 1 : $fuser->entity);
4481
            if ($entity > 1) {
4482
                $dir = DOL_DATA_ROOT . '/' . $entity . '/users';
4483
            } else {
4484
                $dir = DOL_DATA_ROOT . '/users';
4485
            }
4486
4487
            if ($dir) {
4488
                //print "Process user id ".$fuser->id."<br>\n";
4489
                $origin = $dir . '/' . $fuser->id;
4490
                $destin = $dir . '/' . $fuser->id . '/photos';
4491
4492
                $origin_osencoded = dol_osencode($origin);
4493
4494
                dol_mkdir($destin);
4495
4496
                //echo '<hr>'.$origin.' -> '.$destin;
4497
                if (dol_is_dir($origin)) {
4498
                    $handle = opendir($origin_osencoded);
4499
                    if (is_resource($handle)) {
4500
                        while (($file = readdir($handle)) !== false) {
4501
                            if ($file == '.' || $file == '..' || $file == 'photos') {
4502
                                continue;
4503
                            }
4504
                            if (!empty($fuser->photo) && ($file != $fuser->photo && $file != 'thumbs')) {
4505
                                continue;
4506
                            }
4507
4508
                            if (dol_is_dir($origin . '/' . $file)) {    // it is a dir (like 'thumbs')
4509
                                $thumbs = opendir($origin_osencoded . '/' . $file);
4510
                                if (is_resource($thumbs)) {
4511
                                    dol_mkdir($destin . '/' . $file);
4512
                                    while (($thumb = readdir($thumbs)) !== false) {
4513
                                        if (!dol_is_file($destin . '/' . $file . '/' . $thumb)) {
4514
                                            if ($thumb == '.' || $thumb == '..') {
4515
                                                continue;
4516
                                            }
4517
4518
                                            //print $origin.'/'.$file.'/'.$thumb.' -> '.$destin.'/'.$file.'/'.$thumb.'<br>'."\n";
4519
                                            print '.';
4520
                                            dol_copy($origin . '/' . $file . '/' . $thumb, $destin . '/' . $file . '/' . $thumb, 0, 0);
4521
                                        }
4522
                                    }
4523
                                    // dol_delete_dir($origin.'/'.$file);
4524
                                }
4525
                            } else { // it is a file
4526
                                if (!dol_is_file($destin . '/' . $file)) {
4527
                                    //print $origin.'/'.$file.' -> '.$destin.'/'.$file.'<br>'."\n";
4528
                                    print '.';
4529
                                    dol_copy($origin . '/' . $file, $destin . '/' . $file, 0, 0);
4530
                                }
4531
                            }
4532
                        }
4533
                    }
4534
                }
4535
            }
4536
        }
4537
    }
4538
4539
    print '</td></tr>';
4540
}
4541
4542
4543
/* A faire egalement: Modif statut paye et fk_facture des factures payes completement
4544
4545
On recherche facture incorrecte:
4546
select f.rowid, f.total_ttc as t1, sum(pf.amount) as t2 from llx_facture as f, llx_paiement_facture as pf where pf.fk_facture=f.rowid and f.fk_statut in(2,3) and paye=0 and close_code is null group by f.rowid
4547
having  f.total_ttc = sum(pf.amount)
4548
4549
On les corrige:
4550
update llx_facture set paye=1, fk_statut=2 where close_code is null
4551
and rowid in (...)
4552
*/
4553
4554
/**
4555
 * Migrate users fields facebook and co to socialnetworks.
4556
 * Can be called only when version is 10.0.* or lower. Fields does not exists after.
4557
 *
4558
 * @return  void
4559
 */
4560
function migrate_users_socialnetworks()
4561
{
4562
    global $db, $langs;
4563
    // skype,twitter,facebook,linkedin,instagram,snapchat,googleplus,youtube,whatsapp
4564
    $error = 0;
4565
    $db->begin();
4566
    print '<tr><td colspan="4">';
4567
    $sql = 'SELECT rowid, socialnetworks';
4568
    $sql .= ', skype, twitter, facebook, linkedin, instagram, snapchat, googleplus, youtube, whatsapp FROM ' . MAIN_DB_PREFIX . 'user WHERE';
4569
    $sql .= " skype IS NOT NULL OR skype <> ''";
4570
    $sql .= " OR twitter IS NOT NULL OR twitter <> ''";
4571
    $sql .= " OR facebook IS NOT NULL OR facebook <> ''";
4572
    $sql .= " OR linkedin IS NOT NULL OR linkedin <> ''";
4573
    $sql .= " OR instagram IS NOT NULL OR instagram <> ''";
4574
    $sql .= " OR snapchat IS NOT NULL OR snapchat <> ''";
4575
    $sql .= " OR googleplus IS NOT NULL OR googleplus <> ''";
4576
    $sql .= " OR youtube IS NOT NULL OR youtube <> ''";
4577
    $sql .= " OR whatsapp IS NOT NULL OR whatsapp <> ''";
4578
    //print $sql;
4579
    $resql = $db->query($sql);
4580
    if ($resql) {
4581
        while ($obj = $db->fetch_object($resql)) {
4582
            $arraysocialnetworks = array();
4583
            if (!empty($obj->skype)) {
4584
                $arraysocialnetworks['skype'] = $obj->skype;
4585
            }
4586
            if (!empty($obj->twitter)) {
4587
                $arraysocialnetworks['twitter'] = $obj->twitter;
4588
            }
4589
            if (!empty($obj->facebook)) {
4590
                $arraysocialnetworks['facebook'] = $obj->facebook;
4591
            }
4592
            if (!empty($obj->linkedin)) {
4593
                $arraysocialnetworks['linkedin'] = $obj->linkedin;
4594
            }
4595
            if (!empty($obj->instagram)) {
4596
                $arraysocialnetworks['instagram'] = $obj->instagram;
4597
            }
4598
            if (!empty($obj->snapchat)) {
4599
                $arraysocialnetworks['snapchat'] = $obj->snapchat;
4600
            }
4601
            if (!empty($obj->googleplus)) {
4602
                $arraysocialnetworks['googleplus'] = $obj->googleplus;
4603
            }
4604
            if (!empty($obj->youtube)) {
4605
                $arraysocialnetworks['youtube'] = $obj->youtube;
4606
            }
4607
            if (!empty($obj->whatsapp)) {
4608
                $arraysocialnetworks['whatsapp'] = $obj->whatsapp;
4609
            }
4610
            if ($obj->socialnetworks == '' || is_null($obj->socialnetworks)) {
4611
                $obj->socialnetworks = '[]';
4612
            }
4613
            $socialnetworks = array_merge($arraysocialnetworks, json_decode($obj->socialnetworks, true));
4614
            $sqlupd = 'UPDATE ' . MAIN_DB_PREFIX . "user SET socialnetworks='" . $db->escape(json_encode($socialnetworks)) . "'";
4615
            $sqlupd .= ', skype=null';
4616
            $sqlupd .= ', twitter=null';
4617
            $sqlupd .= ', facebook=null';
4618
            $sqlupd .= ', linkedin=null';
4619
            $sqlupd .= ', instagram=null';
4620
            $sqlupd .= ', snapchat=null';
4621
            $sqlupd .= ', googleplus=null';
4622
            $sqlupd .= ', youtube=null';
4623
            $sqlupd .= ', whatsapp=null';
4624
            $sqlupd .= ' WHERE rowid = ' . ((int)$obj->rowid);
4625
            //print $sqlupd."<br>";
4626
            $resqlupd = $db->query($sqlupd);
4627
            if (!$resqlupd) {
4628
                dol_print_error($db);
4629
                $error++;
4630
            }
4631
        }
4632
    } else {
4633
        $error++;
4634
    }
4635
    if (!$error) {
4636
        $db->commit();
4637
    } else {
4638
        dol_print_error($db);
4639
        $db->rollback();
4640
    }
4641
    print '<b>' . $langs->trans('MigrationFieldsSocialNetworks', 'Users') . "</b><br>\n";
4642
    print '</td></tr>';
4643
}
4644
4645
/**
4646
 * Migrate members fields facebook and co to socialnetworks
4647
 * Can be called only when version is 10.0.* or lower. Fields does not exists after.
4648
 *
4649
 * @return  void
4650
 */
4651
function migrate_members_socialnetworks()
4652
{
4653
    global $db, $langs;
4654
4655
    print '<tr><td colspan="4">';
4656
    $error = 0;
4657
    $db->begin();
4658
    print '<tr><td colspan="4">';
4659
    $sql = 'SELECT rowid, socialnetworks';
4660
    $sql .= ', skype, twitter, facebook, linkedin, instagram, snapchat, googleplus, youtube, whatsapp FROM ' . MAIN_DB_PREFIX . 'adherent WHERE ';
4661
    $sql .= " skype IS NOT NULL OR skype <> ''";
4662
    $sql .= " OR twitter IS NOT NULL OR twitter <> ''";
4663
    $sql .= " OR facebook IS NOT NULL OR facebook <> ''";
4664
    $sql .= " OR linkedin IS NOT NULL OR linkedin <> ''";
4665
    $sql .= " OR instagram IS NOT NULL OR instagram <> ''";
4666
    $sql .= " OR snapchat IS NOT NULL OR snapchat <> ''";
4667
    $sql .= " OR googleplus IS NOT NULL OR googleplus <> ''";
4668
    $sql .= " OR youtube IS NOT NULL OR youtube <> ''";
4669
    $sql .= " OR whatsapp IS NOT NULL OR whatsapp <> ''";
4670
    //print $sql;
4671
    $resql = $db->query($sql);
4672
    if ($resql) {
4673
        while ($obj = $db->fetch_object($resql)) {
4674
            $arraysocialnetworks = array();
4675
            if (!empty($obj->skype)) {
4676
                $arraysocialnetworks['skype'] = $obj->skype;
4677
            }
4678
            if (!empty($obj->twitter)) {
4679
                $arraysocialnetworks['twitter'] = $obj->twitter;
4680
            }
4681
            if (!empty($obj->facebook)) {
4682
                $arraysocialnetworks['facebook'] = $obj->facebook;
4683
            }
4684
            if (!empty($obj->linkedin)) {
4685
                $arraysocialnetworks['linkedin'] = $obj->linkedin;
4686
            }
4687
            if (!empty($obj->instagram)) {
4688
                $arraysocialnetworks['instagram'] = $obj->instagram;
4689
            }
4690
            if (!empty($obj->snapchat)) {
4691
                $arraysocialnetworks['snapchat'] = $obj->snapchat;
4692
            }
4693
            if (!empty($obj->googleplus)) {
4694
                $arraysocialnetworks['googleplus'] = $obj->googleplus;
4695
            }
4696
            if (!empty($obj->youtube)) {
4697
                $arraysocialnetworks['youtube'] = $obj->youtube;
4698
            }
4699
            if (!empty($obj->whatsapp)) {
4700
                $arraysocialnetworks['whatsapp'] = $obj->whatsapp;
4701
            }
4702
            if ($obj->socialnetworks == '' || is_null($obj->socialnetworks)) {
4703
                $obj->socialnetworks = '[]';
4704
            }
4705
            $socialnetworks = array_merge($arraysocialnetworks, json_decode($obj->socialnetworks, true));
4706
            $sqlupd = 'UPDATE ' . MAIN_DB_PREFIX . "adherent SET socialnetworks='" . $db->escape(json_encode($socialnetworks)) . "'";
4707
            $sqlupd .= ', skype=null';
4708
            $sqlupd .= ', twitter=null';
4709
            $sqlupd .= ', facebook=null';
4710
            $sqlupd .= ', linkedin=null';
4711
            $sqlupd .= ', instagram=null';
4712
            $sqlupd .= ', snapchat=null';
4713
            $sqlupd .= ', googleplus=null';
4714
            $sqlupd .= ', youtube=null';
4715
            $sqlupd .= ', whatsapp=null';
4716
            $sqlupd .= ' WHERE rowid = ' . ((int)$obj->rowid);
4717
            //print $sqlupd."<br>";
4718
            $resqlupd = $db->query($sqlupd);
4719
            if (!$resqlupd) {
4720
                dol_print_error($db);
4721
                $error++;
4722
            }
4723
        }
4724
    } else {
4725
        $error++;
4726
    }
4727
    if (!$error) {
4728
        $db->commit();
4729
    } else {
4730
        dol_print_error($db);
4731
        $db->rollback();
4732
    }
4733
    print '<b>' . $langs->trans('MigrationFieldsSocialNetworks', 'Members') . "</b><br>\n";
4734
    print '</td></tr>';
4735
}
4736
4737
/**
4738
 * Migrate contacts fields facebook and co to socialnetworks
4739
 * Can be called only when version is 10.0.* or lower. Fields does not exists after.
4740
 *
4741
 * @return  void
4742
 */
4743
function migrate_contacts_socialnetworks()
4744
{
4745
    global $db, $langs;
4746
    // jabberid,skype,twitter,facebook,linkedin,instagram,snapchat,googleplus,youtube,whatsapp
4747
    $error = 0;
4748
    $db->begin();
4749
    print '<tr><td colspan="4">';
4750
    $sql = 'SELECT rowid, socialnetworks';
4751
    $sql .= ', jabberid, skype, twitter, facebook, linkedin, instagram, snapchat, googleplus, youtube, whatsapp FROM ' . MAIN_DB_PREFIX . 'socpeople WHERE';
4752
    $sql .= " jabberid IS NOT NULL OR jabberid <> ''";
4753
    $sql .= " OR skype IS NOT NULL OR skype <> ''";
4754
    $sql .= " OR twitter IS NOT NULL OR twitter <> ''";
4755
    $sql .= " OR facebook IS NOT NULL OR facebook <> ''";
4756
    $sql .= " OR linkedin IS NOT NULL OR linkedin <> ''";
4757
    $sql .= " OR instagram IS NOT NULL OR instagram <> ''";
4758
    $sql .= " OR snapchat IS NOT NULL OR snapchat <> ''";
4759
    $sql .= " OR googleplus IS NOT NULL OR googleplus <> ''";
4760
    $sql .= " OR youtube IS NOT NULL OR youtube <> ''";
4761
    $sql .= " OR whatsapp IS NOT NULL OR whatsapp <> ''";
4762
    //print $sql;
4763
    $resql = $db->query($sql);
4764
    if ($resql) {
4765
        while ($obj = $db->fetch_object($resql)) {
4766
            $arraysocialnetworks = array();
4767
            if (!empty($obj->jabberid)) {
4768
                $arraysocialnetworks['jabber'] = $obj->jabberid;
4769
            }
4770
            if (!empty($obj->skype)) {
4771
                $arraysocialnetworks['skype'] = $obj->skype;
4772
            }
4773
            if (!empty($obj->twitter)) {
4774
                $arraysocialnetworks['twitter'] = $obj->twitter;
4775
            }
4776
            if (!empty($obj->facebook)) {
4777
                $arraysocialnetworks['facebook'] = $obj->facebook;
4778
            }
4779
            if (!empty($obj->linkedin)) {
4780
                $arraysocialnetworks['linkedin'] = $obj->linkedin;
4781
            }
4782
            if (!empty($obj->instagram)) {
4783
                $arraysocialnetworks['instagram'] = $obj->instagram;
4784
            }
4785
            if (!empty($obj->snapchat)) {
4786
                $arraysocialnetworks['snapchat'] = $obj->snapchat;
4787
            }
4788
            if (!empty($obj->googleplus)) {
4789
                $arraysocialnetworks['googleplus'] = $obj->googleplus;
4790
            }
4791
            if (!empty($obj->youtube)) {
4792
                $arraysocialnetworks['youtube'] = $obj->youtube;
4793
            }
4794
            if (!empty($obj->whatsapp)) {
4795
                $arraysocialnetworks['whatsapp'] = $obj->whatsapp;
4796
            }
4797
            if ($obj->socialnetworks == '' || is_null($obj->socialnetworks)) {
4798
                $obj->socialnetworks = '[]';
4799
            }
4800
            $socialnetworks = array_merge($arraysocialnetworks, json_decode($obj->socialnetworks, true));
4801
            $sqlupd = 'UPDATE ' . MAIN_DB_PREFIX . "socpeople SET socialnetworks='" . $db->escape(json_encode($socialnetworks)) . "'";
4802
            $sqlupd .= ', jabberid=null';
4803
            $sqlupd .= ', skype=null';
4804
            $sqlupd .= ', twitter=null';
4805
            $sqlupd .= ', facebook=null';
4806
            $sqlupd .= ', linkedin=null';
4807
            $sqlupd .= ', instagram=null';
4808
            $sqlupd .= ', snapchat=null';
4809
            $sqlupd .= ', googleplus=null';
4810
            $sqlupd .= ', youtube=null';
4811
            $sqlupd .= ', whatsapp=null';
4812
            $sqlupd .= ' WHERE rowid = ' . ((int)$obj->rowid);
4813
            //print $sqlupd."<br>";
4814
            $resqlupd = $db->query($sqlupd);
4815
            if (!$resqlupd) {
4816
                dol_print_error($db);
4817
                $error++;
4818
            }
4819
        }
4820
    } else {
4821
        $error++;
4822
    }
4823
    if (!$error) {
4824
        $db->commit();
4825
    } else {
4826
        dol_print_error($db);
4827
        $db->rollback();
4828
    }
4829
    print '<b>' . $langs->trans('MigrationFieldsSocialNetworks', 'Contacts') . "</b><br>\n";
4830
    print '</td></tr>';
4831
}
4832
4833
/**
4834
 * Migrate thirdparties fields facebook and co to socialnetworks
4835
 * Can be called only when version is 10.0.* or lower. Fields does not exists after.
4836
 *
4837
 * @return  void
4838
 */
4839
function migrate_thirdparties_socialnetworks()
4840
{
4841
    global $db, $langs;
4842
    // skype,twitter,facebook,linkedin,instagram,snapchat,googleplus,youtube,whatsapp
4843
    $error = 0;
4844
    $db->begin();
4845
    print '<tr><td colspan="4">';
4846
    $sql = 'SELECT rowid, socialnetworks';
4847
    $sql .= ', skype, twitter, facebook, linkedin, instagram, snapchat, googleplus, youtube, whatsapp FROM ' . MAIN_DB_PREFIX . 'societe WHERE ';
4848
    $sql .= " skype IS NOT NULL OR skype <> ''";
4849
    $sql .= " OR twitter IS NOT NULL OR twitter <> ''";
4850
    $sql .= " OR facebook IS NOT NULL OR facebook <> ''";
4851
    $sql .= " OR linkedin IS NOT NULL OR linkedin <> ''";
4852
    $sql .= " OR instagram IS NOT NULL OR instagram <> ''";
4853
    $sql .= " OR snapchat IS NOT NULL OR snapchat <> ''";
4854
    $sql .= " OR googleplus IS NOT NULL OR googleplus <> ''";
4855
    $sql .= " OR youtube IS NOT NULL OR youtube <> ''";
4856
    $sql .= " OR whatsapp IS NOT NULL OR whatsapp <> ''";
4857
    //print $sql;
4858
    $resql = $db->query($sql);
4859
    if ($resql) {
4860
        while ($obj = $db->fetch_object($resql)) {
4861
            $arraysocialnetworks = array();
4862
            if (!empty($obj->skype)) {
4863
                $arraysocialnetworks['skype'] = $obj->skype;
4864
            }
4865
            if (!empty($obj->twitter)) {
4866
                $arraysocialnetworks['twitter'] = $obj->twitter;
4867
            }
4868
            if (!empty($obj->facebook)) {
4869
                $arraysocialnetworks['facebook'] = $obj->facebook;
4870
            }
4871
            if (!empty($obj->linkedin)) {
4872
                $arraysocialnetworks['linkedin'] = $obj->linkedin;
4873
            }
4874
            if (!empty($obj->instagram)) {
4875
                $arraysocialnetworks['instagram'] = $obj->instagram;
4876
            }
4877
            if (!empty($obj->snapchat)) {
4878
                $arraysocialnetworks['snapchat'] = $obj->snapchat;
4879
            }
4880
            if (!empty($obj->googleplus)) {
4881
                $arraysocialnetworks['googleplus'] = $obj->googleplus;
4882
            }
4883
            if (!empty($obj->youtube)) {
4884
                $arraysocialnetworks['youtube'] = $obj->youtube;
4885
            }
4886
            if (!empty($obj->whatsapp)) {
4887
                $arraysocialnetworks['whatsapp'] = $obj->whatsapp;
4888
            }
4889
            if ($obj->socialnetworks == '' || is_null($obj->socialnetworks)) {
4890
                $obj->socialnetworks = '[]';
4891
            }
4892
            $socialnetworks = array_merge($arraysocialnetworks, json_decode($obj->socialnetworks, true));
4893
            $sqlupd = 'UPDATE ' . MAIN_DB_PREFIX . "societe SET socialnetworks='" . $db->escape(json_encode($socialnetworks)) . "'";
4894
            $sqlupd .= ', skype=null';
4895
            $sqlupd .= ', twitter=null';
4896
            $sqlupd .= ', facebook=null';
4897
            $sqlupd .= ', linkedin=null';
4898
            $sqlupd .= ', instagram=null';
4899
            $sqlupd .= ', snapchat=null';
4900
            $sqlupd .= ', googleplus=null';
4901
            $sqlupd .= ', youtube=null';
4902
            $sqlupd .= ', whatsapp=null';
4903
            $sqlupd .= ' WHERE rowid = ' . ((int)$obj->rowid);
4904
            //print $sqlupd."<br>";
4905
            $resqlupd = $db->query($sqlupd);
4906
            if (!$resqlupd) {
4907
                dol_print_error($db);
4908
                $error++;
4909
            }
4910
        }
4911
    } else {
4912
        $error++;
4913
    }
4914
    if (!$error) {
4915
        $db->commit();
4916
    } else {
4917
        dol_print_error($db);
4918
        $db->rollback();
4919
    }
4920
    print '<b>' . $langs->trans('MigrationFieldsSocialNetworks', 'Thirdparties') . "</b><br>\n";
4921
    print '</td></tr>';
4922
}
4923
4924
4925
/**
4926
 * Migrate export and import profiles to fix field name that was renamed
4927
 *
4928
 * @param string $mode 'export' or 'import'
4929
 * @return  void
4930
 */
4931
function migrate_export_import_profiles($mode = 'export')
4932
{
4933
    global $db, $langs;
4934
4935
    $error = 0;
4936
    $resultstring = '';
4937
4938
    $db->begin();
4939
4940
    print '<tr class="trforrunsql"><td colspan="4">';
4941
    $sql = 'SELECT rowid, field';
4942
    if ($mode == 'export') {
4943
        $sql .= ', filter';
4944
    }
4945
    $sql .= ' FROM ' . MAIN_DB_PREFIX . $mode . '_model WHERE';
4946
    $sql .= " type LIKE 'propale_%' OR type LIKE 'commande_%' OR type LIKE 'facture_%'";
4947
    //print $sql;
4948
    $resql = $db->query($sql);
4949
    if ($resql) {
4950
        while ($obj = $db->fetch_object($resql)) {
4951
            $oldfield = $obj->field;
4952
            $newfield = str_replace(array(',f.facnumber', 'f.facnumber,', 'f.total,', 'f.tva,'), array(',f.ref', 'f.ref,', 'f.total_ht,', 'f.total_tva,'), $oldfield);
4953
4954
            if ($mode == 'export') {
4955
                $oldfilter = $obj->filter;
4956
                $newfilter = str_replace(array('f.facnumber=', 'f.total=', 'f.tva='), array('f.ref=', 'f.total_ht=', 'f.total_tva='), $oldfilter);
4957
            } else {
4958
                $oldfilter = '';
4959
                $newfilter = '';
4960
            }
4961
4962
            if ($oldfield != $newfield || $oldfilter != $newfilter) {
4963
                $sqlupd = 'UPDATE ' . MAIN_DB_PREFIX . $mode . "_model SET field = '" . $db->escape($newfield) . "'";
4964
                if ($mode == 'export') {
4965
                    $sqlupd .= ", filter = '" . $db->escape($newfilter) . "'";
4966
                }
4967
                $sqlupd .= ' WHERE rowid = ' . ((int)$obj->rowid);
4968
                $resultstring .= '<tr class="trforrunsql" style=""><td class="wordbreak" colspan="4">' . $sqlupd . "</td></tr>\n";
4969
                $resqlupd = $db->query($sqlupd);
4970
                if (!$resqlupd) {
4971
                    dol_print_error($db);
4972
                    $error++;
4973
                }
4974
            }
4975
        }
4976
    } else {
4977
        $error++;
4978
    }
4979
    if (!$error) {
4980
        $db->commit();
4981
    } else {
4982
        dol_print_error($db);
4983
        $db->rollback();
4984
    }
4985
    print '<b>' . $langs->trans('MigrationImportOrExportProfiles', $mode) . "</b><br>\n";
4986
    print '</td></tr>';
4987
4988
    if ($resultstring) {
4989
        print $resultstring;
4990
    } else {
4991
        print '<tr class="trforrunsql" style=""><td class="wordbreak" colspan="4">' . $langs->trans("NothingToDo") . "</td></tr>\n";
4992
    }
4993
}
4994
4995
/**
4996
 * Migrate Rank into contract  line
4997
 *
4998
 * @return  void
4999
 */
5000
function migrate_contractdet_rank()
5001
{
5002
    global $db, $langs;
5003
5004
    $error = 0;
5005
    $resultstring = '';
5006
5007
    $db->begin();
5008
    print '<tr class="trforrunsql"><td colspan="4">';
5009
    print '<b>' . $langs->trans('MigrationContractLineRank') . "</b><br>\n";
5010
5011
    $sql = "SELECT c.rowid as cid ,cd.rowid as cdid,cd.rang FROM " . $db->prefix() . "contratdet as cd INNER JOIN " . $db->prefix() . "contrat as c ON c.rowid=cd.fk_contrat AND cd.rang=0";
5012
    $sql .= " ORDER BY c.rowid,cd.rowid";
5013
5014
    $resql = $db->query($sql);
5015
    if ($resql) {
5016
        $currentRank = 0;
5017
        $current_contract = 0;
5018
        while ($obj = $db->fetch_object($resql)) {
5019
            if (empty($current_contract) || $current_contract == $obj->cid) {
5020
                $currentRank++;
5021
            } else {
5022
                $currentRank = 1;
5023
            }
5024
5025
            $sqlUpd = "UPDATE " . $db->prefix() . "contratdet SET rang=" . (int)$currentRank . " WHERE rowid=" . (int)$obj->cdid;
5026
            $resultstring = '.';
5027
            print $resultstring;
5028
            $resqlUpd = $db->query($sqlUpd);
5029
            if (!$resqlUpd) {
5030
                dol_print_error($db);
5031
                $error++;
5032
            }
5033
5034
            $current_contract = $obj->cid;
5035
        }
5036
    } else {
5037
        $error++;
5038
    }
5039
    if (!$error) {
5040
        $db->commit();
5041
    } else {
5042
        $db->rollback();
5043
    }
5044
5045
    print '</td></tr>';
5046
5047
    if (!$resultstring) {
5048
        print '<tr class="trforrunsql" style=""><td class="wordbreak" colspan="4">' . $langs->trans("NothingToDo") . "</td></tr>\n";
5049
    }
5050
}
5051