Failed Conditions
Push — master ( eb6487...5db91a )
by Sylvain
07:53
created

Importer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Service;
6
7
use Doctrine\DBAL\Driver\PDOConnection;
8
use Doctrine\ORM\EntityManager;
9
use Interop\Container\ContainerInterface;
10
11
class Importer
12
{
13
    /**
14
     * @var ContainerInterface
15
     */
16
    private $container;
17
18
    /**
19
     * @var EntityManager
20
     */
21
    private $entityManager;
22
23
    /**
24
     * @var PDOConnection
25
     */
26
    private $filemaker;
27
28
    /**
29
     * @var PDOConnection
30
     */
31
    private $typo3;
32
33
    /**
34
     * @var array
35
     */
36
    private $members = [];
37
38
    /**
39
     * @var array
40
     */
41
    private $users = [];
42
43
    /**
44
     * Storage requests
45
     *
46
     * @var array
47
     */
48
    private $storage = [];
49
50
    /**
51
     * Allocated storage
52
     * [idBookable] => number of bookings
53
     *
54
     * @var array
55
     */
56
    private $storageAllocated = [];
57
58
    /**
59
     * Import constructor
60
     */
61
    public function __construct(ContainerInterface $container, EntityManager $entityManager)
62
    {
63
        $this->container = $container;
64
        $this->entityManager = $entityManager;
65
    }
66
67
    /**
68
     * Import the members from FileMaker and TYPO3
69
     */
70
    public function import(): void
71
    {
72
        $this->loadMembers();
73
        $this->loadPeople();
74
        $this->deleteTestUsers();
75
        $this->loadStorageRequests();
76
        $this->insertBookables();
77
        $this->insertUsers();
78
        $this->insertBookings();
79
    }
80
81
    /**
82
     * @return PDOConnection
83
     */
84
    private function connectFileMaker(): PDOConnection
85
    {
86
        if ($this->filemaker) {
87
            return $this->filemaker;
88
        }
89
        $config = $this->container->get('config');
90
91
        $dsn = sprintf('odbc:Driver={%s};Server=%s;Database=%s;charset=UTF-8', $config['filemaker']['driver'], $config['filemaker']['host'], $config['filemaker']['dbname']);
92
        $this->filemaker = new PDOConnection($dsn, $config['filemaker']['user'], $config['filemaker']['password']);
93
94
        return $this->filemaker;
95
    }
96
97
    /**
98
     * @return PDOConnection
99
     */
100
    private function connectTypo3(): PDOConnection
101
    {
102
        if ($this->typo3) {
103
            return $this->typo3;
104
        }
105
        $config = $this->container->get('config');
106
107
        $this->typo3 = new PDOConnection(sprintf('mysql:host=%s;port=%u;dbname=%s', $config['typo3']['host'], $config['typo3']['port'], $config['typo3']['dbname']), $config['typo3']['user'], $config['typo3']['password']);
108
109
        return $this->typo3;
110
    }
111
112
    /**
113
     * Load members from FileMaker "ichtus" table into memory
114
     */
115
    private function loadMembers(): void
116
    {
117
        $this->connectFileMaker();
118
        $query = <<<EOT
119
          SELECT ID_membre,
120
               "nom_prénom",
121
               "date_entrée ichtus",
122
               remarques,
123
               "liens de famille",
124
               "date_séance d'accueil",
125
               "date_formulaire_adhésion",
126
               membre_new,
127
               membre_actif,
128
               membre_suspension,
129
               "membre_archivé",
130
               assurances,
131
               envoi_papier
132
          FROM ichtus
133
          WHERE ((membre_new>0 AND "date_formulaire_adhésion">=DATE '2018-10-01') OR membre_actif>0 OR membre_suspension>0) AND "membre_archivé"=0 AND remarques NOT LIKE '%Ignorer%'
134
EOT;
135
        $statement = $this->filemaker->prepare(trim($query));
136
        if ($statement->execute()) {
137
            echo sprintf('%u membres à importer...', $statement->rowCount()) . PHP_EOL;
138
            foreach ($statement->fetchAll(\PDO::FETCH_ASSOC) as $member) {
139
                foreach ($member as $fieldName => $fieldValue) {
140
                    $member[$fieldName] = $this->fromMacRoman($fieldValue);
141
                }
142
                $this->members[$member['ID_membre']] = $member;
143
                echo sprintf('Membre %u importé', $member['ID_membre']) . PHP_EOL;
144
            }
145
        }
146
    }
147
148
    /**
149
     * Load people from TYPO3 fe_users into memory
150
     */
151
    private function loadPeople(): void
152
    {
153
        $this->connectTypo3();
154
        $query = <<<EOT
155
          SELECT *
156
          FROM fe_users
157
          WHERE FIND_IN_SET(CAST(family_uid as char), :members) AND status_archived=0;
158
EOT;
159
        $statement = $this->typo3->prepare($query);
160
        $statement->bindValue(':members', implode(',', array_keys($this->members)));
161
162
        if ($statement->execute()) {
163
            echo sprintf('%u individus à importer...', $statement->rowCount()) . PHP_EOL;
164
            $withoutLoginCount = 0;
165
            foreach ($statement->fetchAll(\PDO::FETCH_ASSOC) as $user) {
166
                if (($user['family_status'] === 'chef de famille' || $user['family_status'] === 'chef(fe) de famille') && $user['uid'] !== $user['family_uid']) {
167
                    echo sprintf('WARN: utilisateur %u ne devrait pas être de chef de la famille %u', $user['uid'], $user['family_uid']) . PHP_EOL;
168
                }
169
                if (empty($user['new_username'])) {
170
                    echo sprintf("WARN: utilisateur %u (%s %s) n'a pas de login MyIchtus", $user['uid'], $user['first_name'], $user['last_name']) . PHP_EOL;
171
                    ++$withoutLoginCount;
172
                }
173
                $this->users[$user['uid']] = $user;
174
                echo sprintf('Individu %u importé', $user['uid']) . PHP_EOL;
175
            }
176
            if ($withoutLoginCount > 0) {
177
                echo sprintf('%u individus sans login MyIchtus', $withoutLoginCount) . PHP_EOL;
178
            }
179
        }
180
    }
181
182
    /**
183
     * Create users
184
     */
185
    private function insertUsers(): void
186
    {
187
        $conn = $this->entityManager->getConnection();
188
189
        $insert = <<<EOT
190
                INSERT INTO user(
191
                  id,
192
                  login,
193
                  first_name,
194
                  last_name,
195
                  birthday,
196
                  sex,
197
                  email,
198
                  street,
199
                  postcode,
200
                  locality,
201
                  country_id,
202
                  mobile_phone,
203
                  phone,
204
                  internal_remarks,
205
                  iban,
206
                  has_insurance,
207
                  swiss_sailing,
208
                  swiss_sailing_type,
209
                  swiss_windsurf_type,
210
                  receives_newsletter,
211
                  role,
212
                  family_relationship,
213
                  billing_type,
214
                  welcome_session_date,
215
                  status,
216
                  creation_date
217
                ) VALUES (
218
                  :id,
219
                  :login,
220
                  :first_name,
221
                  :last_name,
222
                  :birthday,
223
                  :sex,
224
                  :email,
225
                  :street,
226
                  :postcode,
227
                  :locality,
228
                  :country_id,
229
                  :mobile_phone,
230
                  :phone,
231
                  :remarks,
232
                  :iban,
233
                  :has_insurance,
234
                  :swiss_sailing,
235
                  :swiss_sailing_type,
236
                  :swiss_windsurf_type,
237
                  :receives_newsletter,
238
                  :role,
239
                  :family_relationship,
240
                  :billing_type,
241
                  :welcome_session_date,
242
                  :status,
243
                  :creation_date
244
                )
245
EOT;
246
        $insert = $conn->prepare($insert);
247
248
        $createAccount = <<<EOT
249
                INSERT INTO account(
250
                  owner_id,
251
                  creation_date,
252
                  balance,
253
                  name,
254
                  parent_id,
255
                  type,
256
                  code
257
                ) VALUES (
258
                  :owner,
259
                  NOW(),
260
                  :balance,
261
                  :name,
262
                  10011, -- Passifs -> 2030 Acomptes de clients
263
                  'liability',
264
                  :code
265
                )
266
EOT;
267
        $createAccount = $conn->prepare($createAccount);
268
269
        foreach ($this->users as $user) {
270
            echo sprintf('Insert user %u (%s %s)', $user['uid'], $user['first_name'], $user['last_name']) . PHP_EOL;
271
            $insert->bindValue(':id', $user['uid']);
272
            $insert->bindValue(':login', $user['new_username']);
273
            $insert->bindValue(':first_name', $user['first_name']);
274
            $insert->bindValue(':last_name', $user['last_name']);
275
            $insert->bindValue(':birthday', $user['date_birth'] !== null && $user['date_birth'] !== '0000-00-00' ? $user['date_birth'] : null);
276
            $insert->bindValue(':sex', $user['sexe'] === 'F' ? 2 : 1);
277
            $insert->bindValue(':email', !empty($user['email']) ? $user['email'] : null);
278
            $insert->bindValue(':street', $user['address']);
279
            $insert->bindValue(':postcode', $user['zip']);
280
            $insert->bindValue(':locality', $user['city']);
281
282
            switch ($user['country']) {
283
                case 'CH': $country_id = 1;
284
285
break;
286
                case 'FR': $country_id = 2;
287
288
break;
289
                case 'DE': $country_id = 10;
290
291
break;
292
                case 'CA': $country_id = 6;
293
294
break;
295
                case 'NL': $country_id = 19;
296
297
break;
298
                default:
299
                    $country_id = null;
300
                    echo sprintf("WARN: pas de correspondance pour le code pays %s de l\\'individu %u (%s &s)", $user['country'], $user['uid'], $user['first_name'], $user['last_name']) . PHP_EOL;
301
            }
302
            $insert->bindValue(':country_id', $country_id);
303
304
            $insert->bindValue(':mobile_phone', !empty($user['natel']) ? $user['natel'] : '');
305
            $insert->bindValue(':phone', $user['telephone']);
306
307
            if ($user['uid'] === $user['family_uid']) {
308
                // Si responsable de l'adhésion, fusionne les notes au niveau du membre et de l'individu
309
                $remarks = implode(PHP_EOL, [$this->members[$user['family_uid']]['remarques'], $user['notes']]);
310
            } else {
311
                $remarks = !empty($user['notes']) ? $user['notes'] : '';
312
            }
313
314
            $insert->bindValue(':remarks', $remarks);
315
            $insert->bindValue(':iban', !empty($user['IBAN']) ? $user['IBAN'] : '');
316
317
            $hasInsurance = false;
318
            if (empty($this->members[$user['family_uid']]['assurances'])) {
319
                echo sprintf('WARN: membre %u n\'a aucune assurance', $user['family_uid']) . PHP_EOL;
320
            } elseif (mb_strpos($this->members[$user['family_uid']]['assurances'], 'RC privée') !== false) {
321
                $hasInsurance = true;
322
            }
323
            $insert->bindValue(':has_insurance', $hasInsurance);
324
325
            $insert->bindValue(':swiss_sailing', !empty($user['ichtus_swiss_sailing']) ? $user['ichtus_swiss_sailing'] : '');
326
            switch ($user['ichtus_swiss_sailing_type']) {
327
                case 'A': $swissSailingType = 'active';
328
329
break;
330
                case 'P': $swissSailingType = 'passive';
331
332
break;
333
                case 'J': $swissSailingType = 'junior';
334
335
break;
336
                default: $swissSailingType = null;
337
            }
338
            $insert->bindValue(':swiss_sailing_type', $swissSailingType);
339
340
            switch ($user['ichtus_swiss_windsurf_type']) {
341
                case 'A': $swissWindsurfType = 'active';
342
343
break;
344
                case 'P': $swissWindsurfType = 'passive';
345
346
break;
347
                default: $swissWindsurfType = null;
348
            }
349
            $insert->bindValue(':swiss_windsurf_type', $swissWindsurfType);
350
351
            $insert->bindValue(':receives_newsletter', !empty($user['email']) ? 1 : 0);
352
353
            switch ($user['family_status']) {
354
                case 'chef de famille':
355
                    $relationship = 'householder';
356
                    $role = 'member';
357
358
                    break;
359
                case 'chef(fe) de famille':
360
                    $relationship = 'householder';
361
                    $role = 'member';
362
363
                    break;
364
                case 'conjoint':
365
                    $relationship = 'partner';
366
                    $role = 'individual';
367
368
                    break;
369
                case 'enfant':
370
                    $relationship = 'child';
371
                    $role = 'individual';
372
373
                    break;
374
                case 'parent':
375
                    $relationship = 'parent';
376
                    $role = 'individual';
377
378
                    break;
379
                case 'soeur':
380
                    $relationship = 'sister';
381
                    $role = 'individual';
382
383
                    break;
384
                case 'frère':
385
                    $relationship = 'brother';
386
                    $role = 'individual';
387
388
                    break;
389
                case 'beau-frère':
390
                    $relationship = 'brother';
391
                    $role = 'individual';
392
393
                    break;
394
                default:
395
                    $relationship = 'householder';
396
                    $role = 'individual';
397
                    echo sprintf("WARN: individu %u (%s %s) n'a pas de statut familial", $user['uid'], $user['first_name'], $user['last_name']) . PHP_EOL;
398
            }
399
            if (in_array($user['uid'], [1057, 2738], true)) {
400
                $role = 'administrator';
401
            } elseif (!empty($user['ichtus_comite_fonction'])) {
402
                $role = 'responsible';
403
            }
404
            $insert->bindValue(':role', $role);
405
            $insert->bindValue(':family_relationship', $relationship);
406
407
            if ($this->members[$user['family_uid']]['envoi_papier'] && empty($user['email'])) {
408
                $insert->bindValue(':billing_type', 'paper');
409
            } else {
410
                $insert->bindValue(':billing_type', 'electronic');
411
            }
412
            $insert->bindValue(':welcome_session_date', $this->members[$user['family_uid']]["date_séance d'accueil"]);
413
414
            $userStatus = 'new';
415
            if ($user['status_new'] + $user['status_actif'] + $user['status_archived'] > 1) {
416
                echo sprintf('WARN individu %u (%s %s) a plus d\' un statut actif à la fois', $user['uid'], $user['first_name'], $user['last_name']) . PHP_EOL;
417
            }
418
            if ($user['status_actif']) {
419
                $userStatus = 'active';
420
            } elseif ($user['status_archived']) {
421
                $userStatus = 'archived';
422
            }
423
            $insert->bindValue(':status', $userStatus);
424
425
            $insert->bindValue(':creation_date', $this->members[$user['family_uid']]['date_entrée ichtus']);
426
427
            if ($insert->execute() === false) {
428
                echo sprintf('ERROR: création de l\'individu %u (%s %s)', $user['uid'], $user['first_name'], $user['last_name']) . PHP_EOL;
429
430
                continue;
431
            }
432
433
            // Crée un compte débiteur pour le membre
434
            $createAccount->bindValue(':owner', $user['uid']);
435
            $createAccount->bindValue(':name', implode(' ', [$user['first_name'], $user['last_name']]));
436
            $accountNumber = sprintf('2030%04u', $user['uid']); // 2030 (Acomptes de client) & ID User = numéro de compte unique
437
            $createAccount->bindValue(':code', $accountNumber);
438
            $createAccount->bindValue(':balance', 0.00); // Importer le solde des comptes 2018 ?
439
            if ($createAccount->execute() === false) {
440
                echo sprintf('ERROR: échec de création de compte débiteur n°%u pour l\'utilisateur %u (%s %s)', $accountNumber, $user['uid'], $user['first_name'], $user['last_name']) . PHP_EOL;
441
            }
442
        }
443
444
        $updateOwner = $conn->prepare('UPDATE user SET owner_id=:owner WHERE id=:id');
445
        foreach ($this->users as $user) {
446
            if ($user['family_uid'] && $user['family_uid'] !== $user['uid']) {
447
                // Update family ownership
448
                $updateOwner->bindValue(':owner', $user['family_uid']);
449
                $updateOwner->bindValue(':id', $user['uid']);
450
                $updateOwner->execute();
451
            }
452
        }
453
    }
454
455
    public function loadStorageRequests(): void
456
    {
457
        $this->connectTypo3();
458
        $query = 'SELECT * FROM tx_speciality_storage_places';
459
        $statement = $this->typo3->prepare($query);
460
461
        if ($statement->execute()) {
462
            echo sprintf('%u demandes d\'emplacement de stockage à importer...', $statement->rowCount()) . PHP_EOL;
463
            foreach ($statement->fetchAll(\PDO::FETCH_ASSOC) as $request) {
464
                if (!array_key_exists($request['uid_link'], $this->members)) {
465
                    echo sprintf('WARN: demande de stockage %u pour membre %u (%s %s) introuvable', $request['uid'], $request['uid_link'], $request['first_name'], $request['last_name']) . PHP_EOL;
466
                }
467
                $this->storage[$request['uid_link']] = $request;
468
            }
469
        }
470
    }
471
472
    /**
473
     * Create bookables (storage lockers, cabinets, space for boats)
474
     */
475
    private function insertBookables(): void
476
    {
477
        $conn = $this->entityManager->getConnection();
478
479
        $insert = <<<EOT
480
                INSERT INTO bookable(
481
                  code,
482
                  name,
483
                  description,
484
                  initial_price,
485
                  periodic_price,
486
                  simultaneous_booking_maximum,
487
                  booking_type,
488
                  creation_date
489
                ) VALUES (
490
                  :code,
491
                  :name,
492
                  :description,
493
                  :initial_price,
494
                  :periodic_price,
495
                  :simultaneous_booking_maximum,
496
                  :booking_type,
497
                  NOW()
498
                )
499
EOT;
500
501
        $insert = $conn->prepare($insert);
502
503
        // Armoires
504
        $insert->bindValue(':initial_price', 0);
505
        $insert->bindValue(':periodic_price', 50);
506
        // Une armoire peut être partagée entre 2 membres
507
        $insert->bindValue(':simultaneous_booking_maximum', 2);
508
        $insert->bindValue(':booking_type', 'admin_approved');
509
        $insert->bindValue(':description', 'Armoire (50 x 200 x 70 cm)');
510
511
        for ($i = 1; $i <= 120; ++$i) {
512
            $insert->bindValue(':name', sprintf('Armoire %u', $i));
513
            $insert->bindValue(':code', sprintf('STVA%u', $i));
514
            $insert->execute();
515
        }
516
517
        // Casiers
518
        $insert->bindValue(':periodic_price', 30);
519
        $insert->bindValue(':simultaneous_booking_maximum', 1);
520
        $insert->bindValue(':description', 'Casier (50 x 50 x 70 cm)');
521
        for ($i = 1; $i <= 36; ++$i) {
522
            $insert->bindValue(':name', sprintf('Casier %u', $i));
523
            $insert->bindValue(':code', sprintf('STVC%u', $i));
524
            $insert->execute();
525
        }
526
527
        // Stockage flotteurs
528
        $insert->bindValue(':periodic_price', 50);
529
        $insert->bindValue(':simultaneous_booking_maximum', -1);
530
        $insert->bindValue(':description', 'Stockage sous le local pour un flotteur');
531
        for ($i = 1; $i <= 80; ++$i) {
532
            $insert->bindValue(':name', sprintf('Stockage flotteur %u', $i));
533
            $insert->bindValue(':code', sprintf('STVF%u', $i));
534
            $insert->execute();
535
        }
536
    }
537
538
    /**
539
     * Create periodic bookings for all members
540
     */
541
    private function insertBookings(): void
542
    {
543
        $conn = $this->entityManager->getConnection();
544
545
        $insert = <<<EOT
546
                INSERT INTO booking(
547
                  owner_id,
548
                  creation_date,
549
                  status,
550
                  participant_count,
551
                  start_date
552
                ) VALUES (
553
                  :owner,
554
                  NOW(),
555
                  :status,
556
                  :participant_count,
557
                  NOW()
558
                )
559
EOT;
560
561
        $insert = $conn->prepare($insert);
562
563
        $insert2 = 'INSERT INTO booking_bookable(booking_id, bookable_id) VALUES (:booking, :bookable)';
564
565
        $insert2 = $conn->prepare($insert2);
566
567
        foreach ($this->members as $idMember => $member) {
568
            // Cotisation annuelle
569
            $insert->bindValue(':owner', $idMember);
570
            $insert->bindValue(':status', 'booked');
571
            $insert->bindValue(':participant_count', 1);
572
            $insert->execute();
573
            $insert2->bindValue(':booking', $conn->lastInsertId());
574
            $insert2->bindValue(':bookable', 3006); // Cotisation annuelle
575
            $insert2->execute();
576
577
            // Fond de réparation (optionnel)
578
            if (!empty($member['assurances']) && mb_strpos($member['assurances'], 'Fonds réparation') !== false) {
579
                $insert->execute();
580
                $insert2->bindValue(':booking', $conn->lastInsertId());
581
                $insert2->bindValue(':bookable', 3026); // Fonds de réparation interne
582
                $insert2->execute();
583
            }
584
585
            // Adhésion NFT (optionnel)
586
            if (!empty($this->users[$idMember]['ichtus_NFT'])) {
587
                $insert->execute();
588
                $insert2->bindValue(':booking', $conn->lastInsertId());
589
                $insert2->bindValue(':bookable', 3004); // Cotisation NFT
590
                $insert2->execute();
591
            }
592
        }
593
594
        // Attribution des emplacements de stockage
595
        $selectBookableByName = $conn->prepare('SELECT id, name, simultaneous_booking_maximum FROM bookable WHERE name=:name');
596
        foreach ($this->storage as $request) {
597
            if (empty($request['uid_link']) || !array_key_exists($request['uid_link'], $this->members)) {
598
                echo sprintf('ERROR: UID membre de %s %s inconnu dans fichier de demande de stockage', $request['first_name'], $request['last_name']) . PHP_EOL;
599
600
                continue;
601
            }
602
            $insert->bindValue(':owner', $request['uid_link']);
603
            foreach ([1 => 'Armoire %u', 2 => 'Armoire %u', 3 => 'Casier %u', 4 => 'Stockage floteur %u'] as $index => $bookableName) {
604
                if ($request["materiel{$index}"] > 0 && !empty($request["materiel{$index}attrib"])) {
605
                    $selectBookableByName->bindValue(':name', sprintf($bookableName, $request["materiel{$index}attrib"]));
606
                    $bookable = null;
607
                    if ($selectBookableByName->execute() && $selectBookableByName->rowCount() === 1) {
608
                        $bookable = $selectBookableByName->fetch(\PDO::FETCH_ASSOC);
609
                    }
610
                    if ($bookable) {
611
                        $insert->execute();
612
                        $insert2->bindValue(':booking', $conn->lastInsertId());
613
                        $insert2->bindValue(':bookable', $bookable['id']);
614
                        $insert2->execute();
615
                        if (!array_key_exists($bookable['id'], $this->storageAllocated)) {
616
                            $this->storageAllocated[$bookable['id']] = 1;
617
                        } else {
618
                            $this->storageAllocated[$bookable['id']] += 1;
619
                        }
620
                        echo sprintf('%s attribué à %s %s', $bookable['name'], $this->users[$request['uid_link']]['first_name'], $this->users[$request['uid_link']]['last_name']) . PHP_EOL;
621
                        if ($this->storageAllocated[$bookable['id']] > $bookable['simultaneous_booking_maximum']) {
622
                            echo sprintf('WARN: %s attribué %u fois dépassant la limite de %u', $bookable['name'], $this->storageAllocated[$bookable], $bookable['simultaneous_booking_maximum']) . PHP_EOL;
623
                        }
624
                    } else {
625
                        echo sprintf("ERROR: cannot find $bookableName in bookables", $request["materiel{$index}attrib"]) . PHP_EOL;
626
                    }
627
                }
628
            }
629
        }
630
    }
631
632
    /**
633
     * Convert MacRoman string to UTF-8
634
     *
635
     * @param mixed $string
636
     *
637
     * @return string
638
     */
639
    private function fromMacRoman($string): ?string
640
    {
641
        return !empty($string) ? iconv('MacRoman', 'UTF-8', $string) : $string;
642
    }
643
644
    /**
645
     * Delete existing test users prior importing to prevent an ID collision
646
     */
647
    private function deleteTestUsers(): void
648
    {
649
        $conn = $this->entityManager->getConnection();
650
        $result = $conn->executeQuery('SELECT id FROM account a where a.owner_id >= 1000 AND a.owner_id <= 1014');
651
        $accounts = $result->fetchAll(\PDO::FETCH_COLUMN);
652
        $stmt = $conn->prepare('DELETE tl, t FROM transaction_line tl JOIN transaction t ON tl.transaction_id = t.id WHERE FIND_IN_SET(CAST(tl.debit_id as char), :accounts) OR FIND_IN_SET(CAST(tl.credit_id as char), :accounts)');
653
        $stmt->bindValue('accounts', implode(',', $accounts));
654
        $stmt->execute();
655
        $stmt = $conn->prepare('DELETE FROM account WHERE FIND_IN_SET(CAST(id as char), :accounts)');
656
        $stmt->bindValue('accounts', implode(',', $accounts));
657
        $stmt->execute();
658
        $stmt = $conn->prepare('DELETE FROM message WHERE (creator_id >= 1000 AND creator_id <= 1014) OR (owner_id >= 1000 AND owner_id <= 1014)');
659
        $stmt->execute();
660
        $stmt = $conn->prepare('DELETE FROM user_tag WHERE (creator_id >= 1000 AND creator_id <= 1014) OR (owner_id >= 1000 AND owner_id <= 1014)');
661
        $stmt->execute();
662
        $stmt = $conn->prepare('DELETE FROM user_tag WHERE (creator_id >= 1000 AND creator_id <= 1014) OR (owner_id >= 1000 AND owner_id <= 1014)');
663
        $stmt->execute();
664
        $stmt = $conn->prepare('DELETE FROM expense_claim WHERE (creator_id >= 1000 AND creator_id <= 1014) OR (owner_id >= 1000 AND owner_id <= 1014)');
665
        $stmt->execute();
666
        $stmt = $conn->prepare('DELETE FROM booking WHERE (creator_id >= 1000 AND creator_id <= 1014) OR (owner_id >= 1000 AND owner_id <= 1014)');
667
        $stmt->execute();
668
        $stmt = $conn->prepare('SET FOREIGN_KEY_CHECKS=0; DELETE FROM user WHERE id >= 1000 AND id <= 1014; SET FOREIGN_KEY_CHECKS=1;');
669
        $stmt->execute();
670
    }
671
}
672