<?php
namespace App\Entity;
use App\Repository\DocumentRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\CancelReason ;
use App\Entity\ReturnReason ;
use App\Entity\RefundReason ;
use JsonSerializable;
/**
* @ORM\Entity(repositoryClass=DocumentRepository::class)
*/
class Document implements JsonSerializable
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $type;
/**
* @ORM\Column(type="string", length=255)
*/
private $status;
/**
* @ORM\Column(type="string", length=255)
*/
private $conditionDocument;
/**
* @ORM\Column(type="string", length=255)
*/
private $internalNbr;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $externalNbr;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $object;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $note;
/**
* @ORM\Column(type="decimal", precision=12, scale=3, options={"default":"0.000", "comment": "Total HT brut (avant remise document)"})
*/
private $totalAmountHt;
/**
* @ORM\Column(type="decimal", precision=12, scale=3, options={"default":"0.000"})
*/
private $totalTva;
/**
* @ORM\Column(name="total_amount_ttc", type="decimal", precision=12, scale=3, options={"default":"0.000","comment":"Total TTC net (après remise document)"})
*/
private $totalAmountTtc;
/**
* @ORM\Column(type="string", length=255)
*/
private $paymentMethod;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $paymentDeadline;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $paymentRef;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $discount;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $discountType;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $advancePayment;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $advancePaymentType;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $parcelTrackingNbr;
/**
* @ORM\OneToMany(targetEntity=DocumentProduit::class, mappedBy="document" ,cascade={"persist"})
*/
private $documentProduits;
/**
* @ORM\OneToMany(targetEntity=DocumentDeclinationProduit::class, mappedBy="document" ,cascade={"persist"})
*/
private $documentDeclinationProduits;
/**
* @ORM\Column(type="string", length=255)
*/
private $category;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="documents")
*/
private $client;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="userDocuments")
*/
private $user;
/**
* @ORM\ManyToOne(targetEntity=Document::class, inversedBy="documents")
*/
private $document;
/**
* @ORM\OneToMany(targetEntity=Document::class, mappedBy="document")
*/
private $documents;
/**
* @ORM\ManyToOne(targetEntity=Delivery::class, inversedBy="documents")
*/
private $delivery;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $urlPdf;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $deliveryDiscount;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $deliveryDiscountType;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $deliveryPrice;
/**
* @ORM\ManyToOne(targetEntity=Tva::class)
*/
private $deliveryTva;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $deliveryTotal;
// Document.php (à l'intérieur de la classe Document)
/**
* @ORM\Column(name="delivery_company_total", type="decimal", precision=12, scale=2, nullable=true)
*/
private $deliveryCompanyTotal;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $adress;
/**
* @ORM\OneToMany(targetEntity=Comment::class, mappedBy="document")
* @ORM\OrderBy({"createAt" = "DESC"})
*/
private $comments;
/**
* @ORM\ManyToOne(targetEntity=Supplier::class, inversedBy="documents")
*/
private $supplier;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $urlTracking;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private $packagesNbr;
/**
* @ORM\OneToMany(targetEntity=Comment::class, mappedBy="documentComment")
*/
private $documentComments;
/**
* @ORM\Column(name="promised_at", type="datetime", nullable=true, options={"comment":"Date promise client/fournisseur"})
*/
private ?\DateTimeInterface $promisedAt = null;
/**
* @ORM\Column(name="shipped_at", type="datetime", nullable=true)
*/
private ?\DateTimeInterface $shippedAt = null;
/**
* @ORM\Column(name="delivered_at", type="datetime", nullable=true)
*/
private ?\DateTimeInterface $deliveredAt = null;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $returnedAt;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $bonrecuAt;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $aPayerLe;
/**
* @ORM\ManyToOne(targetEntity=Source::class, inversedBy="documents")
*/
private $source;
/**
* @ORM\Column(type="boolean")
*/
private $isFreeDelivery;
/**
* @ORM\ManyToOne(targetEntity=User::class)
*/
private $updatedBy;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* @ORM\OneToMany(targetEntity=Activity::class, mappedBy="document")
*/
private $activities;
/**
* @ORM\ManyToOne(targetEntity=Promotion::class)
*/
private $promotion;
/**
* @ORM\Column(name="payment_status", type="string", length=32, options={"default":"non-paye"})
*/
private $paymentStatus = 'non-paye';
/**
* @ORM\Column(name="paid_at", type="datetime", nullable=true)
*/
private $paidAt;
/**
* @ORM\Column(type="decimal", precision=12, scale=3, options={"default": "0.000", "comment": "Total des encaissements TTC"})
*/
private $totalPaid;
/**
* @ORM\Column(name="refund_amount", type="decimal", precision=12, scale=3, nullable=true)
*/
private $refundAmount;
/**
* @ORM\Column(name="refunded_at", type="datetime", nullable=true)
*/
private $refundedAt;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\CancelReason")
* @ORM\JoinColumn(name="cancel_reason_id", referencedColumnName="id", onDelete="SET NULL")
*/
private $cancelReason;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\RefundReason")
* @ORM\JoinColumn(name="refund_reason_id", referencedColumnName="id", onDelete="SET NULL")
*/
private $refundReason;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\ReturnReason")
* @ORM\JoinColumn(name="return_reason_id", referencedColumnName="id", onDelete="SET NULL", nullable=true)
*/
private $returnReason;
public function __construct()
{
$this->documentProduits = new ArrayCollection();
$this->documentDeclinationProduits = new ArrayCollection();
$this->documents = new ArrayCollection();
$this->comments = new ArrayCollection();
$this->documentComments = new ArrayCollection();
$this->activities = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(string $type): self
{
$this->type = $type;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getConditionDocument(): ?string
{
return $this->conditionDocument;
}
public function setConditionDocument(string $conditionDocument): self
{
$this->conditionDocument = $conditionDocument;
return $this;
}
public function getInternalNbr(): ?string
{
return $this->internalNbr;
}
public function setInternalNbr(string $internalNbr): self
{
$this->internalNbr = $internalNbr;
return $this;
}
public function getExternalNbr(): ?string
{
return $this->externalNbr;
}
public function setExternalNbr(string $externalNbr): self
{
$this->externalNbr = $externalNbr;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getObject(): ?string
{
return $this->object;
}
public function setObject(?string $object): self
{
$this->object = $object;
return $this;
}
public function getNote(): ?string
{
return $this->note;
}
public function setNote(?string $note): self
{
$this->note = $note;
return $this;
}
public function getTotalAmountHt(): ?float
{
return $this->totalAmountHt;
}
public function setTotalAmountHt(float $totalAmountHt): self
{
$this->totalAmountHt = $totalAmountHt;
return $this;
}
public function getTotalTva(): ?float
{
return $this->totalTva;
}
public function setTotalTva(float $totalTva): self
{
$this->totalTva = $totalTva;
return $this;
}
public function getTotalAmountTtc(): ?float
{
return $this->totalAmountTtc;
}
public function setTotalAmountTtc(float $totalAmountTtc): self
{
$this->totalAmountTtc = $totalAmountTtc;
return $this;
}
public function getPaymentMethod(): ?string
{
return $this->paymentMethod;
}
public function setPaymentMethod(string $paymentMethod): self
{
$this->paymentMethod = $paymentMethod;
return $this;
}
public function getPaymentDeadline(): ?string
{
return $this->paymentDeadline;
}
public function setPaymentDeadline(?string $paymentDeadline): self
{
$this->paymentDeadline = $paymentDeadline;
return $this;
}
public function getPaymentRef(): ?string
{
return $this->paymentRef;
}
public function setPaymentRef(?string $paymentRef): self
{
$this->paymentRef = $paymentRef;
return $this;
}
public function getDiscount(): ?float
{
return $this->discount;
}
public function setDiscount(?float $discount): self
{
$this->discount = $discount;
return $this;
}
public function getDiscountType(): ?string
{
return $this->discountType;
}
public function setDiscountType(?string $discountType): self
{
$this->discountType = $discountType;
return $this;
}
public function getAdvancePayment(): ?float
{
return $this->advancePayment;
}
public function setAdvancePayment(?float $advancePayment): self
{
$this->advancePayment = $advancePayment;
return $this;
}
public function getAdvancePaymentType(): ?string
{
return $this->advancePaymentType;
}
public function setAdvancePaymentType(?string $advancePaymentType): self
{
$this->advancePaymentType = $advancePaymentType;
return $this;
}
public function getParcelTrackingNbr(): ?string
{
return $this->parcelTrackingNbr;
}
public function setParcelTrackingNbr(?string $parcelTrackingNbr): self
{
$this->parcelTrackingNbr = $parcelTrackingNbr;
return $this;
}
/**
* @return Collection|DocumentProduit[]
*/
public function getDocumentProduits(): Collection
{
return $this->documentProduits;
}
public function addDocumentProduit(DocumentProduit $documentProduit): self
{
if( !$this->documentProduits->contains($documentProduit)) {
$this->documentProduits[] = $documentProduit;
$documentProduit->setDocument($this);
}
return $this;
}
public function removeDocumentProduit(DocumentProduit $documentProduit): self
{
if( $this->documentProduits->removeElement($documentProduit)) {
// set the owning side to null (unless already changed)
if( $documentProduit->getDocument() === $this) {
$documentProduit->setDocument(null);
}
}
return $this;
}
/**
* @return Collection|DocumentDeclinationProduit[]
*/
public function getDocumentDeclinationProduits(): Collection
{
return $this->documentDeclinationProduits;
}
public function addDocumentDeclinationProduit(DocumentDeclinationProduit $documentDeclinationProduit): self
{
if( !$this->documentDeclinationProduits->contains($documentDeclinationProduit)) {
$this->documentDeclinationProduits[] = $documentDeclinationProduit;
$documentDeclinationProduit->setDocument($this);
}
return $this;
}
public function removeDocumentDeclinationProduit(DocumentDeclinationProduit $documentDeclinationProduit): self
{
if( $this->documentDeclinationProduits->removeElement($documentDeclinationProduit)) {
// set the owning side to null (unless already changed)
if( $documentDeclinationProduit->getDocument() === $this) {
$documentDeclinationProduit->setDocument(null);
}
}
return $this;
}
public function getCategory(): ?string
{
return $this->category;
}
public function setCategory(string $category): self
{
$this->category = $category;
return $this;
}
public function getClient(): ?User
{
return $this->client;
}
public function setClient(?User $client): self
{
$this->client = $client;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getDocument(): ?self
{
return $this->document;
}
public function setDocument(?self $document): self
{
$this->document = $document;
return $this;
}
/**
* @return Collection|self[]
*/
public function getDocuments(): Collection
{
return $this->documents;
}
public function addDocument(self $document): self
{
if( !$this->documents->contains($document)) {
$this->documents[] = $document;
$document->setDocument($this);
}
return $this;
}
public function removeDocument(self $document): self
{
if( $this->documents->removeElement($document)) {
// set the owning side to null (unless already changed)
if( $document->getDocument() === $this) {
$document->setDocument(null);
}
}
return $this;
}
public function getDelivery(): ?Delivery
{
return $this->delivery;
}
public function setDelivery(?Delivery $delivery): self
{
$this->delivery = $delivery;
return $this;
}
public function getUrlPdf(): ?string
{
return $this->urlPdf;
}
public function setUrlPdf(?string $urlPdf): self
{
$this->urlPdf = $urlPdf;
return $this;
}
public function getDeliveryDiscount(): ?float
{
return $this->deliveryDiscount;
}
public function setDeliveryDiscount(?float $deliveryDiscount): self
{
$this->deliveryDiscount = $deliveryDiscount;
return $this;
}
public function getDeliveryDiscountType(): ?string
{
return $this->deliveryDiscountType;
}
public function setDeliveryDiscountType(?string $deliveryDiscountType): self
{
$this->deliveryDiscountType = $deliveryDiscountType;
return $this;
}
public function getDeliveryPrice(): ?float
{
return $this->deliveryPrice;
}
public function setDeliveryPrice(?float $deliveryPrice): self
{
$this->deliveryPrice = $deliveryPrice;
return $this;
}
public function getDeliveryTva(): ?Tva
{
return $this->deliveryTva;
}
public function setDeliveryTva(?Tva $deliveryTva): self
{
$this->deliveryTva = $deliveryTva;
return $this;
}
public function getDeliveryTotal(): ?float
{
return $this->deliveryTotal;
}
public function setDeliveryTotal(?float $deliveryTotal): self
{
$this->deliveryTotal = $deliveryTotal;
return $this;
}
public function getDeliveryCompanyTotal(): ?string
{
return $this->deliveryCompanyTotal;
}
public function setDeliveryCompanyTotal(?string $deliveryCompanyTotal): self
{
$this->deliveryCompanyTotal = $deliveryCompanyTotal;
return $this;
}
public function getAdress(): ?string
{
return $this->adress;
}
public function setAdress(?string $adress): self
{
$this->adress = $adress;
return $this;
}
/**
* @return Collection|Comment[]
*/
public function getComments(): Collection
{
return $this->comments;
}
public function addComment(Comment $comment): self
{
if( !$this->comments->contains($comment)) {
$this->comments[] = $comment;
$comment->setDocument($this);
}
return $this;
}
public function removeComment(Comment $comment): self
{
if( $this->comments->removeElement($comment)) {
// set the owning side to null (unless already changed)
if( $comment->getDocument() === $this) {
$comment->setDocument(null);
}
}
return $this;
}
public function getSupplier(): ?Supplier
{
return $this->supplier;
}
public function setSupplier(?Supplier $supplier): self
{
$this->supplier = $supplier;
return $this;
}
public function getUrlTracking(): ?string
{
return $this->urlTracking;
}
public function setUrlTracking(?string $urlTracking): self
{
$this->urlTracking = $urlTracking;
return $this;
}
public function getPackagesNbr(): ?int
{
return $this->packagesNbr;
}
public function setPackagesNbr(?int $packagesNbr): self
{
$this->packagesNbr = $packagesNbr;
return $this;
}
/**
* @return Collection|Comment[]
*/
public function getDocumentComments(): Collection
{
return $this->documentComments;
}
public function addDocumentComment(Comment $documentComment): self
{
if( !$this->documentComments->contains($documentComment)) {
$this->documentComments[] = $documentComment;
$documentComment->setDocumentComment($this);
}
return $this;
}
public function removeDocumentComment(Comment $documentComment): self
{
if( $this->documentComments->removeElement($documentComment)) {
// set the owning side to null (unless already changed)
if( $documentComment->getDocumentComment() === $this) {
$documentComment->setDocumentComment(null);
}
}
return $this;
}
public function getPromisedAt(): ?\DateTimeInterface
{
return $this->promisedAt;
}
public function setPromisedAt(?\DateTimeInterface $promisedAt): self
{
$this->promisedAt = $promisedAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(?\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getShippedAt(): ?\DateTimeInterface
{
return $this->shippedAt;
}
public function setShippedAt(?\DateTimeInterface $shippedAt): self
{
$this->shippedAt = $shippedAt;
return $this;
}
public function getDeliveredAt(): ?\DateTimeInterface
{
return $this->deliveredAt;
}
public function setDeliveredAt(?\DateTimeInterface $dt): self
{
$this->deliveredAt = $dt; return $this;
}
public function getReturnedAt(): ?\DateTimeInterface
{
return $this->returnedAt;
}
public function setReturnedAt(?\DateTimeInterface $returnedAt): self
{
$this->returnedAt = $returnedAt;
return $this;
}
public function getBonrecuAt(): ?\DateTimeInterface
{
return $this->bonrecuAt;
}
public function setBonrecuAt(?\DateTimeInterface $bonrecuAt): self
{
$this->bonrecuAt = $bonrecuAt;
return $this;
}
public function getAPayerLe(): ?\DateTimeInterface
{
return $this->aPayerLe;
}
public function setAPayerLe(?\DateTimeInterface $aPayerLe): self
{
$this->aPayerLe = $aPayerLe;
return $this;
}
public function getSource(): ?Source
{
return $this->source;
}
public function setSource(?Source $source): self
{
$this->source = $source;
return $this;
}
public function getIsFreeDelivery(): ?bool
{
return $this->isFreeDelivery;
}
public function setIsFreeDelivery(bool $isFreeDelivery): self
{
$this->isFreeDelivery = $isFreeDelivery;
return $this;
}
/**
* @return Collection|Activity[]
*/
public function getActivities(): Collection
{
return $this->activities;
}
public function addActivity(Activity $activity): self
{
if( !$this->activities->contains($activity)) {
$this->activities[] = $activity;
$activity->setDocument($this);
}
return $this;
}
public function removeActivity(Activity $activity): self
{
if( $this->activities->removeElement($activity)) {
// set the owning side to null (unless already changed)
if( $activity->getDocument() === $this) {
$activity->setDocument(null);
}
}
return $this;
}
public function getUpdatedBy(): ?User
{
return $this->user;
}
public function setUpdatedBy(?User $user): self
{
$this->updatedBy = $user;
return $this;
}
public function getPromotion(): ?Promotion
{
return $this->promotion;
}
public function setPromotion(?Promotion $promotion): self
{
$this->promotion = $promotion;
return $this;
}
public function getCancelReason(): ?CancelReason
{
return $this->cancelReason;
}
public function setCancelReason(?CancelReason $cancelReason): self
{
$this->cancelReason = $cancelReason;
return $this;
}
public function getRefundReason(): ?RefundReason
{
return $this->refundReason;
}
public function setRefundReason(?RefundReason $refundReason): self
{
$this->refundReason = $refundReason;
return $this;
}
public function getReturnReason(): ?ReturnReason
{
return $this->returnReason;
}
public function setReturnReason(?ReturnReason $returnReason): self
{
$this->returnReason = $returnReason;
return $this;
}
public function jsonSerialize()
{
return array(
'id' => $this->getId(),
'totalClient' => $this->getTotalAmountTtc() + $this->getDeliveryPrice(),
'createdAt' => $this->getCreatedAt()->format('d/m/Y h:i'),
'status' => $this->getStatus()
);
}
/* ---------- Getters/Setters paiement ---------- */
public function getPaymentStatus(): ?string
{
return $this->paymentStatus;
}
public function setPaymentStatus(string $paymentStatus): self
{
$this->paymentStatus = $paymentStatus;
return $this;
}
public function getPaidAt(): ?\DateTimeInterface
{
return $this->paidAt;
}
public function setPaidAt(?\DateTimeInterface $paidAt): self
{
$this->paidAt = $paidAt;
return $this;
}
/**
* Attention: Doctrine renvoie DECIMAL en string.
* On garde string pour éviter les surprises d’arrondi.
*/
public function getTotalPaid(): ?string
{
return $this->totalPaid;
}
public function setTotalPaid($totalPaid): self
{
// accepte float|string, on normalise à 3 décimales
$this->totalPaid = number_format((float)$totalPaid, 3, '.', '');
return $this;
}
/** @ORM\PrePersist */
public function ensureTotalPaid(): void
{
if ($this->totalPaid === null || $this->totalPaid === '') {
$this->totalPaid = '0.000';
}
}
public function getRefundAmount(): ?string
{
return $this->refundAmount;
}
public function setRefundAmount($refundAmount): self
{
$this->refundAmount = $refundAmount !== null
? number_format((float)$refundAmount, 3, '.', '')
: null;
return $this;
}
public function getRefundedAt(): ?\DateTimeInterface
{
return $this->refundedAt;
}
public function setRefundedAt(?\DateTimeInterface $refundedAt): self
{
$this->refundedAt = $refundedAt;
return $this;
}
/* ---------- Helper historique ---------- */
/** Ajoute proprement une étape dans condition_document */
public function addConditionStep(string $label): self
{
$current = trim((string)$this->getConditionDocument());
$this->setConditionDocument($current !== '' ? $current.' -> '.$label : $label);
return $this;
}
}