src/Entity/User.php line 59

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Repository\TransactionRepository;
  4. use DateTime;
  5. use Doctrine\Common\Collections\ArrayCollection;
  6. use Doctrine\Common\Collections\Criteria;
  7. use Doctrine\ORM\Mapping as ORM;
  8. use FOS\UserBundle\Model\User as BaseUser;
  9. use Gedmo\Mapping\Annotation as Gedmo;
  10. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  11. use Symfony\Component\HttpFoundation\File\File;
  12. use Symfony\Component\Intl\Countries;
  13. use Symfony\Component\Intl\Exception\MissingResourceException;
  14. use Symfony\Component\Validator\Constraints as Assert;
  15. use Vich\UploaderBundle\Mapping\Annotation as Vich;
  16. /**
  17.  * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
  18.  *
  19.  * @ORM\Table(
  20.  *     name="user",
  21.  *     indexes={
  22.  *
  23.  *         @ORM\Index(columns={"created_at"}),
  24.  *         @ORM\Index(columns={"last_login"}),
  25.  *         @ORM\Index(columns={"username"}),
  26.  *         @ORM\Index(columns={"email"})
  27.  *     }
  28.  * )
  29.  *
  30.  * @ORM\InheritanceType("SINGLE_TABLE")
  31.  *
  32.  * @ORM\DiscriminatorColumn(name="type", type="string")
  33.  *
  34.  * @ORM\DiscriminatorMap({
  35.  *      "user" = "PrivateUser",
  36.  *      "pro"  = "ProUser",
  37.  * })
  38.  *
  39.  * We pass the entityClass so that uniqueness is checked when PrivateUser and ProUser are instanced.
  40.  *
  41.  * @UniqueEntity(
  42.  *     fields = "username",
  43.  *     entityClass="App\Entity\User",
  44.  *     groups={"registration_pro_2", "Default", "Registration", "portugal", "belgium"},
  45.  *     message="fos_user.username.already_used"
  46.  * )
  47.  * @UniqueEntity(
  48.  *     fields = "email",
  49.  *     entityClass="App\Entity\User",
  50.  *     groups={"registration_pro_2", "Default", "Registration", "portugal", "belgium"},
  51.  *     message="fos_user.email.already_used"
  52.  * )
  53.  *
  54.  * @Vich\Uploadable
  55.  */
  56. abstract class User extends BaseUser
  57. {
  58.     public const TYPE_PRIVATE 'user';
  59.     public const TYPE_SOCIETY 'society';
  60.     public const TYPE_PRO 'pro';
  61.     public const SF_TYPE_PROFESSIONAL 'Professionnel';
  62.     public const SF_TYPE_SOCIETY 'Société';
  63.     public const SF_TYPE_PERSON 'Particulier';
  64.     public const ORIGIN_VPAUTO 'vpauto';
  65.     public const ORIGIN_SHOWVROOM 'showvroom';
  66.     /**
  67.      * @ORM\Id
  68.      *
  69.      * @ORM\Column(type="bigint")
  70.      *
  71.      * @ORM\GeneratedValue(strategy="AUTO")
  72.      */
  73.     protected $id;
  74.     /**
  75.      * @ORM\Column(type="string", length=20, nullable=true)
  76.      *
  77.      * @Assert\NotBlank(groups={"profile"})
  78.      */
  79.     protected $title;
  80.     /**
  81.      * @ORM\Column(type="string", length=255, nullable=true)
  82.      *
  83.      * @Assert\NotBlank(groups={"profile", "payment_check_info", "registration_pro_2"}, message="frontend.profile.lastname.blank")
  84.      */
  85.     protected $lastname;
  86.     /**
  87.      * @ORM\Column(type="string", length=255, nullable=true)
  88.      *
  89.      * @Assert\NotBlank(groups={"profile", "payment_check_info", "registration_pro_2"}, message="frontend.profile.firstname.blank")
  90.      */
  91.     protected $firstname;
  92.     /**
  93.      * @ORM\Column(type="string", length=255, nullable=true)
  94.      *
  95.      * @Assert\NotBlank(groups={"profile", "payment_check_info", "registration_pro_1"}, message="frontend.profile.address.blank")
  96.      */
  97.     protected $address;
  98.     /**
  99.      * @ORM\Column(type="string", length=255, nullable=true)
  100.      */
  101.     protected $addressComplement;
  102.     /**
  103.      * @ORM\Column(type="string", length=50, name="zip_code", nullable=true)
  104.      *
  105.      * @Assert\NotBlank(groups={"profile", "payment_check_info", "registration_pro_1"}, message="frontend.profile.zipCode.blank")
  106.      */
  107.     protected $zipCode;
  108.     /**
  109.      * @ORM\Column(type="string", length=255, nullable=true)
  110.      *
  111.      * @Assert\NotBlank(groups={"profile", "payment_check_info", "registration_pro_1"}, message="frontend.profile.city.blank")
  112.      */
  113.     protected $city;
  114.     /**
  115.      * @ORM\Column(type="string", length=255, nullable=true)
  116.      *
  117.      * @Assert\NotBlank(groups={"profile", "payment_check_info", "registration_pro_1"}, message="frontend.profile.country.blank")
  118.      */
  119.     protected $country;
  120.     /**
  121.      * @ORM\Column(type="string", length=255, nullable=true)
  122.      */
  123.     protected $referralSource;
  124.     /**
  125.      * 40 is the maximal length in Salesforce, we need to accept data that is imported from Salesforce.
  126.      *
  127.      * @ORM\Column(type="string", length=40, nullable=true)
  128.      *
  129.      * @Assert\NotBlank(groups={"registration_pro_2"}, message="frontend.page.register_pro.form.required.phone")
  130.      */
  131.     protected $phone;
  132.     /**
  133.      * @ORM\Column(type="string", length=30, nullable=true)
  134.      *
  135.      * @Assert\NotBlank(groups={"profile", "payment_check_info"}, message="frontend.profile.mobile.blank")
  136.      */
  137.     protected $mobile;
  138.     /**
  139.      * @Gedmo\Timestampable(on="create")
  140.      *
  141.      * @ORM\Column(type="datetime", name="created_at")
  142.      */
  143.     protected $createdAt;
  144.     /**
  145.      * @Gedmo\Timestampable(on="update")
  146.      *
  147.      * @ORM\Column(type="datetime", name="updated_at")
  148.      */
  149.     protected $updatedAt;
  150.     /**
  151.      * @ORM\Column(type="boolean", nullable=true)
  152.      */
  153.     protected $newsletter;
  154.     /**
  155.      * @ORM\Column(type="datetime", nullable=true)
  156.      */
  157.     protected $lastOptinChangeDate;
  158.     /**
  159.      * @ORM\ManyToMany(targetEntity="App\Entity\Auction", mappedBy="users")
  160.      */
  161.     protected $auctions;
  162.     /**
  163.      * @ORM\Column(type="boolean")
  164.      */
  165.     protected $needsTransaction;
  166.     /**
  167.      * @ORM\Column(type="boolean", nullable=true)
  168.      */
  169.     protected $society;
  170.     /**
  171.      * @ORM\Column(type="boolean")
  172.      */
  173.     protected $smsOptin;
  174.     /**
  175.      * locked was removed from FOSUserBundle,
  176.      * see https://github.com/FriendsOfSymfony/FOSUserBundle/commit/7ad2a4ba08a4f038e49227abf1b893968af1c995.
  177.      *
  178.      * @var bool
  179.      *
  180.      * @ORM\Column(type="boolean")
  181.      */
  182.     protected $locked;
  183.     /**
  184.      * @ORM\Column(type="string", nullable=true)
  185.      *
  186.      * @Assert\NotBlank(groups={"registration_pro"}, message="assert.user.language.not_blank")
  187.      */
  188.     protected $language;
  189.     /**
  190.      * @Vich\UploadableField(mapping="user_avatar", fileNameProperty="avatar")
  191.      *
  192.      * @Assert\NotBlank(groups={"avatar"})
  193.      *
  194.      * @Assert\Image(
  195.      *     minWidth = 200,
  196.      *     maxWidth = 1800,
  197.      *     minHeight = 200,
  198.      *     maxHeight = 1800,
  199.      *     groups={"avatar"}
  200.      * )
  201.      *
  202.      * @Assert\File(
  203.      *     maxSize = "8M",
  204.      *     groups={"avatar"},
  205.      *     maxSizeMessage = "Ce fichier est trop volumineux (maximum à {{ limit }}Mo)"
  206.      * )
  207.      *
  208.      * @var File
  209.      */
  210.     protected $avatarFile;
  211.     /**
  212.      * @ORM\Column(type="string", length=255, nullable=true)
  213.      *
  214.      * @var string
  215.      */
  216.     protected $avatar;
  217.     /**
  218.      * @ORM\Column(type="string")
  219.      */
  220.     protected $vehicleListType;
  221.     /**
  222.      * @ORM\Column(type="string")
  223.      *
  224.      * @var string
  225.      */
  226.     protected $origin;
  227.     /**
  228.      * @ORM\OneToMany(targetEntity="VehicleAlert", mappedBy="user", cascade={"persist", "remove"})
  229.      */
  230.     private $vehicleAlerts;
  231.     /**
  232.      * @ORM\OneToMany(targetEntity="App\Entity\Selection", mappedBy="user", cascade={"persist", "remove"})
  233.      **/
  234.     private $selections;
  235.     /**
  236.      * @ORM\OneToMany(targetEntity="App\Entity\SmsAlert", mappedBy="user", cascade={"persist", "remove"})
  237.      **/
  238.     private $smsAlerts;
  239.     /**
  240.      * @ORM\OneToMany(targetEntity="Alert", mappedBy="user", cascade={"persist", "remove"})
  241.      */
  242.     private $alerts;
  243.     /**
  244.      * @ORM\OneToMany(targetEntity="ProUser", mappedBy="salesman")
  245.      */
  246.     private $managedUsers;
  247.     /**
  248.      * @ORM\OneToMany(targetEntity="App\Entity\Transaction", mappedBy="user")
  249.      *
  250.      * @ORM\OrderBy({"createdAt"="DESC","id"="DESC"})
  251.      */
  252.     private $transactions;
  253.     /**
  254.      * @ORM\OneToMany(targetEntity="App\Entity\PurchaseInstruction", mappedBy="user", cascade={"remove"})
  255.      */
  256.     private $purchaseInstructions;
  257.     /**
  258.      * @ORM\OneToMany(targetEntity="App\Entity\PurchaseInstructionRule", mappedBy="user", cascade={"remove"})
  259.      */
  260.     private $purchaseInstructionRules;
  261.     /**
  262.      * @ORM\OneToMany(targetEntity="App\Entity\Bid", mappedBy="user")
  263.      */
  264.     private $bids;
  265.     /**
  266.      * @ORM\Column(type="string", length=40, unique=true)
  267.      */
  268.     private $liveApiKey;
  269.     /**
  270.      * @ORM\Column(type="datetime", nullable=true)
  271.      */
  272.     private $liveLoggedInAt;
  273.     /**
  274.      * @ORM\Column(type="datetime", nullable=true)
  275.      */
  276.     private $liveLoggedOutAt;
  277.     /**
  278.      * Salesforce Account Id.
  279.      *
  280.      * @ORM\Column(type="string", length=18, nullable=true)
  281.      */
  282.     private $sfAccountId;
  283.     /**
  284.      * Salesforce Contact Id.
  285.      *
  286.      * @ORM\Column(type="string", length=18, nullable=true)
  287.      */
  288.     private $sfContactId;
  289.     /**
  290.      * @ORM\Column(type="string", length=18, nullable=true)
  291.      */
  292.     private $sfLeadId;
  293.     /**
  294.      * @ORM\ManyToMany(targetEntity="App\Entity\BuyersGroup", mappedBy="users", cascade={"persist"})
  295.      */
  296.     private $buyersGroups;
  297.     /**
  298.      * @ORM\OneToMany(targetEntity="App\Entity\Behaviour", mappedBy="user", cascade={"remove"})
  299.      */
  300.     private $behaviours;
  301.     /**
  302.      * @ORM\Column(unique=true, nullable=true)
  303.      */
  304.     private $adId;
  305.     /**
  306.      * @ORM\OneToMany(targetEntity="App\Entity\CgvUserSignature", mappedBy="user", cascade={"remove"})
  307.      */
  308.     private $cgvSignatures;
  309.     public function __construct()
  310.     {
  311.         parent::__construct();
  312.         $this->locked false;
  313.         $this->bids = new ArrayCollection();
  314.         $this->vehicleAlerts = new ArrayCollection();
  315.         $this->alerts = new ArrayCollection();
  316.         $this->transactions = new ArrayCollection();
  317.         $this->managedUsers = new ArrayCollection();
  318.         $this->auctions = new ArrayCollection();
  319.         $this->purchaseInstructions = new ArrayCollection();
  320.         $this->buyersGroups = new ArrayCollection();
  321.         $this->behaviours = new ArrayCollection();
  322.         $this->selections = new ArrayCollection();
  323.         $this->smsAlerts = new ArrayCollection();
  324.         $this->country 'FR';
  325.         $this->smsOptin false;
  326.         $this->liveApiKey sha1(\random_bytes(40));
  327.         $this->language 'fr';
  328.         $this->lastOptinChangeDate = new \DateTime();
  329.         $this->vehicleListType 'Mosaique';
  330.         $this->society false;
  331.         $this->origin self::ORIGIN_VPAUTO;
  332.     }
  333.     public function getId()
  334.     {
  335.         return $this->id;
  336.     }
  337.     public function setTitle($title): void
  338.     {
  339.         $this->title $title;
  340.     }
  341.     public function getTitle()
  342.     {
  343.         return $this->title;
  344.     }
  345.     public function setLastname($lastname): void
  346.     {
  347.         $this->lastname $lastname;
  348.     }
  349.     public function getLastname()
  350.     {
  351.         return $this->lastname;
  352.     }
  353.     public function setFirstname($firstname): void
  354.     {
  355.         $this->firstname $firstname;
  356.     }
  357.     public function getFirstname()
  358.     {
  359.         return $this->firstname;
  360.     }
  361.     public function setAddress($address): void
  362.     {
  363.         $this->address $address;
  364.     }
  365.     public function getAddress()
  366.     {
  367.         return $this->address;
  368.     }
  369.     public function setAddressComplement($addressComplement): void
  370.     {
  371.         $this->addressComplement $addressComplement;
  372.     }
  373.     public function getAddressComplement()
  374.     {
  375.         return $this->addressComplement;
  376.     }
  377.     public function setZipCode($zipCode): void
  378.     {
  379.         $this->zipCode $zipCode;
  380.     }
  381.     public function getZipCode()
  382.     {
  383.         return $this->zipCode;
  384.     }
  385.     public function setCity($city): void
  386.     {
  387.         $this->city $city;
  388.     }
  389.     public function getCity()
  390.     {
  391.         return $this->city;
  392.     }
  393.     public function setCountry($country): void
  394.     {
  395.         $this->country $country;
  396.     }
  397.     public function getCountry()
  398.     {
  399.         return $this->country;
  400.     }
  401.     public function getFullCountryName()
  402.     {
  403.         if (null === $this->country) {
  404.             return '';
  405.         }
  406.         try {
  407.             $country Countries::getName($this->country);
  408.         } catch (MissingResourceException) {
  409.             $country $this->country;
  410.         }
  411.         return $country;
  412.     }
  413.     public function setReferralSource($referralSource)
  414.     {
  415.         return $this->referralSource $referralSource;
  416.     }
  417.     public function getReferralSource()
  418.     {
  419.         return $this->referralSource;
  420.     }
  421.     public function setPhone($phone): void
  422.     {
  423.         $this->phone $phone;
  424.     }
  425.     public function getPhone()
  426.     {
  427.         return $this->phone;
  428.     }
  429.     public function setMobile($mobile): void
  430.     {
  431.         $this->mobile preg_replace('/[^0-9+]/'''$mobile);
  432.     }
  433.     public function getMobile()
  434.     {
  435.         return $this->mobile;
  436.     }
  437.     public function setCreatedAt($createdAt): void
  438.     {
  439.         $this->createdAt $createdAt;
  440.     }
  441.     public function getCreatedAt()
  442.     {
  443.         return $this->createdAt;
  444.     }
  445.     public function setSalt($salt): void
  446.     {
  447.         $this->salt $salt;
  448.     }
  449.     public function getSalt(): ?string
  450.     {
  451.         return $this->salt;
  452.     }
  453.     public function setUpdatedAt($updatedAt): void
  454.     {
  455.         $this->updatedAt $updatedAt;
  456.     }
  457.     public function getUpdatedAt()
  458.     {
  459.         return $this->updatedAt;
  460.     }
  461.     public function setNewsletter($newsletter): void
  462.     {
  463.         if ($newsletter !== $this->newsletter) {
  464.             $this->lastOptinChangeDate = new \DateTime();
  465.         }
  466.         $this->newsletter $newsletter;
  467.     }
  468.     public function getLastOptinChangeDate()
  469.     {
  470.         return $this->lastOptinChangeDate;
  471.     }
  472.     public function getNewsletter()
  473.     {
  474.         return $this->newsletter;
  475.     }
  476.     public function setSfAccountId($sfAccountId): void
  477.     {
  478.         $this->sfAccountId $sfAccountId;
  479.     }
  480.     public function getSfAccountId()
  481.     {
  482.         return $this->sfAccountId;
  483.     }
  484.     public function setSfContactId($sfContactId): void
  485.     {
  486.         $this->sfContactId $sfContactId;
  487.     }
  488.     public function getSfContactId()
  489.     {
  490.         return $this->sfContactId;
  491.     }
  492.     public function setSfLeadId($sfLeadId): void
  493.     {
  494.         $this->sfLeadId $sfLeadId;
  495.     }
  496.     public function getSfLeadId()
  497.     {
  498.         return $this->sfLeadId;
  499.     }
  500.     public function addAlertOnVehicle(Vehicle $vehicle): void
  501.     {
  502.         $vehicleAlert = new VehicleAlert($vehicle);
  503.         $this->vehicleAlerts[] = $vehicleAlert;
  504.         $vehicleAlert->setUser($this);
  505.     }
  506.     public function getVehicleAlerts()
  507.     {
  508.         return $this->vehicleAlerts;
  509.     }
  510.     public function hasVehicleAlertOnVehicle(Vehicle $vehicle)
  511.     {
  512.         $criteria Criteria::create();
  513.         $criteria
  514.             ->where(
  515.                 Criteria::expr()->eq('vehicle'$vehicle)
  516.             )
  517.         ;
  518.         return count($this->getVehicleAlerts()->matching($criteria)) > 0;
  519.     }
  520.     public function addAlert(Alert $alerts): void
  521.     {
  522.         $this->alerts[] = $alerts;
  523.     }
  524.     public function getAlerts()
  525.     {
  526.         return $this->alerts;
  527.     }
  528.     public function setEmail($email): void
  529.     {
  530.         $this->email $email;
  531.         $this->setUsername($email);
  532.     }
  533.     public function getAuctions()
  534.     {
  535.         return $this->auctions;
  536.     }
  537.     public function setAuctions($auctions): void
  538.     {
  539.         $this->auctions $auctions;
  540.     }
  541.     public function addVehicleAlert(VehicleAlert $vehicleAlerts): void
  542.     {
  543.         $this->vehicleAlerts[] = $vehicleAlerts;
  544.     }
  545.     public function addTransaction(Transaction $transaction): void
  546.     {
  547.         $this->transactions[] = $transaction;
  548.     }
  549.     /**
  550.      * This is the same check that in findValidTransactionByUserAndSale,
  551.      * but it is less strict since we don't want to hide a transaction that was valid
  552.      * during the sale but expired just after.
  553.      * The threshold is 14 days => 7 days added to the 7 days base threshold.
  554.      *
  555.      * @see TransactionRepository::findValidTransactionByUserAndSale()
  556.      */
  557.     public function getSaleTransaction(Sale $sale)
  558.     {
  559.         $validityThreshold = (new \DateTime('now'))->sub(new \DateInterval('P14D'));
  560.         return $this
  561.             ->transactions
  562.             ->filter(fn ($transaction) =>
  563.                 /* @var Transaction $transaction */
  564.                 $transaction->getSale() === $sale
  565.                 && $transaction->isValid()
  566.                 && $transaction->getCreatedAt() >= $validityThreshold)
  567.             ->first()
  568.         ;
  569.     }
  570.     public function getTransactions()
  571.     {
  572.         return $this->transactions;
  573.     }
  574.     public function addPurchaseInstruction(PurchaseInstruction $purchaseInstruction): void
  575.     {
  576.         $this->purchaseInstructions[] = $purchaseInstruction;
  577.     }
  578.     public function getPurchaseInstructions()
  579.     {
  580.         return $this->purchaseInstructions;
  581.     }
  582.     public function getPurchaseInstructionRules()
  583.     {
  584.         return $this->purchaseInstructionRules;
  585.     }
  586.     public function getBids()
  587.     {
  588.         return $this->bids;
  589.     }
  590.     public function getSalePurchaseInstructionRule(Sale $sale)
  591.     {
  592.         return $this
  593.             ->purchaseInstructionRules
  594.             ->filter(fn ($purchaseInstructionRule) => $purchaseInstructionRule->getSale() === $sale)
  595.             ->first()
  596.         ;
  597.     }
  598.     public function getFullName()
  599.     {
  600.         return sprintf('%s %s'$this->firstname$this->lastname);
  601.     }
  602.     public function setLiveApiKey($liveApiKey): void
  603.     {
  604.         $this->liveApiKey $liveApiKey;
  605.     }
  606.     public function getLiveApiKey()
  607.     {
  608.         return $this->liveApiKey;
  609.     }
  610.     public function setLiveLoggedInAt($liveLoggedInAt): void
  611.     {
  612.         $this->liveLoggedInAt $liveLoggedInAt;
  613.     }
  614.     public function getLiveLoggedInAt()
  615.     {
  616.         return $this->liveLoggedInAt;
  617.     }
  618.     public function setLiveLoggedOutAt($liveLoggedOutAt): void
  619.     {
  620.         $this->liveLoggedOutAt $liveLoggedOutAt;
  621.     }
  622.     public function getLiveLoggedOutAt()
  623.     {
  624.         return $this->liveLoggedOutAt;
  625.     }
  626.     public function setNeedsTransaction($needsTransaction): void
  627.     {
  628.         $this->needsTransaction $needsTransaction;
  629.     }
  630.     public function hasNeedsTransaction()
  631.     {
  632.         return $this->needsTransaction;
  633.     }
  634.     public function setSociety($society): void
  635.     {
  636.         $this->society $society;
  637.     }
  638.     public function isSociety()
  639.     {
  640.         return (bool) $this->society;
  641.     }
  642.     public function setSmsOptin($smsOptin): void
  643.     {
  644.         $this->smsOptin $smsOptin;
  645.     }
  646.     public function isSmsOptin()
  647.     {
  648.         return (bool) $this->smsOptin;
  649.     }
  650.     public function setLanguage($language): void
  651.     {
  652.         $this->language $language;
  653.     }
  654.     public function getLanguage()
  655.     {
  656.         return $this->language;
  657.     }
  658.     /**
  659.      * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $avatar
  660.      *
  661.      * @throws \Exception
  662.      */
  663.     public function setAvatarFile(?File $avatar null): void
  664.     {
  665.         $this->avatarFile $avatar;
  666.         if (null !== $avatar) {
  667.             $this->updatedAt = new \DateTimeImmutable();
  668.         }
  669.     }
  670.     public function getAvatarFile()
  671.     {
  672.         return $this->avatarFile;
  673.     }
  674.     public function setAvatar($avatar): void
  675.     {
  676.         $this->avatar $avatar;
  677.     }
  678.     public function getAvatar()
  679.     {
  680.         return $this->avatar;
  681.     }
  682.     public function setVehicleListType($vehicleListType): void
  683.     {
  684.         $this->vehicleListType $vehicleListType;
  685.     }
  686.     public function getVehicleListType()
  687.     {
  688.         return $this->vehicleListType;
  689.     }
  690.     /**
  691.      * Checks if user has a buyersGroup.
  692.      *
  693.      * @return bool
  694.      */
  695.     public function hasBuyersGroup(BuyersGroup $group)
  696.     {
  697.         return $this->buyersGroups->contains($group);
  698.     }
  699.     /**
  700.      * Add this user to a buyer group.
  701.      *
  702.      * @param BuyersGroup $group The group you want the user to be added to
  703.      */
  704.     public function addBuyersGroup(BuyersGroup $group): void
  705.     {
  706.         if (!$this->hasBuyersGroup($group)) {
  707.             $this->buyersGroups[] = $group;
  708.         }
  709.     }
  710.     public function removeBuyersGroup(BuyersGroup $group): void
  711.     {
  712.         if ($this->hasBuyersGroup($group)) {
  713.             $this->buyersGroups->removeElement($group);
  714.         }
  715.     }
  716.     /**
  717.      * Get the current buyers groups the user is part of.
  718.      *
  719.      * @return ArrayCollection Contains a list of BuyersGroup objects
  720.      */
  721.     public function getBuyersGroups()
  722.     {
  723.         return $this->buyersGroups;
  724.     }
  725.     public function addManagedUser(User $user): void
  726.     {
  727.         $this->managedUsers[] = $user;
  728.     }
  729.     public function removeManagedUser(User $user): void
  730.     {
  731.         $this->managedUsers->remove($user);
  732.     }
  733.     public function getManagedUsers()
  734.     {
  735.         return $this->managedUsers;
  736.     }
  737.     public function addBehaviour(Behaviour $behaviour): void
  738.     {
  739.         $this->behaviours[] = $behaviour;
  740.     }
  741.     public function getBehaviours()
  742.     {
  743.         return $this->behaviours;
  744.     }
  745.     public function hasAccessedSale(Sale $sale)
  746.     {
  747.         foreach ($this->getBehaviours() as $behaviour) {
  748.             if ($behaviour instanceof SaleBehaviour && $sale === $behaviour->getSale()) {
  749.                 return true;
  750.             }
  751.         }
  752.         return false;
  753.     }
  754.     public function addSelection(Vehicle $vehicle): void
  755.     {
  756.         $selection = new Selection($vehicle);
  757.         $this->selections[] = $selection;
  758.         $selection->setUser($this);
  759.     }
  760.     public function getSelections()
  761.     {
  762.         $activeSelections $this->selections->filter(fn ($selection) => $selection->getvehicle()->getSale()->getAfterSaleEndDate() > new \DateTime());
  763.         return $activeSelections;
  764.     }
  765.     public function addSmsAlert(Vehicle $vehicle): void
  766.     {
  767.         $smsAlert = new SmsAlert($vehicle);
  768.         $this->smsAlerts[] = $smsAlert;
  769.         $smsAlert->setUser($this);
  770.     }
  771.     public function getSmsAlerts()
  772.     {
  773.         $activeAlerts $this->smsAlerts->filter(fn ($smsAlert) => $smsAlert->getVehicle()->getAuction()->getClosedAt() > new \DateTime());
  774.         return $activeAlerts;
  775.     }
  776.     public function isGranted($role)
  777.     {
  778.         return in_array($role$this->getRoles());
  779.     }
  780.     public function isForeigner()
  781.     {
  782.         return 'FR' !== $this->country;
  783.     }
  784.     public function isLocked()
  785.     {
  786.         return !$this->isAccountNonLocked();
  787.     }
  788.     public function setLocked($boolean)
  789.     {
  790.         $this->locked $boolean;
  791.         return $this;
  792.     }
  793.     public function isAccountNonLocked()
  794.     {
  795.         return !$this->locked;
  796.     }
  797.     /**
  798.      * Return the number of vehicle that the user is purchasing (Electronic sale or live sale).
  799.      *
  800.      * @return int
  801.      */
  802.     public function countLiveBids()
  803.     {
  804.         $liveBids 0;
  805.         foreach ($this->purchaseInstructions as $pi) {
  806.             if ($pi->getSale()->isActive()) {
  807.                 ++$liveBids;
  808.             }
  809.         }
  810.         foreach ($this->bids as $bid) {
  811.             if ($bid->getAuction()->isOpen()) {
  812.                 ++$liveBids;
  813.             }
  814.         }
  815.         return $liveBids;
  816.     }
  817.     public function isOnlooker()
  818.     {
  819.         return false;
  820.     }
  821.     /**
  822.      * @return string
  823.      */
  824.     public function getOrigin()
  825.     {
  826.         return $this->origin;
  827.     }
  828.     /**
  829.      * @param string $origin
  830.      */
  831.     public function setOrigin($origin): void
  832.     {
  833.         $this->origin $origin;
  834.     }
  835.     public function getCgvSignatures()
  836.     {
  837.         return $this->cgvSignatures;
  838.     }
  839.     public function setCgvSignatures($cgvSignatures): void
  840.     {
  841.         $this->cgvSignatures $cgvSignatures;
  842.     }
  843.     /**
  844.      * @return string
  845.      */
  846.     public function getAdId()
  847.     {
  848.         return $this->adId;
  849.     }
  850.     /**
  851.      * @return $this
  852.      */
  853.     public function setAdId(?string $adId)
  854.     {
  855.         $this->adId $adId;
  856.         return $this;
  857.     }
  858. }