<?php
namespace App\Entity;
use App\Utils\Formatter;
use App\Validator as McaAssert;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use phpDocumentor\Reflection\Types\Integer;
use Symfony\Component\Validator\Constraints as Assert;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity(repositoryClass="App\Repository\ProspectRepository")
* @ORM\EntityListeners({"App\Listener\ProspectListener"})
* @ApiResource(
* collectionOperations={
"post"={
* "validation_groups"={"Default", "API"}
* },
*
* },
* itemOperations={"get"={"security"="is_granted('ROLE_API')"}},
* normalizationContext={"groups"={"prospect:read"}},
* denormalizationContext={"groups"={"prospect:write"}}
* )
*/
class Prospect implements MediaoptionDeliverable
{
const TYPE_APPOINTMENT = 'appointment';
const TYPE_CHECKUP = 'checkup';
const ACQUISITION_MODE_API = 'api';
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="create")
*/
private $created;
/**
* @ORM\Column(type="smallint", nullable=true)
* @Assert\NotBlank(groups={"API"})
* @Groups({"prospect:write"})
*/
private $gender;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"prospect:read", "prospect:write"})
* @Assert\NotBlank
* @Assert\Length(
* min = 2,
* max = 50,
* )
* @Assert\Regex(
* pattern="/^[A-Za-zÀ-úœ'\-\s]*$/",
* message="Le prénom n'est pas valide"
* )
*/
private $firstname;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"prospect:read", "prospect:write"})
* @Assert\NotBlank
* @Assert\Regex(
* pattern="/^[A-Za-zÀ-úœ'\-\s]*$/",
* message="Le nom n'est pas valide"
* )
* @Assert\Length(
* min = 2,
* max = 50,
* )
*/
private $lastname;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"prospect:read", "prospect:write"})
* @Assert\NotBlank()
* @Assert\Length(
* min = 2,
* max = 200,
* )
*/
private $address;
/**
* @ORM\Column(type="string", length=5)
* @Assert\NotBlank()
* @Assert\Regex(
* pattern="/^(([0-8][0-9])|(9[0-5])|(2[ab]))[0-9]{3}$/",
* message="Le code postal n'est pas valide"
* )
* @Groups({"prospect:read", "prospect:write"})
*/
private $postalcode;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\Length(
* min = 2,
* max = 50,
* )
* @Assert\NotBlank(groups={"API"})
* @Groups({"prospect:read", "prospect:write"})
*/
private $city;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\NotBlank
* @Assert\Regex ("/^\w([\w\-\_\+\.\d]+?)+@[\w-]+(\.[A-Za-z]{2,4}){1,2}$/")
* @Assert\Email(
* message = "L'email '{{ value }}' n'est pas valide",
* mode = "strict"
* )
* @Groups({"prospect:read", "prospect:write"})
*/
private $email;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\NotBlank
* @McaAssert\ValidPhoneNumber
* @Groups({"prospect:read", "prospect:write"})
*/
private $phoneNumber;
/**
* @ORM\Column(type="string", length=4, nullable=true)
* @Assert\NotBlank()
* @Assert\Regex(pattern="/^(19|20)\d{2}$/", message="L'année de naissance n'est pas valide.")
* @Groups({"prospect:read", "prospect:write"})
*/
private $yearOfBirth;
/**
* @ORM\Column(type="boolean")
* @Groups({"prospect:read", "prospect:write"})
*/
private $isPrivacy=0;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"prospect:read", "prospect:write"})
*/
private $isOptin;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"prospect:read", "prospect:write"})
*/
private $isPartnerOffer;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"prospect:read", "prospect:write"})
*/
private $request;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\PhoneValidation", inversedBy="prospect", cascade={"persist", "remove"})
* @ORM\JoinColumn(nullable=true)
*/
private $phoneValidation;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProspectOnStore", mappedBy="prospect", cascade={"persist", "remove"})
*/
private $prospectsOnStore;
/**
* @ORM\OneToMany(targetEntity="App\Entity\MediaoptinDelivery", mappedBy="prospect", cascade={"persist", "remove"})
*/
private $mediaoptinDeliveries;
/**
* Mode d'acquisition du lead (emailing, facebook, ...)
*
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"prospect:write"})
*/
private $acquisitionMode;
/**
* Base emailing de provenance du lead
*
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\NotBlank(groups={"API"})
* @Groups({"prospect:write"})
*/
private $acquisitionBase;
/**
* Url de provenance du lead (dernière URL avant persist)
*
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"prospect:write"})
*/
private $acquisitionUrl;
/**
* Meta keyword URL
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"prospect:write"})
*/
private $acquisitionKeyword;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $latitude;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $longitude;
/**
* @var string
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $locationType;
/**
* @var string
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $countryCode;
/**
* @var boolean
* @ORM\Column(type="boolean")
*/
private $isDropped = false;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProspectDuplicate", mappedBy="prospect", cascade={"remove"})
*/
private $prospectDuplicates;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private $duplicateState;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"prospect:write"})
* @var boolean
*/
private $isOrlPrescription;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"prospect:write"})
* @var boolean
*/
private $isEquipped;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"prospect:write"})
* @var boolean
*/
private $isThirdPerson;
/**
* @ORM\OneToOne(targetEntity=ProspectQualification::class, cascade={"persist", "remove"}, inversedBy="prospect")
*/
private $qualification;
/**
* Add checkmail boolean on prospect: yes->email validated , no->email invalid, null->no validation has been done
* @ORM\Column(type="boolean", nullable=true)
*/
private $checkmail;
/**
* @ORM\Column(type="boolean")
*/
private bool $isUsingDoctolib=false;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"prospect:write"})
*/
private ?bool $isQualifiedExternally=false;
public function __construct()
{
$this->prospectsOnStore = new ArrayCollection();
$this->mediaoptinDeliveries = new ArrayCollection();
$this->prospectDuplicates = new ArrayCollection();
}
/**
* Représente l'entité par défault
* @return string
*/
public function __toString(){
return 'Prospect ['.$this->getId().']';
}
/**
* Obtenir l'adresse complète
* @return string
*/
public function getFullAddress() {
return $this->getAddress() . ' ' . $this->getPostalcode() . ' ' . $this->getCity();
}
/**
* Représente l'entité dans le BO
* @return string
*/
public function getLabel(){
return '#'.$this->getId();
}
public function getId(): ?int
{
return $this->id;
}
public function getGender(): ?int
{
return $this->gender;
}
public function setGender(?int $gender): self
{
$this->gender = $gender;
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 getFullname(): ?string
{
return ucfirst($this->firstname).' '.ucfirst($this->lastname);
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
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 getYearOfBirth(): ?string
{
return $this->yearOfBirth;
}
public function setYearOfBirth(?string $yearOfBirth): self
{
//prevent insertion of non numeri value (ex: 1994-05-17). if not numeric field remains blank
$yearOfBirth = substr($yearOfBirth,0,4);
if(is_numeric($yearOfBirth)){
$this->yearOfBirth = $yearOfBirth;
}
return $this;
}
public function getDateFromYearOfBirth(): ?\DateTimeInterface {
return new \DateTime($this->getYearOfBirth() . '-01-01');
}
public function getAge(): int {
$now = new \DateTime();
return $this->getDateFromYearOfBirth()->diff($now)->y;
}
public function getRequest(): ?string
{
return $this->request;
}
public function setRequest(string $request): self
{
$this->request = $request;
return $this;
}
public function getIsPrivacy(): ?bool
{
return $this->isPrivacy;
}
public function setIsPrivacy(bool $isPrivacy): self
{
$this->isPrivacy = $isPrivacy;
return $this;
}
public function getIsOptin(): ?bool
{
return $this->isOptin;
}
public function setIsOptin(bool $isOptin): self
{
$this->isOptin = $isOptin;
return $this;
}
public function getIsPartnerOffer(): ?bool
{
return $this->isPartnerOffer;
}
public function setIsPartnerOffer(bool $isPartnerOffer): self
{
$this->isPartnerOffer = $isPartnerOffer;
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(?string $address): self
{
$this->address = $address;
return $this;
}
public function getPostalcode(): ?string
{
return $this->postalcode;
}
public function setPostalcode(?string $postalcode): self
{
if(strlen($postalcode) === 4) {
$this->postalcode = str_pad($postalcode, 5, '0', STR_PAD_LEFT);
} else {
$this->postalcode = $postalcode;
}
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(?string $city): self
{
$this->city = $city;
return $this;
}
public function getPhoneValidation(): ?PhoneValidation
{
return $this->phoneValidation;
}
public function setPhoneValidation(?PhoneValidation $phoneValidation): self
{
$this->phoneValidation = $phoneValidation;
return $this;
}
public function getExportProspectsOnStore()
{
$exportStores = [];
foreach ($this->getProspectsOnStore() as $key => $val) {
$str = $val->getStore()->getName() . ' (' . $val->getStore()->getZipCode(). ')';
if($val->getIsDemandForThird()){
$str .= " <span class=\"badge badge-warning\">demande pour un tiers</span>";
}
$exportStores[] = $str;
}
return join(' , ', $exportStores);
}
/**
* @return Collection|ProspectOnStore[]
*/
public function getProspectsOnStore(): Collection
{
return $this->prospectsOnStore;
}
/**
* @param Store $store
* @return ?ProspectOnStore
*/
public function getProspectOnStore(Store $store): ?ProspectOnStore
{
$criteria = Criteria::create() ->andWhere(Criteria::expr()->eq('store', $store))->setMaxResults(1);
$pos = $this->prospectsOnStore->matching($criteria);
if($pos->isEmpty()){
return null;
}else{
return $pos->first();
}
}
/**
* @return int
*/
public function getNbOfProspectsOnStore(): int
{
return $this->prospectsOnStore->count();
}
public function addProspectsOnStore(ProspectOnStore $prospectsOnStore): self
{
if (!$this->prospectsOnStore->contains($prospectsOnStore)) {
$this->prospectsOnStore[] = $prospectsOnStore;
$prospectsOnStore->setProspect($this);
}
return $this;
}
public function removeProspectsOnStore(ProspectOnStore $prospectsOnStore): self
{
if ($this->prospectsOnStore->contains($prospectsOnStore)) {
$this->prospectsOnStore->removeElement($prospectsOnStore);
// set the owning side to null (unless already changed)
if ($prospectsOnStore->getProspect() === $this) {
$prospectsOnStore->setProspect(null);
}
}
return $this;
}
public function getCreated(): ?\DateTimeInterface
{
return $this->created;
}
public function setCreated(\DateTimeInterface $created): self
{
$this->created = $created;
return $this;
}
/**
* @return Collection|MediaoptinDelivery[]
*/
public function getMediaoptinDeliveriesOwnOrByStore(): Collection
{
if(empty($this->prospectsOnStore)){
return $this->mediaoptinDeliveries;
}else{
$deliveries = [];
foreach ($this->prospectsOnStore as $pos){
$deliveries = array_merge($deliveries, $pos->getMediaoptinDeliveries()->toArray() );
}
return new ArrayCollection($deliveries);
}
}
public function getExportMediaoptinDeliveriesOwnOrByStore()
{
//dump($this->getMediaoptinDeliveriesOwnOrByStore());
$exportDeliveries = [];
foreach ($this->getMediaoptinDeliveriesOwnOrByStore() as $key => $val) {
if($val->getDeliveryDate()){
$str = $val->getDeliveryDate()->format('d/m/Y');
}else{
$str = $val->getResponse();
}
$exportDeliveries[] = $str;
}
return join(', ', $exportDeliveries);
}
/**
* Display the label of deliveries (for export)
* @return string|null
*/
public function getDeliveryStatusLabel(): ?string {
$deliveries = $this->getMediaoptinDeliveriesOwnOrByStore();
if(count($deliveries)==0){
return 'multi';
}
foreach ($deliveries as $delivery){
if($delivery->isSuccessful()){
return 'livré';
}else{
return 'erreur';
}
}
return null;
}
/**
* @return Collection|MediaoptinDelivery[]
*/
public function getMediaoptinDeliveries(): Collection
{
return $this->mediaoptinDeliveries;
}
public function addMediaoptinDelivery(MediaoptinDelivery $mediaoptinDelivery): self
{
if (!$this->mediaoptinDeliveries->contains($mediaoptinDelivery)) {
$this->mediaoptinDeliveries[] = $mediaoptinDelivery;
$mediaoptinDelivery->setProspect($this);
}
return $this;
}
public function removeMediaoptinDelivery(MediaoptinDelivery $mediaoptinDelivery): self
{
if ($this->mediaoptinDeliveries->contains($mediaoptinDelivery)) {
$this->mediaoptinDeliveries->removeElement($mediaoptinDelivery);
// set the owning side to null (unless already changed)
if ($mediaoptinDelivery->getProspect() === $this) {
$mediaoptinDelivery->setProspect(null);
}
}
return $this;
}
public function getAcquisitionMode(): ?string
{
return $this->acquisitionMode;
}
public function setAcquisitionMode(?string $acquisitionMode): self
{
$this->acquisitionMode = $acquisitionMode;
return $this;
}
public function getAcquisitionBase(): ?string
{
return $this->acquisitionBase;
}
public function setAcquisitionBase(?string $acquisitionBase): self
{
$this->acquisitionBase = $acquisitionBase;
return $this;
}
public function getAcquisitionUrl(): ?string
{
return $this->acquisitionUrl;
}
public function setAcquisitionUrl(?string $acquisitionUrl): self
{
$this->acquisitionUrl = $acquisitionUrl;
return $this;
}
public function getLatitude(): ?float
{
return $this->latitude;
}
public function setLatitude(?float $latitude): self
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?float
{
return $this->longitude;
}
public function setLongitude(?float $longitude): self
{
$this->longitude = $longitude;
return $this;
}
public function getLocationType(): ?string
{
return $this->locationType;
}
public function setLocationType(?string $locationType): self
{
$this->locationType = $locationType;
return $this;
}
public function getCountryCode(): ?string
{
return $this->countryCode;
}
public function setCountryCode(?string $countryCode): self
{
$this->countryCode = $countryCode;
return $this;
}
public function getIsDropped(): ?bool
{
return $this->isDropped;
}
public function setIsDropped(bool $isDropped): self
{
$this->isDropped = $isDropped;
return $this;
}
public function getLeadNumber(){
return md5($this->getEmail());
}
/**
* @return Collection|ProspectDuplicate[]
*/
public function getProspectDuplicates(): Collection
{
return $this->prospectDuplicates;
}
/**
* @return integer
*/
public function getNbOfProspectDuplicates(): int
{
return $this->prospectDuplicates->count();
}
public function addProspectDuplicate(ProspectDuplicate $prospectDuplicate): self
{
if (!$this->prospectDuplicates->contains($prospectDuplicate)) {
$this->prospectDuplicates[] = $prospectDuplicate;
$prospectDuplicate->setProspect($this);
}
return $this;
}
public function removeProspectDuplicate(ProspectDuplicate $prospectDuplicate): self
{
if ($this->prospectDuplicates->contains($prospectDuplicate)) {
$this->prospectDuplicates->removeElement($prospectDuplicate);
// set the owning side to null (unless already changed)
if ($prospectDuplicate->getProspect() === $this) {
$prospectDuplicate->setProspect(null);
}
}
return $this;
}
public function getDuplicateState(): ?int
{
return $this->duplicateState;
}
public function setDuplicateState($state): self
{
$this->duplicateState = $state;
return $this;
}
public function getIsOrlPrescription(): ?bool
{
return $this->isOrlPrescription;
}
public function setIsOrlPrescription(?bool $isOrlPrescription): self
{
$this->isOrlPrescription = $isOrlPrescription;
return $this;
}
public function getIsEquipped(): ?bool
{
return $this->isEquipped;
}
public function setIsEquipped(?bool $isEquipped): self
{
$this->isEquipped = $isEquipped;
return $this;
}
public function getIsThirdPerson(): ?bool
{
return $this->isThirdPerson;
}
public function setIsThirdPerson(?bool $isThirdPerson): self
{
$this->isThirdPerson = $isThirdPerson;
return $this;
}
/**
* Export for Sonata Admin
* @return string
*/
public function getExportIsOrlPrescription() {
if(isset($this->isOrlPrescription)) {
return $this->getIsOrlPrescription() ? "Oui" : "Non";
} else {
return "Non renseigné";
}
}
/**
* Export for Sonata Admin
* @return string
*/
public function getExportIsEquipped() {
if(isset($this->isEquipped)) {
return $this->getIsEquipped() ? "Oui" : "Non";
} else {
return "Non renseigné";
}
}
/**
* Export for Sonata Admin
* @return string
*/
public function getExportIsThirdPerson() {
if(isset($this->isThirdPerson)) {
return $this->getIsThirdPerson() ? "Oui" : "Non";
} else {
return "Non renseigné";
}
}
public function getQualification(): ?ProspectQualification
{
return $this->qualification;
}
public function setQualification(?ProspectQualification $qualification): self
{
$this->qualification = $qualification;
return $this;
}
public function getCheckmail(): ?bool
{
return $this->checkmail;
}
public function setCheckmail(?bool $checkmail): self
{
$this->checkmail = $checkmail;
return $this;
}
public function getAcquisitionKeyword(): ?string
{
return $this->acquisitionKeyword;
}
public function setAcquisitionKeyword(?string $acquisitionKeyword): self
{
$this->acquisitionKeyword = $acquisitionKeyword;
return $this;
}
/**
* @return bool
*/
public function isUsingDoctolib(): bool
{
return $this->isUsingDoctolib;
}
/**
* @param bool $isUsingDoctolib
*/
public function setIsUsingDoctolib(bool $isUsingDoctolib): void
{
$this->isUsingDoctolib = $isUsingDoctolib;
}
public function getIsQualifiedExternally(): ?bool
{
return $this->isQualifiedExternally;
}
public function setIsQualifiedExternally($isQualifiedExternally): void
{
$this->isQualifiedExternally = boolval($isQualifiedExternally);
}
}