Failed Conditions
Push — master ( 893dc8...0c1f2a )
by Adrien
06:01
created

User::getReceivesNewsletter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Model;
6
7
use Application\DBAL\Types\BillingTypeType;
8
use Application\DBAL\Types\BookingStatusType;
9
use Application\DBAL\Types\RelationshipType;
10
use Application\Repository\LogRepository;
11
use Application\Repository\UserRepository;
12
use Application\Service\Role;
13
use Application\Traits\HasAddress;
14
use Application\Traits\HasDoorAccess;
15
use Application\Traits\HasIban;
16
use Application\Traits\HasRemarks;
17
use Cake\Chronos\Chronos;
18
use Cake\Chronos\Date;
19
use Doctrine\Common\Collections\ArrayCollection;
20
use Doctrine\Common\Collections\Collection;
21
use Doctrine\ORM\Mapping as ORM;
22
use Ecodev\Felix\Api\Exception;
23
use Ecodev\Felix\Model\CurrentUser;
24
use Ecodev\Felix\Model\Traits\HasInternalRemarks;
25
use Ecodev\Felix\Model\Traits\HasPassword;
26
use GraphQL\Doctrine\Annotation as API;
27
28
/**
29
 * User.
30
 *
31
 * @ORM\Entity(repositoryClass="Application\Repository\UserRepository")
32
 * @ORM\HasLifecycleCallbacks
33
 * @ORM\AssociationOverrides({
34
 *     @ORM\AssociationOverride(name="owner", inversedBy="users")
35
 * })
36
 * @API\Sorting({
37
 *     "Application\Api\Input\Sorting\Age",
38
 *     "Application\Api\Input\Sorting\Balance",
39
 * })
40
 * @API\Filters({
41
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\HasBookingWithTaggedBookableOperatorType", type="id"),
42
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\HasBookingWithBookableOperatorType", type="id"),
43
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\HasBookingStatusOperatorType", type="id"),
44
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\HasBookingCompletedOperatorType", type="boolean"),
45
 *     @API\Filter(field="bookingCount", operator="Application\Api\Input\Operator\BookingCount\BookingCountEqualOperatorType", type="int"),
46
 *     @API\Filter(field="bookingCount", operator="Application\Api\Input\Operator\BookingCount\BookingCountGreaterOperatorType", type="int"),
47
 *     @API\Filter(field="bookingCount", operator="Application\Api\Input\Operator\BookingCount\BookingCountGreaterOrEqualOperatorType", type="int"),
48
 *     @API\Filter(field="bookingCount", operator="Application\Api\Input\Operator\BookingCount\BookingCountLessOperatorType", type="int"),
49
 *     @API\Filter(field="bookingCount", operator="Application\Api\Input\Operator\BookingCount\BookingCountLessOrEqualOperatorType", type="int"),
50
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\EqualOperatorType", type="Money"),
51
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\GreaterOperatorType", type="Money"),
52
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\GreaterOrEqualOperatorType", type="Money"),
53
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\LessOperatorType", type="Money"),
54
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\LessOrEqualOperatorType", type="Money"),
55
 *     @API\Filter(field="bookingDate", operator="Application\Api\Input\Operator\BookingDate\BookingDateEqualOperatorType", type="Date"),
56
 *     @API\Filter(field="bookingDate", operator="Application\Api\Input\Operator\BookingDate\BookingDateGreaterOperatorType", type="Date"),
57
 *     @API\Filter(field="bookingDate", operator="Application\Api\Input\Operator\BookingDate\BookingDateGreaterOrEqualOperatorType", type="Date"),
58
 *     @API\Filter(field="bookingDate", operator="Application\Api\Input\Operator\BookingDate\BookingDateLessOperatorType", type="Date"),
59
 *     @API\Filter(field="bookingDate", operator="Application\Api\Input\Operator\BookingDate\BookingDateLessOrEqualOperatorType", type="Date"),
60
 * })
61
 */
62
class User extends AbstractModel implements \Ecodev\Felix\Model\User
63
{
64
    public const ROLE_ANONYMOUS = 'anonymous';
65
    public const ROLE_BOOKING_ONLY = 'booking_only';
66
    public const ROLE_INDIVIDUAL = 'individual';
67
    public const ROLE_ACCOUNTING_VERIFICATOR = 'accounting_verificator';
68
    public const ROLE_MEMBER = 'member';
69
    public const ROLE_TRAINER = 'trainer';
70
    public const ROLE_FORMATION_RESPONSIBLE = 'formation_responsible';
71
    public const ROLE_RESPONSIBLE = 'responsible';
72
    public const ROLE_ADMINISTRATOR = 'administrator';
73
74
    public const STATUS_INACTIVE = 'inactive';
75
    public const STATUS_NEW = 'new';
76
    public const STATUS_ACTIVE = 'active';
77
    public const STATUS_ARCHIVED = 'archived';
78
79
    use HasAddress;
80
    use HasDoorAccess;
81
    use HasIban;
82
    use HasInternalRemarks;
83
    use HasPassword;
84
    use HasRemarks;
85
86
    /**
87
     * @var User
88
     */
89
    private static $currentUser;
90
91
    /**
92
     * Set currently logged in user
93
     * WARNING: this method should only be called from \Application\Authentication\AuthenticationListener.
94
     *
95
     * @param User $user
96
     */
97 274
    public static function setCurrent(?self $user): void
98
    {
99 274
        self::$currentUser = $user;
100
101
        // Initalize ACL filter with current user if a logged in one exists
102
        /** @var UserRepository $userRepository */
103 274
        $userRepository = _em()->getRepository(self::class);
104 274
        $aclFilter = $userRepository->getAclFilter();
105 274
        $aclFilter->setUser($user);
106
107 274
        CurrentUser::set($user);
108 274
    }
109
110
    /**
111
     * Returns currently logged user or null.
112
     */
113 96
    public static function getCurrent(): ?self
114
    {
115 96
        return self::$currentUser;
116
    }
117
118
    /**
119
     * @var null|string
120
     *
121
     * @ORM\Column(type="string", length=50, nullable=true, unique=true)
122
     */
123
    private $login;
124
125
    /**
126
     * @var string
127
     * @ORM\Column(type="string", length=191)
128
     */
129
    private $firstName = '';
130
131
    /**
132
     * @var string
133
     * @ORM\Column(type="string", length=191)
134
     */
135
    private $lastName = '';
136
137
    /**
138
     * @var null|string
139
     * @ORM\Column(type="string", length=191, nullable=true, unique=true)
140
     */
141
    private $email;
142
143
    /**
144
     * @var string
145
     * @ORM\Column(type="UserRole", options={"default" = User::ROLE_INDIVIDUAL})
146
     */
147
    private $role = self::ROLE_INDIVIDUAL;
148
149
    /**
150
     * @var string
151
     * @ORM\Column(type="UserStatus", options={"default" = User::STATUS_NEW})
152
     */
153
    private $status = self::STATUS_NEW;
154
155
    /**
156
     * @var null|Chronos
157
     * @ORM\Column(type="datetime", nullable=true)
158
     */
159
    private $welcomeSessionDate;
160
161
    /**
162
     * @var null|Chronos
163
     * @ORM\Column(type="datetime", nullable=true)
164
     */
165
    private $resignDate;
166
167
    /**
168
     * @var int sex
169
     * @ORM\Column(type="smallint", options={"default" = 0}))
170
     */
171
    private $sex = 0;
172
173
    /**
174
     * @var string
175
     * @ORM\Column(type="string", length=25, options={"default" = ""})
176
     */
177
    private $phone = '';
178
179
    /**
180
     * @var string
181
     * @ORM\Column(type="string", length=25, options={"default" = ""})
182
     */
183
    private $mobilePhone = '';
184
185
    /**
186
     * @var string
187
     * @ORM\Column(type="string", length=25, options={"default" = ""})
188
     */
189
    private $swissSailing = '';
190
191
    /**
192
     * @var string
193
     * @ORM\Column(type="SwissSailingType", nullable=true)
194
     */
195
    private $swissSailingType;
196
197
    /**
198
     * @var string
199
     * @ORM\Column(type="SwissWindsurfType", nullable=true)
200
     */
201
    private $swissWindsurfType;
202
203
    /**
204
     * @var null|Date
205
     * @ORM\Column(type="date", nullable=true)
206
     */
207
    private $birthday;
208
209
    /**
210
     * @var bool
211
     * @ORM\Column(type="boolean", options={"default" = 0})
212
     */
213
    private $termsAgreement = false;
214
215
    /**
216
     * @var bool
217
     * @ORM\Column(type="boolean", options={"default" = 0})
218
     */
219
    private $hasInsurance = false;
220
221
    /**
222
     * @var bool
223
     * @ORM\Column(type="boolean", options={"default" = 0})
224
     */
225
    private $receivesNewsletter = false;
226
227
    /**
228
     * @var string
229
     * @ORM\Column(type="Relationship", options={"default" = RelationshipType::HOUSEHOLDER})
230
     */
231
    private $familyRelationship = RelationshipType::HOUSEHOLDER;
232
233
    /**
234
     * @var string
235
     * @ORM\Column(type="BillingType", options={"default" = BillingTypeType::ELECTRONIC})
236
     */
237
    private $billingType = BillingTypeType::ELECTRONIC;
238
239
    /**
240
     * @var Collection<Booking>
241
     * @ORM\OneToMany(targetEntity="Booking", mappedBy="owner")
242
     */
243
    private $bookings;
244
245
    /**
246
     * @var Collection<License>
247
     * @ORM\ManyToMany(targetEntity="License", mappedBy="users")
248
     */
249
    private $licenses;
250
251
    /**
252
     * @var Collection<UserTag>
253
     * @ORM\ManyToMany(targetEntity="UserTag", mappedBy="users")
254
     */
255
    private $userTags;
256
257
    /**
258
     * @var Collection<Message>
259
     * @ORM\OneToMany(targetEntity="Message", mappedBy="recipient")
260
     */
261
    private $messages;
262
263
    /**
264
     * There is actually 0 to 1 account, never more. And this is
265
     * enforced by DB unique constraints.
266
     *
267
     * @var Collection<Account>
268
     * @ORM\OneToMany(targetEntity="Account", mappedBy="owner")
269
     */
270
    private $accounts;
271
272
    /**
273
     * @var Collection<User>
274
     * @ORM\OneToMany(targetEntity="User", mappedBy="owner")
275
     */
276
    private $users;
277
278
    /**
279
     * Constructor.
280
     *
281
     * @param string $role role for new user
282
     */
283 109
    public function __construct(string $role = self::ROLE_INDIVIDUAL)
284
    {
285 109
        $this->role = $role;
286 109
        $this->bookings = new ArrayCollection();
287 109
        $this->accounts = new ArrayCollection();
288 109
        $this->licenses = new ArrayCollection();
289 109
        $this->userTags = new ArrayCollection();
290 109
        $this->messages = new ArrayCollection();
291 109
        $this->users = new ArrayCollection();
292 109
    }
293
294
    /**
295
     * Set login (eg: johndoe).
296
     *
297
     * @API\Input(type="Login")
298
     */
299 15
    public function setLogin(string $login): void
300
    {
301 15
        $this->login = $login;
302 15
    }
303
304
    /**
305
     * Get login (eg: johndoe).
306
     *
307
     * @API\Field(type="?Login")
308
     */
309 29
    public function getLogin(): ?string
310
    {
311 29
        return $this->login;
312
    }
313
314
    /**
315
     * Set first name.
316
     */
317 10
    public function setFirstName(string $firstName): void
318
    {
319 10
        $this->firstName = $firstName;
320 10
    }
321
322
    /**
323
     * Get first name.
324
     */
325 32
    public function getFirstName(): string
326
    {
327 32
        return $this->firstName;
328
    }
329
330
    /**
331
     * Set last name.
332
     */
333 10
    public function setLastName(string $lastName): void
334
    {
335 10
        $this->lastName = $lastName;
336 10
    }
337
338
    /**
339
     * Get last name.
340
     */
341 25
    public function getLastName(): string
342
    {
343 25
        return $this->lastName;
344
    }
345
346
    /**
347
     * Get full name.
348
     */
349 25
    public function getName(): string
350
    {
351 25
        return implode(' ', [$this->getFirstName(), $this->getLastName()]);
352
    }
353
354
    /**
355
     * Set email.
356
     *
357
     * @API\Input(type="?Email")
358
     */
359 5
    public function setEmail(?string $email): void
360
    {
361 5
        $this->email = $email;
362 5
    }
363
364
    /**
365
     * Get email.
366
     *
367
     * @API\Field(type="?Email")
368
     */
369 15
    public function getEmail(): ?string
370
    {
371 15
        return $this->email;
372
    }
373
374
    /**
375
     * Get the user role.
376
     *
377
     * @API\Field(type="UserRole")
378
     */
379 100
    public function getRole(): string
380
    {
381 100
        return $this->role;
382
    }
383
384
    /**
385
     * Sets the user role.
386
     *
387
     * @API\Input(type="UserRole")
388
     */
389 7
    public function setRole(string $role): void
390
    {
391 7
        if (!Role::canUpdate(self::getCurrent(), $this->role, $role)) {
392 3
            $currentRole = self::getCurrent() ? self::getCurrent()->getRole() : self::ROLE_ANONYMOUS;
393
394 3
            throw new Exception($currentRole . ' is not allowed to change role from ' . $this->role . ' to ' . $role);
395
        }
396
397 4
        $this->role = $role;
398 4
    }
399
400 9
    public function setOwner(?self $owner = null): void
401
    {
402 9
        if ($owner === $this) {
403 1
            throw new Exception('This user cannot be owned by himself');
404
        }
405
406 8
        if ($owner && $owner->getOwner()) {
407 1
            throw new Exception('This user cannot be owned by a user who is himself owned by somebody else');
408
        }
409
410 8
        if ($owner && $this->users->count()) {
411 1
            throw new Exception('This user owns other users, so he cannot himself be owned by somebody else');
412
        }
413
414 8
        if ($this->getOwner()) {
415 2
            $this->getOwner()->getEmail(); // Trigger lazy loading
416 2
            $this->getOwner()->users->removeElement($this);
417
        }
418
419 8
        parent::setOwner($owner);
420
421 8
        if ($this->getOwner()) {
422 4
            $this->getOwner()->getEmail(); // Trigger lazy loading
423 4
            $this->getOwner()->users->add($this);
424 4
            $this->setStatus($this->getOwner()->getStatus());
425
        }
426 8
    }
427
428
    /**
429
     * @API\Field(type="Application\Api\Enum\UserStatusType")
430
     */
431 6
    public function getStatus(): string
432
    {
433 6
        return $this->status;
434
    }
435
436
    /**
437
     * @API\Input(type="Application\Api\Enum\UserStatusType")
438
     */
439 13
    public function setStatus(string $newStatus): void
440
    {
441 13
        if ($newStatus === self::STATUS_ARCHIVED && $this->status !== self::STATUS_ARCHIVED) {
442 2
            $this->setResignDate(Chronos::NOW());
443 12
        } elseif ($this->status === self::STATUS_ARCHIVED && $newStatus !== self::STATUS_ARCHIVED) {
444
            $this->setResignDate(null);
445
        }
446
447 13
        $this->status = $newStatus;
448 13
        $this->revokeToken();
449
450 13
        foreach ($this->users as $user) {
451 1
            if ($user !== $this) {
452 1
                $user->setStatus($newStatus);
453
            }
454
        }
455 13
    }
456
457
    /**
458
     * Whether this user is a family owner or not.
459
     *
460
     * This is used for our internal logic and should
461
     * NEVER be related to `familyRelationship`. That field
462
     * is purely informative for humans.
463
     */
464 1
    public function isFamilyOwner(): bool
465
    {
466 1
        return !$this->getOwner();
467
    }
468
469 1
    public function initialize(): void
470
    {
471 1
        $this->role = self::ROLE_MEMBER; // Bypass security
472 1
        $this->setStatus(self::STATUS_NEW);
473 1
    }
474
475
    public function getPhone(): string
476
    {
477
        return $this->phone;
478
    }
479
480
    public function setPhone(string $phone): void
481
    {
482
        $this->phone = $phone;
483
    }
484
485
    public function getMobilePhone(): string
486
    {
487
        return $this->mobilePhone;
488
    }
489
490 1
    public function setMobilePhone(string $mobilePhone): void
491
    {
492 1
        $this->mobilePhone = $mobilePhone;
493 1
    }
494
495
    public function getBirthday(): ?Date
496
    {
497
        return $this->birthday;
498
    }
499
500 1
    public function setBirthday(?Date $birthday): void
501
    {
502 1
        $this->birthday = $birthday;
503 1
    }
504
505
    /**
506
     * return null|int.
507
     */
508
    public function getAge(): ?int
509
    {
510
        if ($this->birthday) {
511
            return (new Date())->diffInYears($this->birthday);
512
        }
513
514
        return null;
515
    }
516
517
    /**
518
     * Get bookings.
519
     */
520 3
    public function getBookings(): Collection
521
    {
522 3
        return $this->bookings;
523
    }
524
525
    /**
526
     * Get active bookings (confirmed and non-terminated).
527
     *
528
     * @API\Exclude
529
     */
530 2
    public function getRunningBookings(): Collection
531
    {
532 2
        return $this->bookings->filter(fn (Booking $booking) => $booking->getStatus() === BookingStatusType::BOOKED && $booking->getEndDate() === null);
533
    }
534
535
    /**
536
     * Notify the user that it has a new booking.
537
     * This should only be called by Booking::setResponsible().
538
     */
539 16
    public function bookingAdded(Booking $booking): void
540
    {
541 16
        $this->bookings->add($booking);
542 16
    }
543
544
    /**
545
     * Notify the user that it has a booking was removed.
546
     * This should only be called by Booking::setResponsible().
547
     */
548 4
    public function bookingRemoved(Booking $booking): void
549
    {
550 4
        $this->bookings->removeElement($booking);
551 4
    }
552
553 2
    public function getLicenses(): Collection
554
    {
555 2
        return $this->licenses;
556
    }
557
558 1
    public function getUserTags(): Collection
559
    {
560 1
        return $this->userTags;
561
    }
562
563
    /**
564
     * Notify the user that it has a new license.
565
     * This should only be called by License::addUser().
566
     */
567 1
    public function licenseAdded(License $license): void
568
    {
569 1
        $this->licenses->add($license);
570 1
    }
571
572
    /**
573
     * Notify the user that it a license was removed.
574
     * This should only be called by License::removeUser().
575
     */
576 1
    public function licenseRemoved(License $license): void
577
    {
578 1
        $this->licenses->removeElement($license);
579 1
    }
580
581
    /**
582
     * Notify the user that it has a new userTag.
583
     * This should only be called by UserTag::addUser().
584
     */
585 1
    public function userTagAdded(UserTag $userTag): void
586
    {
587 1
        $this->userTags->add($userTag);
588 1
    }
589
590
    /**
591
     * Notify the user that a userTag was removed.
592
     * This should only be called by UserTag::removeUser().
593
     */
594 1
    public function userTagRemoved(UserTag $userTag): void
595
    {
596 1
        $this->userTags->removeElement($userTag);
597 1
    }
598
599
    public function isTermsAgreement(): bool
600
    {
601
        return $this->termsAgreement;
602
    }
603
604 1
    public function setTermsAgreement(bool $termsAgreement): void
605
    {
606 1
        $this->termsAgreement = $termsAgreement;
607 1
    }
608
609
    public function hasInsurance(): bool
610
    {
611
        return $this->hasInsurance;
612
    }
613
614 1
    public function setHasInsurance(bool $hasInsurance): void
615
    {
616 1
        $this->hasInsurance = $hasInsurance;
617 1
    }
618
619
    public function getWelcomeSessionDate(): ?Chronos
620
    {
621
        return $this->welcomeSessionDate;
622
    }
623
624
    public function setWelcomeSessionDate(?Chronos $welcomeSessionDate): void
625
    {
626
        $this->welcomeSessionDate = $welcomeSessionDate;
627
    }
628
629 1
    public function getResignDate(): ?Chronos
630
    {
631 1
        return $this->resignDate;
632
    }
633
634 2
    public function setResignDate(?Chronos $resignDate): void
635
    {
636 2
        $this->resignDate = $resignDate;
637 2
    }
638
639
    public function getReceivesNewsletter(): bool
640
    {
641
        return $this->receivesNewsletter;
642
    }
643
644
    public function setReceivesNewsletter(bool $receivesNewsletter): void
645
    {
646
        $this->receivesNewsletter = $receivesNewsletter;
647
    }
648
649
    /**
650
     * Get the sex.
651
     *
652
     * @API\Field(type="Sex")
653
     */
654
    public function getSex(): int
655
    {
656
        return $this->sex;
657
    }
658
659
    /**
660
     * Set the sex.
661
     *
662
     * @API\Input(type="Sex")
663
     */
664
    public function setSex(int $sex): void
665
    {
666
        $this->sex = $sex;
667
    }
668
669
    /**
670
     * Get the Swiss Sailing licence number.
671
     */
672
    public function getSwissSailing(): string
673
    {
674
        return $this->swissSailing;
675
    }
676
677
    public function setSwissSailing(string $swissSailing): void
678
    {
679
        $this->swissSailing = $swissSailing;
680
    }
681
682
    /**
683
     * Get the Swiss Sailing licence type.
684
     *
685
     * @API\Field(type="?SwissSailingType")
686
     */
687
    public function getSwissSailingType(): ?string
688
    {
689
        return $this->swissSailingType;
690
    }
691
692
    /**
693
     * Set the Swiss Sailing licence type.
694
     *
695
     * @API\Input(type="?SwissSailingType")
696
     */
697
    public function setSwissSailingType(?string $swissSailingType): void
698
    {
699
        $this->swissSailingType = $swissSailingType;
700
    }
701
702
    /**
703
     * Get the Swiss Windsurf licence type.
704
     *
705
     * @API\Field(type="?SwissWindsurfType")
706
     */
707
    public function getSwissWindsurfType(): ?string
708
    {
709
        return $this->swissWindsurfType;
710
    }
711
712
    /**
713
     * Set the Swiss Windsurf licence type.
714
     *
715
     * @API\Input(type="?SwissWindsurfType")
716
     */
717
    public function setSwissWindsurfType(?string $swissWindsurfType): void
718
    {
719
        $this->swissWindsurfType = $swissWindsurfType;
720
    }
721
722
    /**
723
     * Get the first login date.
724
     */
725
    public function getFirstLogin(): ?Chronos
726
    {
727
        /** @var LogRepository $logRepository */
728
        $logRepository = _em()->getRepository(Log::class);
729
730
        return $logRepository->getLoginDate($this, true);
731
    }
732
733
    /**
734
     * Get the last login date.
735
     */
736
    public function getLastLogin(): ?Chronos
737
    {
738
        /** @var LogRepository $logRepository */
739
        $logRepository = _em()->getRepository(Log::class);
740
741
        return $logRepository->getLoginDate($this, false);
742
    }
743
744
    /**
745
     * @API\Field(type="Relationship")
746
     */
747
    public function getFamilyRelationship(): string
748
    {
749
        return $this->familyRelationship;
750
    }
751
752
    /**
753
     * @API\Input(type="Relationship")
754
     */
755 1
    public function setFamilyRelationship(string $familyRelationship): void
756
    {
757 1
        $this->familyRelationship = $familyRelationship;
758 1
    }
759
760
    /**
761
     * @API\Field(type="BillingType")
762
     */
763
    public function getBillingType(): string
764
    {
765
        return $this->billingType;
766
    }
767
768
    /**
769
     * @API\Input(type="BillingType")
770
     */
771
    public function setBillingType(string $billingType): void
772
    {
773
        $this->billingType = $billingType;
774
    }
775
776
    /**
777
     * Get the user transaction account.
778
     */
779 38
    public function getAccount(): ?Account
780
    {
781 38
        if ($this->getOwner() && $this->getOwner() !== $this) {
782 8
            return $this->getOwner()->getAccount();
783
        }
784
785 38
        return $this->accounts->count() ? $this->accounts->first() : null;
786
    }
787
788
    /**
789
     * Notify the user that it has a new account
790
     * This should only be called by Account::setOwner().
791
     */
792 20
    public function accountAdded(Account $account): void
793
    {
794 20
        $this->accounts->clear();
795 20
        $this->accounts->add($account);
796 20
    }
797
798
    /**
799
     * Notify the user that a account was removed
800
     * This should only be called by Account::setOwner().
801
     */
802 1
    public function accountRemoved(): void
803
    {
804 1
        $this->accounts->clear();
805 1
    }
806
807
    /**
808
     * Get messages sent to the user.
809
     */
810 1
    public function getMessages(): Collection
811
    {
812 1
        return $this->messages;
813
    }
814
815
    /**
816
     * Notify the user that it has a new message
817
     * This should only be called by Message::setRecipient().
818
     */
819 9
    public function messageAdded(Message $message): void
820
    {
821 9
        $this->messages->add($message);
822 9
    }
823
824
    /**
825
     * Notify the user that a message was removed
826
     * This should only be called by Message::setRecipient().
827
     */
828 1
    public function messageRemoved(Message $message): void
829
    {
830 1
        $this->messages->removeElement($message);
831 1
    }
832
833
    /**
834
     * Check if the user can *really* open a door
835
     * This also takes into account the user status and role.
836
     *
837
     * @API\Field(args={@API\Argument(name="door", type="?Application\Api\Enum\DoorType")})
838
     *
839
     * @param null|string $door a particular door, or null for any
840
     */
841 6
    public function getCanOpenDoor(?string $door = null): bool
842
    {
843 6
        $allowedStatus = [self::STATUS_ACTIVE];
844
        $allowedRoles = [
845 6
            self::ROLE_ACCOUNTING_VERIFICATOR,
846 6
            self::ROLE_INDIVIDUAL,
847 6
            self::ROLE_MEMBER,
848 6
            self::ROLE_TRAINER,
849 6
            self::ROLE_FORMATION_RESPONSIBLE,
850 6
            self::ROLE_RESPONSIBLE,
851 6
            self::ROLE_ADMINISTRATOR,
852
        ];
853
854 6
        if ($door && !$this->$door) {
855 3
            return false;
856
        }
857
858 6
        if (!in_array($this->status, $allowedStatus, true) || !in_array($this->role, $allowedRoles, true)) {
859 2
            return false;
860
        }
861
862 4
        return true;
863
    }
864
865
    /**
866
     * Override parent to prevents users created from administration to be family of the administrator.
867
     *
868
     * The owner must be explicitly set for all users.
869
     */
870 3
    protected function getOwnerForCreation(): ?self
871
    {
872 3
        return null;
873
    }
874
}
875