<?php
namespace App\Entity;
use Doctrine\DBAL\Types\Types;
use App\Entity\ProduitPromotion;
use Doctrine\ORM\Mapping as ORM;
use App\Repository\ProduitRepository;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;
#[ORM\Entity(repositoryClass: ProduitRepository::class)]
class Produit
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $product_name = null;
#[ORM\Column]
private ?int $qtt = null;
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: '2')]
private ?string $prix = null;
#[ORM\ManyToOne(inversedBy: 'produits')]
#[ORM\JoinColumn(nullable: false)]
private ?Category $category = null;
#[ORM\Column(nullable: true)]
private ?bool $publishItem = null;
#[ORM\ManyToOne(inversedBy: 'produits')]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null;
#[ORM\Column(nullable: true)]
private ?bool $promo = null;
#[ORM\OneToMany(mappedBy: 'produit', targetEntity: CommandeDetails::class, orphanRemoval: true)]
private Collection $commandeDetails;
#[ORM\Column(length: 300)]
private ?string $Description = null;
#[ORM\OneToMany(mappedBy: 'produit', targetEntity: Image::class,
orphanRemoval: true,cascade:['persist'])]
private Collection $images;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $publish_date = null;
#[ORM\OneToMany(mappedBy: 'produit', targetEntity: ProduitPromotion::class, orphanRemoval: true)]
private Collection $promotions;
#[ORM\OneToMany(mappedBy: 'produit', targetEntity: ProduitVariant::class, orphanRemoval: true,cascade:['persist'])]
private Collection $produitVariants;
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2, nullable: true)]
private ?string $sale_price = null;
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2, nullable: true)]
private ?string $cost_price = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $date_production = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $date_expiration = null;
#[ORM\ManyToOne(inversedBy: 'produits')]
#[ORM\JoinColumn(nullable: false)]
private ?Magasin $magasin = null;
// ── Up to 3 named variant dimensions (e.g. "Scent", "Size", "Color") ──
#[ORM\Column(length: 255, nullable: true)]
private ?string $variant_type = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $variant_type2 = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $variant_type3 = null;
public function __construct()
{
$this->commandeDetails = new ArrayCollection();
$this->images = new ArrayCollection();
$this->promotions = new ArrayCollection();
$this->produitVariants = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getProductName(): ?string
{
return $this->product_name;
}
public function setProductName(string $product_name): self
{
$this->product_name = $product_name;
return $this;
}
public function getQtt(): ?int
{
return $this->qtt;
}
public function setQtt(?int $qtt): self
{
$this->qtt = $qtt;
return $this;
}
// normale price without promotion
public function getPrix(): ?string
{
return $this->prix;
}
public function setPrix(?string $prix): self
{
$this->prix = $prix;
return $this;
}
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
$this->category = $category;
return $this;
}
public function getPublishItem(): ?bool
{
return $this->publishItem;
}
public function setPublishItem(?bool $publishItem): self
{
$this->publishItem = $publishItem;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function isPromo(): ?bool
{
return $this->promo;
}
public function setPromo(?bool $promo): self
{
$this->promo = $promo;
return $this;
}
/**
* @return Collection<int, CommandeDetails>
*/
public function getCommandeDetails(): Collection
{
return $this->commandeDetails;
}
public function addCommandeDetail(CommandeDetails $commandeDetail): self
{
if (!$this->commandeDetails->contains($commandeDetail)) {
$this->commandeDetails->add($commandeDetail);
$commandeDetail->setProduit($this);
}
return $this;
}
public function removeCommandeDetail(CommandeDetails $commandeDetail): self
{
if ($this->commandeDetails->removeElement($commandeDetail)) {
// set the owning side to null (unless already changed)
if ($commandeDetail->getProduit() === $this) {
$commandeDetail->setProduit(null);
}
}
return $this;
}
public function __toString(): string{
return $this->product_name;
}
public function getDescription(): ?string
{
return $this->Description;
}
public function setDescription(string $Description): self
{
$this->Description = $Description;
return $this;
}
/**
* @return Collection<int, Image>
*/
public function getImages(): Collection
{
return $this->images;
}
public function addImage(Image $image): self
{
if (!$this->images->contains($image)) {
$this->images->add($image);
$image->setProduit($this);
}
return $this;
}
public function removeImage(Image $image): self
{
if ($this->images->removeElement($image)) {
// set the owning side to null (unless already changed)
if ($image->getProduit() === $this) {
$image->setProduit(null);
}
}
return $this;
}
public function getPublishDate(): ?\DateTimeInterface
{
return $this->publish_date;
}
public function setPublishDate(?\DateTimeInterface $publish_date): self
{
$this->publish_date = $publish_date;
return $this;
}
/**
* @return Collection<int, ProduitPromotion>
*/
public function getPromotions(): Collection
{
return $this->promotions;
}
public function getCurrentPromoRate(): float
{
$promorate = 0; // Default rate if no promotion found
$promotions = $this->promotions; // Get the promotions collection
$dateins = new \DateTime();
try {
// Check if there are promotions
if ($promotions->count() > 0) {
// Filtrer les promotions en fonction des dates de début et de fin
$filteredPromotions = $promotions->filter(function ($promotion) use ($dateins) {
$debutPromo = $promotion->getDateDebutPromo();
$finPromo = $promotion->getDateFinPromo();
// Make sure both dates are valid DateTime objects
if ($debutPromo instanceof DateTime && $finPromo instanceof DateTime) {
return $debutPromo <= $dateins && $finPromo > $dateins;
}
// Skip promotion if dates are invalid
return false;
});
$firstPromotion = $filteredPromotions->first();
// If there is at least one active promotion
if ($firstPromotion) {
// Get the rate of the first active promotion
$promo = $firstPromotion->getPromotion();
// Vérifiez si la première promotion existe et si la méthode `getRate()` est accessible
if ($promo && method_exists($promo, 'getRate')) {
$promorate = (float) $promo->getRate();
} else {
$promorate = 0; // Ensure the rate is set to 0 in case of error
}
}
}
} catch (\Exception $e) {
// Catch any exception and log or handle it
error_log('Error fetching promotion: ' . $e->getMessage());
$promorate = 0; // Ensure the rate is set to 0 in case of error
}
// Return the promotion rate (0 if no promotion is active)
return $promorate;
}
public function addPromotion(ProduitPromotion $promotion): self
{
if (!$this->promotions->contains($promotion)) {
$this->promotions->add($promotion);
$promotion->setProduit($this);
}
return $this;
}
public function removePromotion(ProduitPromotion $promotion): self
{
if ($this->promotions->removeElement($promotion)) {
// set the owning side to null (unless already changed)
if ($promotion->getProduit() === $this) {
$promotion->setProduit(null);
}
}
return $this;
}
/**
* @return Collection<int, ProduitVariant>
*/
public function getProduitVariants(): Collection
{
return $this->produitVariants;
}
public function addProduitVariant(ProduitVariant $produitVariant): static
{
if (!$this->produitVariants->contains($produitVariant)) {
$this->produitVariants->add($produitVariant);
$produitVariant->setProduit($this);
}
return $this;
}
public function removeProduitVariant(ProduitVariant $produitVariant): static
{
if ($this->produitVariants->removeElement($produitVariant)) {
// set the owning side to null (unless already changed)
if ($produitVariant->getProduit() === $this) {
$produitVariant->setProduit(null);
}
}
return $this;
}
// after promo price
public function getSalePrice(): ?string
{
$rate = $this->getCurrentPromoRate();
if ($rate > 0){
//calculer le prix
$discount = $this->prix * $rate/100 ;
$this->sale_price = $this->prix - $discount ;
}
else{
$this->sale_price =null;
}
return $this->sale_price ?? $this->getPrix();
}
public function setSalePrice(string $sale_price): static
{
$this->sale_price = $sale_price;
return $this;
}
public function getCostPrice(): ?string
{
return $this->cost_price;
}
public function setCostPrice(?string $cost_price): static
{
$this->cost_price = $cost_price;
return $this;
}
public function getDateProduction(): ?\DateTimeInterface
{
return $this->date_production;
}
public function setDateProduction(?\DateTimeInterface $date_production): static
{
$this->date_production = $date_production;
return $this;
}
public function getDateExpiration(): ?\DateTimeInterface
{
return $this->date_expiration;
}
public function setDateExpiration(?\DateTimeInterface $date_expiration): static
{
$this->date_expiration = $date_expiration;
return $this;
}
public function getMagasin(): ?Magasin
{
return $this->magasin;
}
public function setMagasin(?Magasin $magasin): static
{
$this->magasin = $magasin;
return $this;
}
public function getVariantType(): ?string
{
return $this->variant_type;
}
public function setVariantType(?string $variant_type): self
{
$this->variant_type = $variant_type;
return $this;
}
public function getVariantType2(): ?string
{
return $this->variant_type2;
}
public function setVariantType2(?string $variant_type2): self
{
$this->variant_type2 = $variant_type2;
return $this;
}
public function getVariantType3(): ?string
{
return $this->variant_type3;
}
public function setVariantType3(?string $variant_type3): self
{
$this->variant_type3 = $variant_type3;
return $this;
}
}