<?php
namespace App\Entity;
use App\Repository\FactureFournisseurRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: FactureFournisseurRepository::class)]
class FactureFournisseur
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 100, unique: true)]
private ?string $numeroFacture = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $dateFacture = null;
#[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
private ?\DateTimeInterface $dateEcheance = null;
#[ORM\ManyToOne(inversedBy: 'factures')]
#[ORM\JoinColumn(nullable: false)]
private ?Fournisseur $fournisseur = null;
#[ORM\Column]
private ?float $montantHT = null;
#[ORM\Column]
private ?float $montantTVA = null;
#[ORM\Column]
private ?float $montantTTC = null;
#[ORM\Column]
private ?float $montantPaye = 0;
#[ORM\Column(length: 50)]
private ?string $statut = 'EN_ATTENTE'; // EN_ATTENTE, PARTIELLEMENT_PAYEE, PAYEE
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $notes = null;
#[ORM\ManyToOne]
private ?Boutique $boutique = null;
#[ORM\ManyToOne]
private ?User $creePar = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $createdAt = null;
#[ORM\OneToMany(mappedBy: 'factureFournisseur', targetEntity: PaiementFournisseur::class)]
private Collection $paiements;
#[ORM\OneToMany(mappedBy: 'factureFournisseur', targetEntity: EntreeStock::class)]
private Collection $entreesStock;
public function __construct()
{
$this->paiements = new ArrayCollection();
$this->entreesStock = new ArrayCollection();
$this->createdAt = new \DateTime();
$this->dateFacture = new \DateTime();
}
public function getId(): ?int
{
return $this->id;
}
public function getNumeroFacture(): ?string
{
return $this->numeroFacture;
}
public function setNumeroFacture(string $numeroFacture): static
{
$this->numeroFacture = $numeroFacture;
return $this;
}
public function getDateFacture(): ?\DateTimeInterface
{
return $this->dateFacture;
}
public function setDateFacture(\DateTimeInterface $dateFacture): static
{
$this->dateFacture = $dateFacture;
return $this;
}
public function getDateEcheance(): ?\DateTimeInterface
{
return $this->dateEcheance;
}
public function setDateEcheance(?\DateTimeInterface $dateEcheance): static
{
$this->dateEcheance = $dateEcheance;
return $this;
}
public function getFournisseur(): ?Fournisseur
{
return $this->fournisseur;
}
public function setFournisseur(?Fournisseur $fournisseur): static
{
$this->fournisseur = $fournisseur;
return $this;
}
public function getMontantHT(): ?float
{
return $this->montantHT;
}
public function setMontantHT(float $montantHT): static
{
$this->montantHT = $montantHT;
return $this;
}
public function getMontantTVA(): ?float
{
return $this->montantTVA;
}
public function setMontantTVA(float $montantTVA): static
{
$this->montantTVA = $montantTVA;
return $this;
}
public function getMontantTTC(): ?float
{
return $this->montantTTC;
}
public function setMontantTTC(float $montantTTC): static
{
$this->montantTTC = $montantTTC;
return $this;
}
public function getMontantPaye(): ?float
{
return $this->montantPaye;
}
public function setMontantPaye(float $montantPaye): static
{
$this->montantPaye = $montantPaye;
return $this;
}
public function getStatut(): ?string
{
return $this->statut;
}
public function setStatut(string $statut): static
{
$this->statut = $statut;
return $this;
}
public function getNotes(): ?string
{
return $this->notes;
}
public function setNotes(?string $notes): static
{
$this->notes = $notes;
return $this;
}
public function getBoutique(): ?Boutique
{
return $this->boutique;
}
public function setBoutique(?Boutique $boutique): static
{
$this->boutique = $boutique;
return $this;
}
public function getCreePar(): ?User
{
return $this->creePar;
}
public function setCreePar(?User $creePar): static
{
$this->creePar = $creePar;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): static
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return Collection<int, PaiementFournisseur>
*/
public function getPaiements(): Collection
{
return $this->paiements;
}
public function addPaiement(PaiementFournisseur $paiement): static
{
if (!$this->paiements->contains($paiement)) {
$this->paiements->add($paiement);
$paiement->setFactureFournisseur($this);
}
return $this;
}
public function removePaiement(PaiementFournisseur $paiement): static
{
if ($this->paiements->removeElement($paiement)) {
if ($paiement->getFactureFournisseur() === $this) {
$paiement->setFactureFournisseur(null);
}
}
return $this;
}
/**
* @return Collection<int, EntreeStock>
*/
public function getEntreesStock(): Collection
{
return $this->entreesStock;
}
public function addEntreeStock(EntreeStock $entreeStock): static
{
if (!$this->entreesStock->contains($entreeStock)) {
$this->entreesStock->add($entreeStock);
$entreeStock->setFactureFournisseur($this);
}
return $this;
}
public function removeEntreeStock(EntreeStock $entreeStock): static
{
if ($this->entreesStock->removeElement($entreeStock)) {
if ($entreeStock->getFactureFournisseur() === $this) {
$entreeStock->setFactureFournisseur(null);
}
}
return $this;
}
/**
* Calcule le reste à payer
*/
public function getResteAPayer(): float
{
return $this->montantTTC - $this->montantPaye;
}
/**
* Met à jour le montant payé en calculant depuis les paiements
*/
public function updateMontantPaye(): void
{
$total = 0;
foreach ($this->paiements as $paiement) {
$total += $paiement->getMontant();
}
$this->montantPaye = $total;
// Mettre à jour le statut
$this->updateStatut();
}
/**
* Met à jour le statut de la facture
*/
public function updateStatut(): void
{
if ($this->montantPaye >= $this->montantTTC) {
$this->statut = 'PAYEE';
} elseif ($this->montantPaye > 0) {
$this->statut = 'PARTIELLEMENT_PAYEE';
} else {
$this->statut = 'EN_ATTENTE';
}
}
/**
* Vérifie si la facture est totalement payée
*/
public function isPayee(): bool
{
return $this->statut === 'PAYEE';
}
/**
* Calcule le pourcentage de paiement
*/
public function getPourcentagePaiement(): float
{
if ($this->montantTTC <= 0) {
return 0;
}
return min(100, ($this->montantPaye / $this->montantTTC) * 100);
}
public function __toString(): string
{
return $this->numeroFacture ?? '';
}
}