organization.php 68 KB
Newer Older
Prosper De Laure's avatar
Prosper De Laure committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
/*
 * Copyright (C) 2015 Maarch
 *
 * This file is part of bundle organization.
 *
 * Bundle organization is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Bundle organization is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with bundle organization.  If not, see <http://www.gnu.org/licenses/>.
 */
namespace bundle\organization\Controller;
21

22
use core\Exception;
Prosper De Laure's avatar
Prosper De Laure committed
23
24
25
26
27

/**
 * Control of the organization
 *
 * @package Organization
28
 * @author  Prosper De Laure <prosper.delaure@maarch.org>
Prosper De Laure's avatar
Prosper De Laure committed
29
30
31
32
 */
class organization
{
    protected $sdoFactory;
33
    protected $csv;
34
    protected $accountController;
35
    protected $hasSecurityLevel;
Prosper De Laure's avatar
Prosper De Laure committed
36
37
38

    /**
     * Constructor
Alexis Ragot's avatar
Alexis Ragot committed
39
     * @param \dependency\sdo\Factory $sdoFactory The dependency sdo factory service
40
     * @param \dependency\csv\Csv     $csv        The dependency csv
Prosper De Laure's avatar
Prosper De Laure committed
41
42
43
     *
     * @return void
     */
44
    public function __construct(\dependency\sdo\Factory $sdoFactory, \dependency\csv\Csv $csv = null)
Prosper De Laure's avatar
Prosper De Laure committed
45
46
    {
        $this->sdoFactory = $sdoFactory;
47
        $this->csv = $csv;
48
        $this->accountController = \laabs::newController('auth/userAccount');
49
        $this->hasSecurityLevel = isset(\laabs::configuration('auth')['useSecurityLevel']) ? (bool) \laabs::configuration('auth')['useSecurityLevel'] : false;
Prosper De Laure's avatar
Prosper De Laure committed
50
51
52
53
    }

    /**
     * Index of organizations
54
55
     *
     * @param integer $limit Maximal number of results to dispay
Jerome Boucher's avatar
Jerome Boucher committed
56
     * @param string  $query The query of the index
Prosper De Laure's avatar
Prosper De Laure committed
57
     *
Dylan's avatar
Dylan committed
58
     * @return organization/organization[] An array of organization
Prosper De Laure's avatar
Prosper De Laure committed
59
     */
60
    public function index($limit = null, $query = null)
Prosper De Laure's avatar
Prosper De Laure committed
61
    {
62
        return $this->sdoFactory->index("organization/organization", array("orgId", "displayName", "isOrgUnit", "registrationNumber", "parentOrgId", "ownerOrgId"), $query, null, null, $limit);
Prosper De Laure's avatar
Prosper De Laure committed
63
64
    }

Dylan's avatar
Dylan committed
65
66
67
    /**
     * List of organizations
     *
68
69
70
     * @param bool $ownerOrg
     * @param bool $orgUnit
     *
Dylan's avatar
Dylan committed
71
     * @return organization/organization[] An array of organization whith service
Dylan's avatar
Dylan committed
72
     */
73
    public function todisplay($ownerOrg, $orgUnit)
Dylan's avatar
Dylan committed
74
    {
75
76
77
        $authController = \laabs::newController("auth/userAccount");
        $user = $authController->get(\laabs::getToken('AUTH')->accountId);

Dylan's avatar
Dylan committed
78
        $currentOrg = \laabs::getToken("ORGANIZATION");
79
        $orgList = [];
Dylan's avatar
Dylan committed
80

81
        if (!$currentOrg || (!empty($currentOrg->orgRoleCodes) && in_array('owner', $currentOrg->orgRoleCodes))) {
82
            $orgUnitList = $this->getOwnerOriginatorsOrgs();
Dylan's avatar
Dylan committed
83
84
        } else {
            $orgUnitList = $this->getOwnerOriginatorsOrgs($currentOrg);
Dylan's avatar
Dylan committed
85
86
        }

87
        foreach ($orgUnitList as $org) {
Dylan's avatar
Dylan committed
88
            $organization = \laabs::newInstance('organization/organization');
89
90
91
            $organization->displayName = $org->displayName;
            $organization->orgId = $org->orgId;
            $organization->parentOrgId = $org->parentOrgId;
Dylan's avatar
Dylan committed
92

93
94
95
96
97
98
99
100
101
102
            if ($ownerOrg) {
                $orgList[] = $organization;
            }

            if ($orgUnit) {
                foreach ($org->originators as $orgUnit) {
                    if ($org->orgId == $orgUnit->ownerOrgId) {
                        $orgUnit->ownerOrgName = $org->displayName;
                        $orgList[] = $orgUnit;
                    }
Dylan's avatar
Dylan committed
103
104
105
106
                }
            }
        }

Alexandre Morin's avatar
Alexandre Morin committed
107
108
109
110
111
112
113
        if (isset($orgList)) {
            foreach ($orgList as $org) {
                foreach ($orgList as $orgParent) {
                    if (isset($org->parentOrgId)) {
                        if ($org->parentOrgId == $orgParent->orgId) {
                            $org->parentOrgName = $orgParent->displayName;
                        }
114
115
116
                    }
                }
            }
Alexandre Morin's avatar
Alexandre Morin committed
117
        }
Dylan's avatar
#6998    
Dylan committed
118
119
120
        return $orgList;
    }

121
122
    public function search($term = null, $enabled = "all")
    {
Alexandre Morin's avatar
Alexandre Morin committed
123
        $user = $this->accountController->get(\laabs::getToken('AUTH')->accountId);
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

        $currentOrg = \laabs::getToken("ORGANIZATION");
        $owner = true;

        if (isset($currentOrg)) {
            if (!$currentOrg->orgRoleCodes) {
                $owner = false;
            } elseif (is_array($currentOrg->orgRoleCodes) && !in_array('owner', $currentOrg->orgRoleCodes)) {
                $owner = false;
            }
        }

        $queryParts = array();
        $queryParams = array();

139
140
141
142
        $securityLevel = null;
        if ($this->hasSecurityLevel) {
            $securityLevel = $user->getSecurityLevel();
        }
143
144
145
146
147
148
        if ($securityLevel == $user::SECLEVEL_GENADMIN) {
            $queryParams['isOrgUnit'] = 'false';
            $queryParts['isOrgUnit'] = "isOrgUnit=:isOrgUnit";
        }

        if ($term) {
149
150
151
            $queryParts['term'] = "(registrationNumber ='*".$term."*'
            OR orgName = '*".$term."*'
            OR displayName = '*".$term."*'
152
153
154
            OR parentOrgId = '*".$term."*')";
        }

155
        if ($enabled !== 'all') {
156
157
158
159
160
161
            $queryParams['enabled'] = $enabled;
            $queryParts['enabled'] = "enabled=:enabled";
        }

        $queryString = "";
        if (count($queryParts)) {
162
            $queryString = implode(' AND ', $queryParts);
163
164
        }

Alexandre Morin's avatar
Alexandre Morin committed
165
        $length = \laabs::configuration('presentation.maarchRM')['maxResults'];
166
167
168
169
170
171
        $organizationList = $this->sdoFactory->find("organization/organization", $queryString, $queryParams, null, 0, $length);
        $organizationList = \laabs::castMessageCollection($organizationList, "organization/organizationList");

        if ($term || $enabled !== 'all') {
            $organizations = [];
            foreach ($organizationList as $organization) {
Alexandre Morin's avatar
Alexandre Morin committed
172
173
                $parentOrgId = (string)$organization->parentOrgId;

174
175
176
177
178
179
                if ($user->ownerOrgId && $organization->ownerOrgId != $user->ownerOrgId) {
                    if (empty($parentOrgId) && $organization->orgId != $user->ownerOrgId) {
                        continue;
                    }
                }

Alexandre Morin's avatar
Alexandre Morin committed
180
                if ($parentOrgId) {
181
182
183
                    $organization->parentOrgName = $this->sdoFactory->index(
                        'organization/organization',
                        ['displayName'],
Alexandre Morin's avatar
Alexandre Morin committed
184
185
                        "orgId='". $parentOrgId . "'"
                    )[$parentOrgId];
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
                }
                $organizations[] = $organization;
            }

            return $organizations;
        }

        $tree = array();
        $organizationByParent = array();
        foreach ($organizationList as $organization) {
            $parentOrgId = (string)$organization->parentOrgId;

            if ($user->ownerOrgId && $organization->ownerOrgId != $user->ownerOrgId) {
                if (empty($parentOrgId) && $organization->orgId != $user->ownerOrgId) {
                    continue;
                }
            }

            if (empty($parentOrgId) && $owner) {
                $tree[] = $organization;
                continue;
Alexandre Morin's avatar
Alexandre Morin committed
207
208
209
            } elseif (!$owner && (
                (string)$organization->orgId == (string)$currentOrg->ownerOrgId)
                || (string)$organization->orgId == (string) $user->ownerOrgId) {
210
211
212
213
214
215
216
217
218
219
220
                $tree[] = $organization;
                continue;
            }

            if (!isset($organizationByParent[$parentOrgId])) {
                $organizationByParent[$parentOrgId] = array();
            }

            $organization->parentOrgName = $this->sdoFactory->index(
                'organization/organization',
                ['displayName'],
Alexandre Morin's avatar
Alexandre Morin committed
221
222
                "orgId='". $parentOrgId . "'"
            )[$parentOrgId];
223
224
225
226
227
228
            $organizationByParent[$parentOrgId][] = $organization;
        }

        return $this->buildTree($tree, $organizationByParent);
    }

Prosper De Laure's avatar
Prosper De Laure committed
229
230
231
232
233
234
235
236
237
    /**
     * Get organizations tree
     *
     * @return organization/organizationTree[] The tree of organization
     */
    public function getTree()
    {
        $tree = array();

238
239
240
        $authController = \laabs::newController("auth/userAccount");
        $user = $authController->get(\laabs::getToken('AUTH')->accountId);

Prosper De Laure's avatar
Prosper De Laure committed
241
242
243
244
245
246
        $currentOrg = \laabs::getToken("ORGANIZATION");
        $owner = true;

        if (isset($currentOrg)) {
            if (!$currentOrg->orgRoleCodes) {
                $owner = false;
247
            } elseif (is_array($currentOrg->orgRoleCodes) && !in_array('owner', $currentOrg->orgRoleCodes)) {
Prosper De Laure's avatar
Prosper De Laure committed
248
249
250
251
                $owner = false;
            }
        }

252
253
254
255
        $securityLevel = null;
        if ($this->hasSecurityLevel) {
            $securityLevel = $user->getSecurityLevel();
        }
256

257
        if ($securityLevel == $user::SECLEVEL_GENADMIN) {
258
259
260
261
262
263
264
265
266
267
268
269
270
271
            $organizationList = $this->sdoFactory->find(
                "organization/organization",
                'isOrgUnit = false',
                [],
                'orgName'
            );
        } else {
            $organizationList = $this->sdoFactory->find(
                "organization/organization",
                null,
                [],
                'orgName'
            );
        }
Prosper De Laure's avatar
Prosper De Laure committed
272
273
274
275
276
        $organizationList = \laabs::castMessageCollection($organizationList, "organization/organizationTree");

        // sort organization by parentOrgId
        $organizationByParent = array();
        foreach ($organizationList as $organization) {
277
            $parentOrgId = (string)$organization->parentOrgId;
Prosper De Laure's avatar
Prosper De Laure committed
278
279
280
281

            if (empty($parentOrgId) && $owner) {
                $tree[] = $organization;
                continue;
Alexandre Morin's avatar
Alexandre Morin committed
282
283
284
            } elseif (!$owner && (
                    (string)$organization->orgId == (string)$currentOrg->ownerOrgId)
                || (string)$organization->orgId == (string) $user->ownerOrgId) {
Prosper De Laure's avatar
Prosper De Laure committed
285
286
287
288
                $tree[] = $organization;
                continue;
            }

289
290
291
292
293
294
            if ($user->ownerOrgId && $organization->ownerOrgId != $user->ownerOrgId) {
                if (empty($parentOrgId) && $organization->orgId != $user->ownerOrgId) {
                    continue;
                }
            }

Prosper De Laure's avatar
Prosper De Laure committed
295
296
297
298
299
300
301
302
303
304
305
            if (!isset($organizationByParent[$parentOrgId])) {
                $organizationByParent[$parentOrgId] = array();
            }
            $organizationByParent[$parentOrgId][] = $organization;
        }

        return $this->buildTree($tree, $organizationByParent);
    }

    /**
     * Set positions for the organization tree
306
307
     * @param object $roots            The organization tree roots
     * @param array  $organizationList The list of organization sorted by parent organization
308
     *
Dylan's avatar
Dylan committed
309
     * @return object[]
Prosper De Laure's avatar
Prosper De Laure committed
310
311
312
313
     */
    protected function buildTree($roots, $organizationList)
    {
        foreach ($roots as $organization) {
314
            $orgId = (string)$organization->orgId;
Prosper De Laure's avatar
Prosper De Laure committed
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

            if (isset($organizationList[$orgId])) {
                $organization->organization = $this->buildTree($organizationList[$orgId], $organizationList);
            }
        }

        return $roots;
    }

    /**
     * Create an organization
     * @param organization/organization $organization The organization object to create
     *
     * @return string the new organization's Id
     */
    public function create($organization)
    {
332
        if ($organization->isOrgUnit) {
333
            $this->accountController->isAuthorized(['func_admin', 'user']);
334
        } else {
335
            $this->accountController->isAuthorized('gen_admin');
336
        }
337

338
        $user = $this->accountController->get(\laabs::getToken('AUTH')->accountId);
339
340

        if (!$organization->parentOrgId && !in_array($user->accountName, \laabs::configuration("auth")["adminUsers"])) {
341
342
343
344
345
346
347
348
349
            if (\laabs::getToken("ORGANIZATION")) {
                if (!in_array('owner', \laabs::getToken("ORGANIZATION")->orgRoleCodes)) {
                    throw new \core\Exception("You're not allowed to create an organization");
                }
            } else {
                throw new \core\Exception("You're not allowed to create an organization");
            }
        }

Prosper De Laure's avatar
Prosper De Laure committed
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
        try {
            if (empty($organization->displayName)) {
                $organization->displayName = $organization->orgName;
            }

            $organization->orgId = \laabs::newId();
            $this->sdoFactory->create($organization, 'organization/organization');
        } catch (\Exception $e) {
            throw new \core\Exception("Key already exists");
        }

        return $organization->orgId;
    }

    /**
     * Read an organization by his orgId
     * @param string $orgId The Identifier of the organization to read
     *
     * @return organization/organization the organization
     */
    public function read($orgId)
    {
        $organization = $this->sdoFactory->read("organization/organization", $orgId);
        $organization->users = $this->readUserPositions($orgId);
        $organization->services = $this->readServicePositions($orgId);
        $organization->contacts = $this->getContacts($orgId);
376
        $organization->archivalProfileAccess = $this->sdoFactory->find('organization/archivalProfileAccess', "orgId='$orgId'");
Prosper De Laure's avatar
Prosper De Laure committed
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

        return \laabs::castMessage($organization, "organization/organization");
    }

    /**
     * Get an organization by his regitration number
     * @param string $registrationNumber The registration number of the organization
     *
     * @return organization/organization the organization
     */
    public function getOrgByRegNumber($registrationNumber)
    {
        $organization = $this->sdoFactory->read("organization/organization", array('registrationNumber' => $registrationNumber));

        return \laabs::castMessage($organization, "organization/organization");
    }

    /**
     * Get organizations by their role
     * @param string $role The role of the organizations
     *
     * @return organization/organization[] the organizations
     */
    public function getOrgsByRole($role)
    {
402
        $organizations = $this->sdoFactory->find("organization/organization", "orgRoleCodes = '*$role*'");
Prosper De Laure's avatar
Prosper De Laure committed
403
404
405
406
407

        return \laabs::castMessageCollection($organizations, "organization/organization");
    }

    /**
408
     * List organizations
Prosper De Laure's avatar
Prosper De Laure committed
409
410
     * @param string $role The role of organizations
     *
Dylan's avatar
Dylan committed
411
     * @return organization/organization[] The organizations list
Prosper De Laure's avatar
Prosper De Laure committed
412
413
414
415
416
417
418
419
420
421
422
423
     */
    public function orgList($role = null)
    {
        $queryString = "";

        if ($role) {
            $queryString .= "orgRoleCodes = '*$role*'";
        }

        return $this->sdoFactory->index("organization/organization", array("displayName", "registrationNumber"), $queryString, null, array('registrationNumber'));
    }

424
    /**
425
     * List organizations
Prosper De Laure's avatar
Prosper De Laure committed
426
427
     * @param string $role The role of organizations
     *
Dylan's avatar
Dylan committed
428
     * @return organization/organization[] The organizations list
Prosper De Laure's avatar
Prosper De Laure committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
     */
    public function orgUnitList($role = null)
    {
        $queryString = "";

        if ($role) {
            $queryString .= "orgRoleCodes = '*$role*'";
        }

        $queryString .= "isOrgUnit = 'true'";

        return $this->sdoFactory->index("organization/organization", array("displayName", "registrationNumber"), $queryString, null, array('registrationNumber'));
    }

    /**
     * Get organization's user positions
     * @param string $orgId The organization's identifier
     *
     * @return organization/userPositionTree[] The list of user position
     */
    public function readUserPositions($orgId)
    {
        $users = $this->sdoFactory->find("organization/userPosition", "orgId = '$orgId'");
        $users = \laabs::castMessageCollection($users, 'organization/userPositionTree');

        $userAccountController = \laabs::newController('auth/userAccount');

        foreach ($users as $user) {
457
            $user->displayName = $userAccountController->edit((string)$user->userAccountId)->displayName;
Prosper De Laure's avatar
Prosper De Laure committed
458
459
460
461
462
        }

        return $users;
    }

Dylan's avatar
Dylan committed
463
464
465
466
467
468
469
470
471
472
    /**
     * Get user positions
     * @param string $accountId The user identifier
     *
     * @return organization/userPositionTree[] The list of user position
     */
    public function readUserOrgs($accountId)
    {
        $users = $this->sdoFactory->find("organization/userPosition", "userAccountId = '$accountId'");
        $users = \laabs::castMessageCollection($users, 'organization/userPositionTree');
Dylan's avatar
Dylan committed
473
        $organizations = $this->sdoFactory->find("organization/organization");
Dylan's avatar
Dylan committed
474
475
476

        foreach ($users as $user) {
            $user->displayName = $this->sdoFactory->read("organization/organization", $user->orgId)->displayName;
Dylan's avatar
Dylan committed
477
478

            foreach ($organizations as $org) {
479
                if ($user->orgId == $org->orgId) {
Dylan's avatar
Dylan committed
480
                    foreach ($organizations as $orgName) {
481
                        if ($org->ownerOrgId == $orgName->orgId) {
Dylan's avatar
Dylan committed
482
                            $user->ownerOrgName = $orgName->displayName;
483
                            $user->ownerOrgId = $orgName->orgId;
Dylan's avatar
Dylan committed
484
485
486
487
                        }
                    }
                }
            }
Dylan's avatar
Dylan committed
488
489
490
491
492
        }

        return $users;
    }

Prosper De Laure's avatar
Prosper De Laure committed
493
494
495
496
497
498
499
500
501
502
503
    /**
     * Get organization's service positions
     * @param string $orgId The organization's identifier
     *
     * @return organization/servicePosition[] The list of service position
     */
    public function readServicePositions($orgId)
    {
        $services = $this->sdoFactory->find("organization/servicePosition", "orgId = '$orgId'");
        $services = \laabs::castMessageCollection($services, 'organization/servicePositionTree');

504
        $userAccountController = \laabs::newController('auth/userAccount');
Prosper De Laure's avatar
Prosper De Laure committed
505
506

        foreach ($services as $service) {
507
            $service->displayName = $userAccountController->edit((string)$service->serviceAccountId)->displayName;
Prosper De Laure's avatar
Prosper De Laure committed
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
        }

        return $services;
    }

    /**
     * Get organization's contacts
     * @param string $orgId The organization's identifier
     *
     * @return organization/orgContact[] The list of service position
     */
    public function readContact($orgId)
    {
        return $this->sdoFactory->find("organization/orgContact", "orgId = '$orgId'");
    }

    /**
     * Update an organization
     * @param string                    $orgId        The organization identifier
     * @param organization/organization $organization The organization object to update
     *
     * @return boolean The result of the operation
     */
    public function update($orgId, $organization)
    {
533
        if ($organization->isOrgUnit) {
534
            $this->accountController->isAuthorized(['func_admin', 'user']);
535
        } else {
536
            $this->accountController->isAuthorized('gen_admin');
537
538
        }

Prosper De Laure's avatar
Prosper De Laure committed
539
540
        $organization->orgId = $orgId;

541
        if ($organization->beginDate > $organization->endDate) {
542
543
            throw new \core\Exception("The end date is lower than the begin date.");
        }
544

545
546

        if (isset($organization->orgRoleCodes) && $organization->orgRoleCodes->contains("owner")) {
547
            if ($this->sdoFactory->count("organization/organization", "registrationNumber!='$organization->registrationNumber' AND orgRoleCodes='*owner*'")) {
548
549
                throw new \core\Exception("An owner is already defined.");
            }
550
551
        }

552
553
554
555
556
        try {
            if ($this->isUsed($organization->registrationNumber)) {
                $originalOrganization = $this->read($orgId);
                $organization->registrationNumber = $originalOrganization->registrationNumber;
            }
557

558
559
560
561
562
563
            if (empty($organization->displayName)) {
                $organization->displayName = $organization->orgName;
            }
            $res = $this->sdoFactory->update($organization, 'organization/organization');
        } catch (\Exception $e) {
            throw new \core\Exception("Key already exists");
Prosper De Laure's avatar
Prosper De Laure committed
564
565
        }

566
        return $res;
Prosper De Laure's avatar
Prosper De Laure committed
567
    }
568

Cyril Vazquez's avatar
Cyril Vazquez committed
569
570
571
572
573
    /**
     * Sets the status of an org unit
     *
     * @param string $orgId  The org identifier
     * @param bool   $status The new status (enabled = true of false)
574
     *
Cyril Vazquez's avatar
Cyril Vazquez committed
575
576
     * @return bool The result of the change
     */
577
578
    public function changeStatus($orgId, $status)
    {
579
580
        $this->accountController->isAuthorized(['func_admin']);

581
582
        $organization = $this->sdoFactory->read('organization/organization', $orgId);

583
584
585
        $accountToken = \laabs::getToken('AUTH');
        $account = $this->sdoFactory->read("auth/account", $accountToken->accountId);

586
587
588
589
        $securityLevel = null;
        if ($this->hasSecurityLevel) {
            $securityLevel = $account->getSecurityLevel();
        }
590
591
592
593
594
595
        if ($securityLevel == $account::SECLEVEL_FUNCADMIN) {
            if ($organization->ownerOrgId != $account->ownerOrgId) {
                throw new \core\Exception\UnauthorizedException("You are not allowed to do this action");
            }
        }

596
597
598
599
600
601
602
603
604
605
606
607
        if (!$organization->isOrgUnit) {
            throw new \core\Exception("An organization can't be disabled.");
        }

        if ($status == "true") {
            $organization->enabled = 1;
        } else {
            $organization->enabled = 0;
        }

        return $this->sdoFactory->update($organization);
    }
Prosper De Laure's avatar
Prosper De Laure committed
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625

    /**
     * Move an organization to a new ownerOrg
     * @param string $orgId          The organization identifier
     * @param string $newParentOrgId The new parent organization identifier
     * @param string $newOwnerOrgId  The new owner organization identifier
     *
     * @return boolean The result of the operation
     */
    public function move($orgId, $newParentOrgId = null, $newOwnerOrgId = null)
    {
        if ($newParentOrgId == "") {
            $newParentOrgId = null;
        }
        if ($newOwnerOrgId == "") {
            $newOwnerOrgId = null;
        }

626
        if ($newParentOrgId) {
627
628
629
630
631
632
633
634
635
636
637
            $oldParentOrgs = $this->readParentOrg($orgId);
            $newParentOrgs = $this->readParentOrg($newParentOrgId);

            $newParentOrg = $this->sdoFactory->read("organization/organization", $newParentOrgId);
            if ($newParentOrg->isOrgUnit) {
                for ($i = 0; $i < count($newParentOrgs); $i++) {
                    if (!$newParentOrgs[$i]->isOrgUnit) {
                        $newParentOrg = $newParentOrgs[$i];
                        break;
                    }
                }
Alexandre Morin's avatar
Alexandre Morin committed
638
639
            }

640
641
642
643
644
            for ($i = 0; $i < count($oldParentOrgs); $i++) {
                if (!$oldParentOrgs[$i]->isOrgUnit) {
                    $oldParentOrg = $oldParentOrgs[$i];
                    break;
                }
Alexandre Morin's avatar
Alexandre Morin committed
645
            }
Alexandre Morin's avatar
Alexandre Morin committed
646

647
648
649
650
651
            if ($oldParentOrg->orgId === null
                || ($oldParentOrg->orgId !== null
                    && $oldParentOrg->orgId != $newParentOrg->orgId
                )
            ) {
652
653
                throw new \core\Exception("Organization can''t be moved to an other organization");
            }
Alexandre Morin's avatar
Alexandre Morin committed
654
655
        }

Prosper De Laure's avatar
Prosper De Laure committed
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
        $organization = $this->sdoFactory->read("organization/organization", $orgId);
        $descendants = $this->sdoFactory->readDescendants("organization/organization", $organization);

        $transactionControl = !$this->sdoFactory->inTransaction();

        if ($transactionControl) {
            $this->sdoFactory->beginTransaction();
        }

        try {
            $organization->parentOrgId = $newParentOrgId;
            $organization->ownerOrgId = $newOwnerOrgId;

            if (!$newOwnerOrgId) {
                $newOwnerOrgId = $orgId;
            }

            foreach ($descendants as $descendantOrg) {
674
                if ((string)$descendantOrg->orgId == $organization->orgId) {
Alexis Ragot's avatar
Alexis Ragot committed
675
                    throw new \bundle\organization\Exception\orgMoveException("Organization can't be moved to a descendent organization");
Prosper De Laure's avatar
Prosper De Laure committed
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
                }

                if ($descendantOrg->isOrgUnit && $descendantOrg->ownerOrgId != $newOwnerOrgId) {
                    $descendantOrg->ownerOrgId = $newOwnerOrgId;
                    $this->sdoFactory->update($descendantOrg, 'organization/organization');
                }
            }

            $this->sdoFactory->update($organization);
        } catch (\Exception $e) {
            throw $e;
        }

        if ($transactionControl) {
            $this->sdoFactory->commit();
        }

        return true;
    }

    /**
     * Delete an organization
     * @param string $orgId The organization id
     *
     * @return boolean The restult of the operation
     */
    public function delete($orgId)
    {
        $organization = $this->sdoFactory->read("organization/organization", $orgId);
705
        if ($organization->isOrgUnit) {
706
            $this->accountController->isAuthorized(['func_admin', 'user']);
707
        } else {
708
            $this->accountController->isAuthorized('gen_admin');
709
        }
710
711
712
713
714

        $transactionControl = !$this->sdoFactory->inTransaction();

        if ($transactionControl) {
            $this->sdoFactory->beginTransaction();
715
716
        }

717
718
        try {
            if ($this->isUsed($organization->registrationNumber)) {
719
720
721
722
723
724
                throw new \core\Exception\ForbiddenException(
                    "The organization %s is used in archives.",
                    403,
                    null,
                    [$organization->registrationNumber]
                );
725
726
            }

727
728
729
730
            $controlAuthorities = $this->sdoFactory->find(
                'medona/controlAuthority',
                "originatorOrgUnitId = '$orgId' OR controlAuthorityOrgUnitId = '$orgId'"
            );
Cyril Vazquez's avatar
Cyril Vazquez committed
731
            if (count($controlAuthorities) > 0) {
732
733
734
735
736
737
                throw new \core\Exception\ForbiddenException(
                    "The organization %s is used in control authority.",
                    403,
                    null,
                    [$organization->registrationNumber]
                );
738
            }
739

740
741
742
743
744
            $children = $this->sdoFactory->readChildren("organization/organization", $organization);
            $users = $this->sdoFactory->readChildren("organization/userPosition", $organization);
            $services = $this->sdoFactory->readChildren("organization/servicePosition", $organization);
            $contacts = $this->sdoFactory->readChildren("organization/orgContact", $organization);
            $this->sdoFactory->deleteChildren("organization/archivalProfileAccess", $organization);
745

746
            foreach ($contacts as $contact) {
747
                $this->deleteContactPosition($contact->contactId, (string)$organization->orgId);
748
749
750
            }

            foreach ($children as $child) {
751
752
753
754
                $controlAuthorities = $this->sdoFactory->find(
                    'medona/controlAuthority',
                    "originatorOrgUnitId = '$child->orgId' OR controlAuthorityOrgUnitId = '$child->orgId'"
                );
Cyril Vazquez's avatar
Cyril Vazquez committed
755
                if (count($controlAuthorities) > 0) {
756
757
758
759
760
                    throw new \core\Exception\ForbiddenException(
                        "The child organization is used in control authority.",
                        403,
                        null
                    );
761
                }
762
                $this->delete($child->orgId);
763
764
            }

765
766
767
768
769
770
771
772
773
774
775
776
777
778
            foreach ($users as $user) {
                $this->sdoFactory->delete($user);
            }
            foreach ($services as $service) {
                $this->sdoFactory->delete($service);
            }

            $this->sdoFactory->delete($organization);
        } catch (\Exception $exception) {
            if ($transactionControl) {
                $this->sdoFactory->rollback();
            }

            throw $exception;
Prosper De Laure's avatar
Prosper De Laure committed
779
        }
780
781
782

        if ($transactionControl) {
            $this->sdoFactory->commit();
Prosper De Laure's avatar
Prosper De Laure committed
783
784
785
        }


786
787

        return true;
Prosper De Laure's avatar
Prosper De Laure committed
788
789
790
791
792
793
794
795
796
797
798
799
    }

    /**
     * Add a user position to an organization
     * @param string $userAccountId The user account identifier
     * @param string $orgId         The organization identifier
     * @param string $function      The function of the user
     *
     * @return boolean The result of the operation
     */
    public function addUserPosition($userAccountId, $orgId, $function = null)
    {
800
        $this->accountController->isAuthorized('func_admin');
801

Prosper De Laure's avatar
Prosper De Laure committed
802
803
804
805
806
        $userPosition = \laabs::newInstance('organization/userPosition');
        $userPosition->userAccountId = $userAccountId;
        $userPosition->orgId = $orgId;
        $userPosition->function = $function;
        $userPosition->default = false;
807
808
809
810
        $userDefaultPosition = $this->sdoFactory->find(
            'organization/userPosition',
            "userAccountId = '$userAccountId' AND default = true"
        );
Prosper De Laure's avatar
Prosper De Laure committed
811
812
813
814

        if (empty($userDefaultPosition)) {
            $userPosition->default = true;
        }
815

Prosper De Laure's avatar
Prosper De Laure committed
816
817
818
        return $this->sdoFactory->create($userPosition, 'organization/userPosition');
    }

Dylan's avatar
Dylan committed
819
820
    /**
     * Delete an archival pofile accesss from every organization
Dylan's avatar
Dylan committed
821
822
     * @param string $userAccountId The user account identifier
     * @param string $orgId         The organization identifier
Dylan's avatar
Dylan committed
823
824
825
826
827
     *
     * @return bool The result of the operation
     */
    public function updateUserPosition($userAccountId, $orgId = null)
    {
828
        $this->accountController->isAuthorized('func_admin');
829

Dylan's avatar
Dylan committed
830
831
832
833
834
835
836
837
838
839
        $userPositions = $this->sdoFactory->find("organization/userPosition", "userAccountId='$userAccountId'");
        $default = null;

        foreach ($userPositions as $userPosition) {
            if ($userPosition->default) {
                $default = $userPosition->orgId;
            }
        }

        try {
840
            if ($userPositions) {
Dylan's avatar
Dylan committed
841
842
843
                $this->sdoFactory->deleteCollection($userPositions, "organization/userPosition");
            }

844
            foreach ($orgId as $id) {
Dylan's avatar
Dylan committed
845
846
847
848
                $userPosition = \laabs::newInstance('organization/userPosition');
                $userPosition->userAccountId = $userAccountId;
                $userPosition->orgId = $id;

849
                if ($id == $default) {
Dylan's avatar
Dylan committed
850
                    $userPosition->default = true;
851
                } else {
Dylan's avatar
Dylan committed
852
853
854
                    $userPosition->default = false;
                }

855
                $userPosition = $this->sdoFactory->create($userPosition, 'organization/userPosition');
Dylan's avatar
Dylan committed
856
857
858
859
860
861
862
863
864
            }
        } catch (Exception $e) {
            $this->sdoFactory->rollback();
            throw $e;
        }

        return $userPosition;
    }

Jerome Boucher's avatar
Jerome Boucher committed
865
866


Prosper De Laure's avatar
Prosper De Laure committed
867
868
869
    /**
     * Add a service position to an organization
     * @param string $orgId            The organization identifier
870
     * @param string $serviceAccountId The service account identifier
Prosper De Laure's avatar
Prosper De Laure committed
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
     *
     * @return boolean The result of the operation
     */
    public function addServicePosition($orgId, $serviceAccountId)
    {
        $servicePosition = \laabs::newInstance('organization/servicePosition');
        $servicePosition->serviceAccountId = $serviceAccountId;
        $servicePosition->orgId = $orgId;

        return $this->sdoFactory->create($servicePosition);
    }

    /**
     * Set default user position for an user
     * @param string $orgId         The organization identifier
     * @param string $userAccountId The service account identifier
     *
     * @return boolean The result of the operation
     */
    public function setDefaultUserPosition($orgId, $userAccountId)
    {
892
893
        $previousDefaultUserPosition = $this->sdoFactory->find(
            'organization/userPosition', "userAccountId='$userAccountId' AND default=true");
Prosper De Laure's avatar
Prosper De Laure committed
894
895
896
897
898
899
900

        if (!empty($previousDefaultUserPosition)) {
            $previousDefaultUserPosition = $previousDefaultUserPosition[0];
            $previousDefaultUserPosition->default = false;
            $this->sdoFactory->update($previousDefaultUserPosition, 'organization/userPosition');
        }

901
902
903
904
        $userPosition = $this->sdoFactory->read(
            "organization/userPosition",
            array("userAccountId" => $userAccountId, "orgId" => $orgId)
        );
Prosper De Laure's avatar
Prosper De Laure committed
905
906
907
908
909
910
911
912
913
914
        $userPosition->default = true;

        return $this->sdoFactory->update($userPosition, 'organization/userPosition');
    }

    /**
     * Remove a user's position
     * @param string $userAccountId The user account identifier
     * @param string $orgId         The organization account identifier
     *
Dylan's avatar
Dylan committed
915
     * @return boolean The result of the operation
Prosper De Laure's avatar
Prosper De Laure committed
916
917
918
     */
    public function deleteUserPosition($userAccountId, $orgId)
    {
919
        $this->accountController->isAuthorized('func_admin');
920

921
922
923
924
        $userPosition = $this->sdoFactory->read(
            "organization/userPosition",
            array("userAccountId" => $userAccountId, "orgId" => $orgId)
        );
Prosper De Laure's avatar
Prosper De Laure committed
925
926

        if ($userPosition->default) {
927
928
929
930
            $newDefaultUserPosition = $this->sdoFactory->find(
                'organization/userPosition',
                "userAccountId='$userAccountId'"
            );
Prosper De Laure's avatar
Prosper De Laure committed
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

            if (!empty($newDefaultUserPosition)) {
                $newDefaultUserPosition = $newDefaultUserPosition[0];
                $newDefaultUserPosition->default = true;

                $this->sdoFactory->update($newDefaultUserPosition, 'organization/userPosition');
            }
        }

        return $this->sdoFactory->delete($userPosition);
    }

    /**
     * Remove a contact's position
     * @param string $contactId The user account identifier
     * @param string $orgId     The organization account identifier
     *
Dylan's avatar
Dylan committed
948
     * @return boolean The result of the operation
Prosper De Laure's avatar
Prosper De Laure committed
949
950
951
     */
    public function deleteContactPosition($contactId, $orgId)
    {
952
953
954
955
        $contactPosition = $this->sdoFactory->read(
            "organization/orgContact",
            array("contactId" => $contactId, "orgId" => $orgId)
        );
Prosper De Laure's avatar
Prosper De Laure committed
956
957

        $contactController = \laabs::newController('contact/contact');
958
        $this->sdoFactory->delete($contactPosition);
Prosper De Laure's avatar
Prosper De Laure committed
959

960
        return $contactController->delete($contactId);
Prosper De Laure's avatar
Prosper De Laure committed
961
962
963
964
965
966
967
    }

    /**
     * Remove a service's position
     * @param string $orgId            The organization account identifier
     * @param string $serviceAccountId The service account identifier
     *
Dylan's avatar
Dylan committed
968
     * @return boolean The result of the operation
Prosper De Laure's avatar
Prosper De Laure committed
969
970
971
     */
    public function deleteServicePosition($orgId, $serviceAccountId)
    {
972
973
974
975
        $servicePosition = $this->sdoFactory->read(
            "organization/servicePosition",
            array("serviceAccountId" => $serviceAccountId, "orgId" => $orgId)
        );
Prosper De Laure's avatar
Prosper De Laure committed
976
977
978
979
980
981
982
983

        return $this->sdoFactory->delete($servicePosition);
    }

    /**
     * Get organization contacts
     * @param id $orgId
     *
Dylan's avatar
Dylan committed
984
     * @return contact/contact[] Array of  contact/contact object
Prosper De Laure's avatar
Prosper De Laure committed
985
986
987
988
989
990
991
     */
    public function getContacts($orgId)
    {
        $orgContacts = $this->sdoFactory->find('organization/orgContact', "orgId='$orgId'");

        $contacts = array();
        foreach ($orgContacts as $orgContact) {
992
            try {
993
994
                $contactController = \laabs::newController('contact/contact');
                $contact = $contactController->get($orgContact->contactId);
995
                $contacts[] = (object)array_merge((array)$contact, (array)$orgContact);
Prosper De Laure's avatar
Prosper De Laure committed
996
997
998
999
1000
            } catch (\Exception $e) {

            }
        }