<?php
namespace App\Entity;
use App\Entity\Prescriber\Prescriber;
use App\Utils\Formatter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\PersistentCollection;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\User as BaseUser;
use Gedmo\Mapping\Annotation as Gedmo;
use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Wits\PaymentBundle\Entity\Enum\PaymentMethodTypeEnum;
use Wits\PaymentBundle\Entity\PaymentMethod;
use Wits\PaymentBundle\Entity\StripeUserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User extends BaseUser implements UserInterface, StripeUserInterface, TwoFactorInterface
{
const ROLE_ADMIN = 'ROLE_ADMIN';
const ROLE_FREELANCER = 'ROLE_FREELANCER';
const ROLE_BUSINESS_INTRODUCER = 'ROLE_BUSINESS_INTRODUCER';
const ROLE_CENTRAL_PURCHASING = 'ROLE_CENTRAL_PURCHASING';
const ROLE_FREELANCER_ASSISTANT = 'ROLE_FREELANCER_ASSISTANT';
const ROLE_PRESCRIBER = 'ROLE_PRESCRIBER';
const ROLE_EDITOR = 'ROLE_EDITOR';
const ROLE_USER = 'ROLE_USER';
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @Assert\NotBlank(message="Merci d'entrer votre prénom.", groups={"Registration", "Profile"})
* @Assert\Length(
* min=1,
* max=255,
* minMessage="Le prénom est trop court.",
* maxMessage="Le prénom est trop long.",
* groups={"Registration", "Profile"}
* )
*/
protected $firstname;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @Assert\NotBlank(message="Merci d'entrer votre nom.", groups={"Registration", "Profile"})
* @Assert\Length(
* min=1,
* max=255,
* minMessage="Le nom est trop court.",
* maxMessage="Le nom est trop long.",
* groups={"Registration", "Profile"}
* )
*/
protected $lastname;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @Assert\NotBlank(message="Merci d'entrer votre téléphone.", groups={"Registration", "Profile"})
* @Assert\Regex(
* pattern="/^(?:(?:\+|00)33|0)\s*[1-9](?:[\s.-]*\d{2}){4}$/",
* message="Le téléphone est invalide.",
* groups={"Registration", "Profile"}
* )
*/
protected $phoneNumber;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\HearingBrand")
*/
private $authorizedBrands;
/**
* @Assert\Valid
* @ORM\OneToOne(targetEntity="App\Entity\Administrator", mappedBy="user", cascade={"persist", "remove"})
*/
private $administrator;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $stripeId;
/**
* @ORM\OneToOne(targetEntity=CentralPurchasing::class, mappedBy="user", cascade={"persist", "remove"})
*/
private $centralPurchasing;
/**
* @ORM\OneToOne(targetEntity=FreelancerAssistant::class, mappedBy="user", cascade={"persist", "remove"})
*/
private $freelancerAssistant;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\Column(type="integer", nullable=true)
*
* null tant que le set-up est désactivé
* mettre 0 comme valeur init pour activer la fonctionnalité
* activé le 15/06
*/
private $configStep = 0;
/**
* @ORM\OneToMany(targetEntity=UserTracking::class, mappedBy="user", cascade={"remove"})
*/
private $userTracking;
/**
* @ORM\OneToOne(targetEntity=UserTrackingDuration::class, inversedBy="user", cascade={"persist", "remove"})
*/
private $userTrackingDuration;
/**
* @ORM\OneToMany(targetEntity=PaymentMethod::class, mappedBy="user", orphanRemoval=true)
*/
private $paymentMethods;
/**
* @ORM\OneToOne(targetEntity=PaymentMethod::class)
*/
private $defaultPaymentMethod;
/**
* @ORM\OneToOne(targetEntity=Store::class)
*/
private $storeToAssociateSepaWith;
/**
* Two factor authentification code
* @ORM\Column(type="string", nullable=true)
*/
private string $twoFactorAuthCode;
/**
* Two factor enabled ?
* @ORM\Column(type="boolean")
*/
private bool $emailAuthEnabled = false;
/**
* @ORM\OneToOne(targetEntity=Prescriber::class, mappedBy="user", cascade={"persist", "remove"})
*/
private $prescriber;
public function __construct()
{
parent::__construct();
$this->authorizedBrands = new ArrayCollection();
$this->userTracking = new ArrayCollection();
$this->freelancerComments = new ArrayCollection();
$this->paymentMethods = new ArrayCollection();
}
/**
* Représente l'entité par défault
* @return string
*/
public function __toString()
{
return 'Utilisateur ' . $this->getUsername() . ' [' . $this->getId() . ']';
}
/**
* Représente l'entité dans le BO
* @return string
*/
public function getLabel()
{
return $this->getEmail();
}
public function getId(): ?int
{
return $this->id;
}
public function getMainRole(): string
{
if ($this->isAdmin()) {
return User::ROLE_ADMIN;
} elseif ($this->isTypeFreelancer()) {
return User::ROLE_FREELANCER;
} elseif ($this->isTypeFreelancerAssistant()) {
return User::ROLE_FREELANCER_ASSISTANT;
} else {
return User::ROLE_USER;
}
}
public function isAdmin(): bool
{
return $this->hasRole(User::ROLE_ADMIN) || $this->hasRole(User::ROLE_SUPER_ADMIN);
}
public function hasRoleBusinessIntroducer(): bool
{
return $this->hasRole(User::ROLE_BUSINESS_INTRODUCER);
}
public function hasRoleCentralPurchasing(): bool
{
return $this->hasRole(User::ROLE_CENTRAL_PURCHASING);
}
public function hasRolePrescriber(): bool
{
return $this->hasRole(User::ROLE_PRESCRIBER);
}
/**
* @return Collection|HearingBrand[]
*/
public function getAuthorizedBrands(): Collection
{
return $this->authorizedBrands;
}
public function addAuthorizedBrand(HearingBrand $authorizedBrand): self
{
if (!$this->authorizedBrands->contains($authorizedBrand)) {
$this->authorizedBrands[] = $authorizedBrand;
}
return $this;
}
public function removeAuthorizedBrand(HearingBrand $authorizedBrand): self
{
if ($this->authorizedBrands->contains($authorizedBrand)) {
$this->authorizedBrands->removeElement($authorizedBrand);
}
return $this;
}
public function getAdministrator(): ?Administrator
{
return $this->administrator;
}
public function setAdministrator(?Administrator $administrator): self
{
$this->administrator = $administrator;
// set (or unset) the owning side of the relation if necessary
$newUser = $administrator === null ? null : $this;
if ($newUser !== $administrator->getUser()) {
$administrator->setUser($newUser);
}
return $this;
}
public function getFirstname(): ?string
{
return $this->firstname;
}
public function setFirstname(string $firstname): self
{
$this->firstname = $firstname;
return $this;
}
public function getLastname(): ?string
{
return $this->lastname;
}
public function setLastname(string $lastname): self
{
$this->lastname = $lastname;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phoneNumber;
}
public function setPhoneNumber(string $phoneNumber): self
{
$phoneNumber = Formatter::phoneNumberFrenchFormat($phoneNumber);
$this->phoneNumber = $phoneNumber;
return $this;
}
public function getPhoneNumberFormatted()
{
return wordwrap($this->getPhoneNumber(), 2, ' ', true);
}
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
return $this;
}
public function getFullname(): ?string
{
return ucfirst($this->firstname) . ' ' . strtoupper($this->lastname);
}
public function getFullnameAndEmail(): ?string
{
return $this->getFullname() . ' (' . $this->getEmail() . ')';
}
/**
* @return mixed
*/
public function getStripeId(): ?string
{
return $this->stripeId;
}
/**
* @param mixed $stripeId
*/
public function setStripeId($stripeId): void
{
$this->stripeId = $stripeId;
}
public function getCentralPurchasing(): ?CentralPurchasing
{
return $this->centralPurchasing;
}
public function setCentralPurchasing(CentralPurchasing $centralPurchasing): self
{
$this->centralPurchasing = $centralPurchasing;
// set the owning side of the relation if necessary
if ($centralPurchasing->getUser() !== $this) {
$centralPurchasing->setUser($this);
}
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getFreelancerAssistant(): ?FreelancerAssistant
{
return $this->freelancerAssistant;
}
public function setFreelancerAssistant(FreelancerAssistant $freelancerAssistant): self
{
$this->freelancerAssistant = $freelancerAssistant;
// set the owning side of the relation if necessary
if ($freelancerAssistant->getUser() !== $this) {
$freelancerAssistant->setUser($this);
}
return $this;
}
public function isTypeFreelancer()
{
return $this->administrator instanceof Freelancer;
}
public function isTypePartner()
{
return $this->administrator instanceof Partner;
}
public function isTypeCentralAchat()
{
return !is_null($this->centralPurchasing);
}
public function isTypeFreelancerAssistant()
{
return !is_null($this->freelancerAssistant);
}
public function getConfigStep(): ?int
{
return $this->configStep;
}
public function setConfigStep(?int $configStep): self
{
$this->configStep = $configStep;
return $this;
}
public function hasFinishedConfigStep()
{
return true;//is_null($this->configStep);
}
/**
* @return Collection|UserTracking[]
*/
public function getUserTracking(): Collection
{
return $this->userTracking;
}
public function addUserTracking(UserTracking $userTracking): self
{
if (!$this->userTracking->contains($userTracking)) {
$this->userTracking[] = $userTracking;
$userTracking->setUser($this);
}
return $this;
}
public function removeUserTracking(UserTracking $userTracking): self
{
if ($this->userTracking->contains($userTracking)) {
$this->userTracking->removeElement($userTracking);
// set the owning side to null (unless already changed)
if ($userTracking->getUser() === $this) {
$userTracking->setUser(null);
}
}
return $this;
}
public function getUserTrackingDuration(): ?UserTrackingDuration
{
return $this->userTrackingDuration;
}
public function setUserTrackingDuration(?UserTrackingDuration $userTrackingDuration): self
{
$this->userTrackingDuration = $userTrackingDuration;
return $this;
}
/**
* @return int|null
*/
public function getUserTrackingAverageDuration(): ?int
{
return ($this->getUserTrackingDuration() ? $this->getUserTrackingDuration()->getAverageDuration() : null);
}
/**
* @return Collection|FreelancerComment[]
*/
public function getFreelancerComments(): Collection
{
return $this->freelancerComments;
}
public function addFreelancerComment(FreelancerComment $freelancerComment): self
{
if (!$this->freelancerComments->contains($freelancerComment)) {
$this->freelancerComments[] = $freelancerComment;
$freelancerComment->setAuthor($this);
}
return $this;
}
public function removeFreelancerComment(FreelancerComment $freelancerComment): self
{
if ($this->freelancerComments->contains($freelancerComment)) {
$this->freelancerComments->removeElement($freelancerComment);
// set the owning side to null (unless already changed)
if ($freelancerComment->getAuthor() === $this) {
$freelancerComment->setAuthor(null);
}
}
return $this;
}
/**
* @return PaymentMethod|null
* @deprecated
*/
public function getSepaPaymentMethod(): ?PaymentMethod
{
$methods = $this->paymentMethods->filter(function (PaymentMethod $paymentMethod) {
return $paymentMethod->getType() == PaymentMethodTypeEnum::SEPA;
});
if (count($methods) > 0) {
return $methods[0];
} else {
return null;
}
}
/**
* @return bool
* @deprecated
*/
public function hasSepaPaymentMethod(): bool
{
return !is_null($this->getSepaPaymentMethod());
}
/**
* @return Collection|PaymentMethod[]
*/
public function getPaymentMethods(): Collection
{
return $this->paymentMethods;
}
public function addPaymentMethod(PaymentMethod $paymentMethod): self
{
if (!$this->paymentMethods->contains($paymentMethod)) {
$this->paymentMethods[] = $paymentMethod;
$paymentMethod->setUser($this);
}
return $this;
}
public function removePaymentMethod(PaymentMethod $paymentMethod): self
{
if ($this->paymentMethods->contains($paymentMethod)) {
$this->paymentMethods->removeElement($paymentMethod);
// set the owning side to null (unless already changed)
if ($paymentMethod->getUser() === $this) {
$paymentMethod->setUser(null);
}
}
return $this;
}
public function getStoreToAssociateSepaWith(): ?Store
{
return $this->storeToAssociateSepaWith;
}
public function setStoreToAssociateSepaWith(?Store $storeToAssociateSepaWith): self
{
$this->storeToAssociateSepaWith = $storeToAssociateSepaWith;
return $this;
}
public function clearStoreToAssociateSepaWith(): void
{
$this->setStoreToAssociateSepaWith(null);
}
/**
* @return mixed
*/
public function getDefaultPaymentMethod()
{
return $this->defaultPaymentMethod;
}
/**
* @return boolean
*/
public function hasDefaultPaymentMethod(): bool
{
return !is_null($this->defaultPaymentMethod);
}
/**
* @param mixed $defaultPaymentMethod
*/
public function setDefaultPaymentMethod($defaultPaymentMethod): void
{
$this->defaultPaymentMethod = $defaultPaymentMethod;
}
/**
* Can the user buy credit regarding al his possible status (freelancer, assistant, ...)
* @return bool
*/
public function canBuyCredit(): bool
{
if ($this->isTypeFreelancerAssistant()) {
return $this->getFreelancerAssistant()->getFreelancer()->canBuyCredit();
} elseif ($this->isTypeFreelancer()) {
return $this->getAdministrator()->canBuyCredit();
} else {
return false;
}
}
public function setEmailAuthEnabled(bool $emailAuthEnabled): self
{
$this->emailAuthEnabled = $emailAuthEnabled;
return $this;
}
public function isEmailAuthEnabled(): bool
{
return $this->emailAuthEnabled;
}
public function getEmailAuthRecipient(): string
{
return $this->email;
}
public function getEmailAuthCode(): string
{
if (null === $this->twoFactorAuthCode) {
throw new \LogicException('The email authentication code was not set');
}
return $this->twoFactorAuthCode;
}
public function setEmailAuthCode(string $authCode): void
{
$this->twoFactorAuthCode = $authCode;
}
public function getTrustedTokenVersion(): int
{
return 48645;
}
public function getPrescriber(): ?Prescriber
{
return $this->prescriber;
}
public function isPrescripteur(): bool{
return !is_null($this->prescriber);
}
public function setPrescriber(Prescriber $prescriber): self
{
// set the owning side of the relation if necessary
if ($prescriber->getUser() !== $this) {
$prescriber->setUser($this);
}
$this->prescriber = $prescriber;
return $this;
}
}