<?php
namespace App\Entity\Generic\Customer;
use App\Entity\BaseEntity;
use App\Entity\Shop\Accounting\Transaction;
use App\Entity\Shop\Blog\Article;
use App\Entity\Shop\Blog\Comment;
use App\Entity\Shop\Cart\Cart;
use App\Entity\Shop\Order\Order;
use App\Entity\Shop\Product\ProductReview;
use App\Entity\Shop\Product\ProductReviewReply;
use App\Entity\Shop\Product\ProductReviewVote;
use App\Entity\Shop\Shop\Review;
use App\Entity\Shop\Shop\Shop;
use App\Entity\Shop\Ticket\Ticket;
use App\Entity\Shop\Ticket\TicketMessage;
use App\Repository\Generic\CustomerRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
#[ORM\Table(
name: 'customer',
uniqueConstraints: [
new ORM\UniqueConstraint(name: 'shop_identifier_unique', columns: ['shop_id', 'identifier' , 'mobile'])
]
)]
#[ORM\Entity(repositoryClass: CustomerRepository::class)]
class Customer extends BaseEntity implements UserInterface, PasswordAuthenticatedUserInterface
{
#[ORM\Id]
#[ORM\Column(type: 'guid', unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
private ?string $id;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private mixed $firstName;
#[ORM\Column(length: 180 , nullable: true)]
private ?string $email = null;
#[ORM\Column]
private array $roles = [];
#[ORM\Column(length: 20, nullable: true)]
private ?string $mobile = null;
#[ORM\Column(length: 180)]
private string $identifier; // ایمیل یا شماره موبایل (برای ورود)
/**
* @var string The hashed password
*/
#[ORM\Column]
private ?string $password = null;
#[ORM\Column(type: 'boolean')]
private bool $isVerified = false;
#[ORM\Column(type: Types::BIGINT)]
private ?string $wallet = null;
#[ORM\ManyToOne(inversedBy: 'customers')]
#[ORM\JoinColumn(nullable: false)]
private ?Shop $shop = null;
public function getUserIdentifier(): string
{
return $this->identifier;
}
public function __toString()
{
return $this->getIdentifier();
}
#[ORM\OneToMany(mappedBy: 'customer', targetEntity: Order::class)]
private Collection $orders;
#[ORM\OneToMany(mappedBy: 'customer', targetEntity: Cart::class)]
private Collection $carts;
#[ORM\OneToMany(mappedBy: 'customer', targetEntity: Review::class)]
private Collection $reviews;
#[ORM\OneToMany(mappedBy: 'customer', targetEntity: Address::class)]
private Collection $addresses;
#[ORM\OneToMany(mappedBy: 'author', targetEntity: ProductReview::class)]
private Collection $productReviews;
#[ORM\OneToMany(mappedBy: 'user', targetEntity: ProductReviewVote::class)]
private Collection $productReviewVotes;
#[ORM\OneToMany(mappedBy: 'author', targetEntity: ProductReviewReply::class)]
private Collection $productReviewReplies;
#[ORM\OneToMany(mappedBy: 'author', targetEntity: Article::class)]
private Collection $articles;
#[ORM\OneToMany(mappedBy: 'author', targetEntity: Comment::class)]
private Collection $comments;
#[ORM\OneToMany(mappedBy: 'creator', targetEntity: Ticket::class)]
private Collection $tickets;
#[ORM\OneToMany(mappedBy: 'author', targetEntity: TicketMessage::class)]
private Collection $ticketMessages;
#[ORM\Column(nullable: true)]
private ?int $verifyCode = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $lastName = null;
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Transaction::class)]
private Collection $transactions;
public function __construct()
{
parent::__construct();
$this->wallet = 0;
$this->orders = new ArrayCollection();
$this->carts = new ArrayCollection();
$this->reviews = new ArrayCollection();
$this->addresses = new ArrayCollection();
$this->productReviews = new ArrayCollection();
$this->productReviewVotes = new ArrayCollection();
$this->productReviewReplies = new ArrayCollection();
$this->articles = new ArrayCollection();
$this->comments = new ArrayCollection();
$this->tickets = new ArrayCollection();
$this->ticketMessages = new ArrayCollection();
$this->setVerifyCode(random_int(00000 , 99999));
$this->transactions = new ArrayCollection();
}
public function hasRole($role)
{
return in_array($role, $this->roles);
}
public function getId(): ?string
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): static
{
$this->email = $email;
return $this;
}
/**
* @deprecated since Symfony 5.3, use getUserIdentifier instead
*/
public function getUsername(): string
{
return (string) $this->email;
}
/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): static
{
$this->roles = $roles;
return $this;
}
/**
* @see PasswordAuthenticatedUserInterface
*/
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): static
{
$this->password = $password;
return $this;
}
/**
* Returning a salt is only needed, if you are not using a modern
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
*
* @see UserInterface
*/
public function getSalt(): ?string
{
return null;
}
/**
* @see UserInterface
*/
public function eraseCredentials(): void
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
public function getWallet(): ?string
{
return $this->wallet;
}
public function setWallet(string $wallet): static
{
$this->wallet = $wallet;
return $this;
}
public function getShop(): ?Shop
{
return $this->shop;
}
public function setShop(?Shop $shop): static
{
$this->shop = $shop;
return $this;
}
/**
* @return Collection<int, Order>
*/
public function getOrders(): Collection
{
return $this->orders;
}
public function addOrder(Order $order): static
{
if (!$this->orders->contains($order)) {
$this->orders->add($order);
$order->setCustomer($this);
}
return $this;
}
public function removeOrder(Order $order): static
{
if ($this->orders->removeElement($order)) {
// set the owning side to null (unless already changed)
if ($order->getCustomer() === $this) {
$order->setCustomer(null);
}
}
return $this;
}
/**
* @return Collection<int, Cart>
*/
public function getCarts(): Collection
{
return $this->carts;
}
public function addCart(Cart $cart): static
{
if (!$this->carts->contains($cart)) {
$this->carts->add($cart);
$cart->setCustomer($this);
}
return $this;
}
public function removeCart(Cart $cart): static
{
if ($this->carts->removeElement($cart)) {
// set the owning side to null (unless already changed)
if ($cart->getCustomer() === $this) {
$cart->setCustomer(null);
}
}
return $this;
}
/**
* @return Collection<int, Review>
*/
public function getReviews(): Collection
{
return $this->reviews;
}
public function addReview(Review $review): static
{
if (!$this->reviews->contains($review)) {
$this->reviews->add($review);
$review->setCustomer($this);
}
return $this;
}
public function removeReview(Review $review): static
{
if ($this->reviews->removeElement($review)) {
// set the owning side to null (unless already changed)
if ($review->getCustomer() === $this) {
$review->setCustomer(null);
}
}
return $this;
}
/**
* @return Collection<int, Address>
*/
public function getAddresses(): Collection
{
return $this->addresses;
}
public function addAddress(Address $address): static
{
if (!$this->addresses->contains($address)) {
$this->addresses->add($address);
$address->setCustomer($this);
}
return $this;
}
public function removeAddress(Address $address): static
{
if ($this->addresses->removeElement($address)) {
// set the owning side to null (unless already changed)
if ($address->getCustomer() === $this) {
$address->setCustomer(null);
}
}
return $this;
}
/**
* @return Collection<int, ProductReview>
*/
public function getProductReviews(): Collection
{
return $this->productReviews;
}
public function addProductReview(ProductReview $productReview): static
{
if (!$this->productReviews->contains($productReview)) {
$this->productReviews->add($productReview);
$productReview->setAuthor($this);
}
return $this;
}
public function removeProductReview(ProductReview $productReview): static
{
if ($this->productReviews->removeElement($productReview)) {
// set the owning side to null (unless already changed)
if ($productReview->getAuthor() === $this) {
$productReview->setAuthor(null);
}
}
return $this;
}
/**
* @return Collection<int, ProductReviewVote>
*/
public function getProductReviewVotes(): Collection
{
return $this->productReviewVotes;
}
public function addProductReviewVote(ProductReviewVote $productReviewVote): static
{
if (!$this->productReviewVotes->contains($productReviewVote)) {
$this->productReviewVotes->add($productReviewVote);
$productReviewVote->setUser($this);
}
return $this;
}
public function removeProductReviewVote(ProductReviewVote $productReviewVote): static
{
if ($this->productReviewVotes->removeElement($productReviewVote)) {
// set the owning side to null (unless already changed)
if ($productReviewVote->getUser() === $this) {
$productReviewVote->setUser(null);
}
}
return $this;
}
/**
* @return Collection<int, ProductReviewReply>
*/
public function getProductReviewReplies(): Collection
{
return $this->productReviewReplies;
}
public function addProductReviewReply(ProductReviewReply $productReviewReply): static
{
if (!$this->productReviewReplies->contains($productReviewReply)) {
$this->productReviewReplies->add($productReviewReply);
$productReviewReply->setAuthor($this);
}
return $this;
}
public function removeProductReviewReply(ProductReviewReply $productReviewReply): static
{
if ($this->productReviewReplies->removeElement($productReviewReply)) {
// set the owning side to null (unless already changed)
if ($productReviewReply->getAuthor() === $this) {
$productReviewReply->setAuthor(null);
}
}
return $this;
}
/**
* @return Collection<int, Article>
*/
public function getArticles(): Collection
{
return $this->articles;
}
public function addArticle(Article $article): static
{
if (!$this->articles->contains($article)) {
$this->articles->add($article);
$article->setAuthor($this);
}
return $this;
}
public function removeArticle(Article $article): static
{
if ($this->articles->removeElement($article)) {
// set the owning side to null (unless already changed)
if ($article->getAuthor() === $this) {
$article->setAuthor(null);
}
}
return $this;
}
/**
* @return Collection<int, Comment>
*/
public function getComments(): Collection
{
return $this->comments;
}
public function addComment(Comment $comment): static
{
if (!$this->comments->contains($comment)) {
$this->comments->add($comment);
$comment->setAuthor($this);
}
return $this;
}
public function removeComment(Comment $comment): static
{
if ($this->comments->removeElement($comment)) {
// set the owning side to null (unless already changed)
if ($comment->getAuthor() === $this) {
$comment->setAuthor(null);
}
}
return $this;
}
/**
* @return Collection<int, Ticket>
*/
public function getTickets(): Collection
{
return $this->tickets;
}
public function addTicket(Ticket $ticket): static
{
if (!$this->tickets->contains($ticket)) {
$this->tickets->add($ticket);
$ticket->setCreator($this);
}
return $this;
}
public function removeTicket(Ticket $ticket): static
{
if ($this->tickets->removeElement($ticket)) {
// set the owning side to null (unless already changed)
if ($ticket->getCreator() === $this) {
$ticket->setCreator(null);
}
}
return $this;
}
/**
* @return Collection<int, TicketMessage>
*/
public function getTicketMessages(): Collection
{
return $this->ticketMessages;
}
public function addTicketMessage(TicketMessage $ticketMessage): static
{
if (!$this->ticketMessages->contains($ticketMessage)) {
$this->ticketMessages->add($ticketMessage);
$ticketMessage->setAuthor($this);
}
return $this;
}
public function removeTicketMessage(TicketMessage $ticketMessage): static
{
if ($this->ticketMessages->removeElement($ticketMessage)) {
// set the owning side to null (unless already changed)
if ($ticketMessage->getAuthor() === $this) {
$ticketMessage->setAuthor(null);
}
}
return $this;
}
public function getMobile(): ?string
{
return $this->mobile;
}
public function setMobile(?string $mobile): void
{
$this->mobile = $mobile;
}
public function getIdentifier(): string
{
return $this->identifier;
}
public function setIdentifier(string $identifier): void
{
$this->identifier = $identifier;
}
public function isVerified(): bool
{
return $this->isVerified;
}
public function setIsVerified(bool $isVerified): void
{
$this->isVerified = $isVerified;
}
public function getVerifyCode(): ?int
{
return $this->verifyCode;
}
public function setVerifyCode(?int $verifyCode): void
{
$this->verifyCode = $verifyCode;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(?string $lastName): static
{
$this->lastName = $lastName;
return $this;
}
/**
* @return Collection<int, Transaction>
*/
public function getTransactions(): Collection
{
return $this->transactions;
}
public function addTransaction(Transaction $transaction): static
{
if (!$this->transactions->contains($transaction)) {
$this->transactions->add($transaction);
$transaction->setOwner($this);
}
return $this;
}
public function removeTransaction(Transaction $transaction): static
{
if ($this->transactions->removeElement($transaction)) {
// set the owning side to null (unless already changed)
if ($transaction->getOwner() === $this) {
$transaction->setOwner(null);
}
}
return $this;
}
public function getFirstName(): mixed
{
return $this->firstName;
}
public function setFirstName(mixed $firstName): void
{
$this->firstName = $firstName;
}
}