<?php
namespace App\Entity;
use App\Repository\SaleOrderRepository;
use App\Traits\DateTrait;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\Groups;
use JMS\Serializer\Annotation\SerializedName;
use ReflectionClass;
/**
* @ORM\Entity(repositoryClass=SaleOrderRepository::class)
* @ORM\Table(indexes={
* @ORM\Index(columns={"status"})
* })
*
* @Serializer\ExclusionPolicy("ALL")
*/
class SaleOrder
{
use DateTrait;
/**
* Identifiant interne auto incrémenté
*
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @Expose
* @Groups({
* "sale_order:id",
* "sale_order:list",
* "sale_order:updated",
* "sale_order:item",
* "sale_order",
* "get:read",
* "post:read",
* "export_order_datatable"
* })
*/
private ?int $id = NULL;
/**
* Total de la commande HT
*
* @ORM\Column(type="decimal", precision=8, scale=2)
*
* @Expose
* @Groups({
* "sale_order:list",
* "sale_order:updated",
* "sale_order:item",
* "sale_order",
* "get:read",
* "export_order_datatable"
* })
*/
private float $total = 0.00;
/**
* Méthode d'expédition
*
* @ORM\Column(type="string", length=64, nullable=true)
*
* @Expose
* @Groups({
* "sale_order:item",
* "sale_order:updated",
* "sale_order",
* "get:read"
* })
*/
private ?string $shippingMethod = NULL;
/**
* Statut de la commande
* @ORM\Column(type="string", length=32, options={"default":"pending_processing"})
*
* @Expose
* @Groups({
* "sale_order:status",
* "sale_order:list",
* "sale_order:updated",
* "sale_order:item",
* "sale_order",
* "get:read",
* "post:read",
* "export_order_datatable"
* })
*/
private string $status = 'pending_processing';
/**
* @ORM\OneToOne(targetEntity=BankReturn::class, cascade={"persist", "remove"})
*/
private ?BankReturn $bankReturn = NULL;
/**
* Utilisateur
*
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="orders")
*
* @Expose
* @Groups({
* "sale_order:user",
* "sale_order:item",
* "sale_order:post",
* "sale_order",
* "get:read",
* "post:read",
* "export_order_datatable"
* })
*/
private ?User $user = NULL;
/**
* Motif d'annulation
* @ORM\Column(type="text", nullable=true)
*
* @Expose
* @Groups({
* "sale_order:item",
* "sale_order:updated",
* "sale_order"
* })
*/
private ?string $cancelMotif = NULL;
/**
* Prix de la livraison
*
* @ORM\Column(type="decimal", precision=8, scale=2)
*
* @Expose
* @Groups({
* "sale_order:item",
* "sale_order:updated",
* "sale_order",
* "get:read"
* })
*/
private $shippingPrice;
/**
* Référence interne
*
* @ORM\Column(type="string", length=64, nullable=true)
*
* @Expose
* @Groups({
* "sale_order:item",
* "sale_order"
* })
*/
private ?string $internalReference = NULL;
/**
* Commentaire
*
* @ORM\Column(type="text", nullable=true)
*
* @Expose
* @Groups({
* "sale_order:item",
* "sale_order",
* "get:read"
* })
*/
private ?string $comment = NULL;
/**
* @ORM\Column(type="boolean", options={"default":false})
*
* @Expose
* @Groups({
* "sale_order",
* "get:read"
* })
*/
private bool $isManagedByCustomer = FALSE;
/**
* @ORM\Column(type="decimal", precision=8, scale=2, nullable=true)
*
* @Expose
* @Groups({
* "sale_order",
* "sale_order:updated"
* })
*/
private $feesOrder;
/**
* @ORM\Column(type="decimal", precision=8, scale=2, nullable=true)
*
* @Expose
* @Groups({"sale_order"})
*/
private $extraCbPayment;
/**
* @deprecated NON UTILISÉ
*
* @ORM\Column(type="decimal", precision=8, scale=2, nullable=true)
*
* @Expose
* @Groups({"sale_order"})
*/
private $totalBonusUsed;
/**
* @deprecated
* @ORM\ManyToOne(targetEntity=SaleOrder::class, inversedBy="saleOrders")
*/
private ?SaleOrder $saleorderGrouped = NULL;
/**
* @deprecated
* @ORM\OneToMany(targetEntity=SaleOrder::class, mappedBy="saleorderGrouped")
*/
private Collection $saleOrders;
/**
* @ORM\Column(type="boolean", nullable=true)
*
* @Expose
* @Groups({"sale_order"})
*/
private ?bool $notBillable = NULL;
/**
* @ORM\Column(type="array", nullable=true)
*
* @Expose
* @Groups({"sale_order","get:read"})
*/
private ?array $otherinformations = [];
/**
* Adresse de livraison
*
* @ORM\OneToOne(targetEntity=SaleOrderAddress::class, orphanRemoval=true, cascade={"persist", "remove"})
* @ORM\JoinColumn(onDelete="SET NULL")
*
* @Expose
* @Groups({"sale_order:item", "sale_order:post", "get:read"})
*/
private ?SaleOrderAddress $shippingAddress = NULL;
/**
* Adresse de facturation
*
* @ORM\OneToOne(targetEntity=SaleOrderAddress::class, orphanRemoval=true, cascade={"persist", "remove"})
* @ORM\JoinColumn(onDelete="SET NULL")
*
* @Expose
* @Groups({"sale_order:item", "sale_order:post", "get:read"})
*/
private ?SaleOrderAddress $billingAddress = NULL;
/**
* Liste des produits commandés
* @ORM\OneToMany(targetEntity=SaleOrderItem::class, mappedBy="saleOrder", cascade={"persist", "remove"})
*
* @Expose
* @Groups({"sale_order:item", "sale_order:post", "get:read", "export_order_datatable"})
*/
private Collection $items;
/**
* @ORM\OneToMany(targetEntity=SaleOrderShipment::class, mappedBy="saleOrder", cascade={"remove"})
*
* @Expose
* @Groups({
* "sale_order",
* "sale_order:updated",
* "get:read",
* "export_order_datatable"
* })
*/
private Collection $shipments;
/**
* @ORM\OneToOne(targetEntity=Cart::class, inversedBy="saleOrder", cascade={"persist", "remove"})
*/
private ?Cart $cart = NULL;
/**
* @ORM\OneToMany(targetEntity=PointTransaction::class, mappedBy="saleOrder", cascade={"remove"})
*/
private Collection $pointTransactions;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private ?int $oldId = NULL;
/**
* @ORM\OneToOne(targetEntity=SaleOrderInvoice::class, inversedBy="saleOrder", cascade={"persist", "remove"})
*/
private ?SaleOrderInvoice $invoice = NULL;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $categoryValues;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $customQuestion;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $orderRate;
/**
* @ORM\Column(type="boolean", options={"default":false})
*/
private bool $isTrip = FALSE;
// virtual property
private ?string $agency = null;
public function __construct()
{
$this->saleOrders = new ArrayCollection();
$this->items = new ArrayCollection();
$this->shipments = new ArrayCollection();
$this->pointTransactions = new ArrayCollection();
}
public static function getStatuses()
{
$statuses = [];
$reflect = new ReflectionClass( SaleOrder::class );
foreach ( $reflect->getConstants() as $k => $const ) {
if ( preg_match( "/^(STATUS)/", $k ) ) {
$statuses[ $const ] = 'capsule.order.status.' . $const;
}
}
return $statuses;
}
/**
* Retourne la société de l'admin adhérent (spécial algorel)
*
* @Serializer\VirtualProperty()
* @SerializedName("agency")
* @Expose()
* @Groups({"get:read"})
*
*/
public function getAgency(): ?string
{
return $this->agency;
}
public function setAgency( ?string $agency ): self
{
$this->agency = $agency;
return $this;
}
/**
* Retourne le cumul des produits + frais de port + frais de commande
*
* @Serializer\VirtualProperty()
* @SerializedName("totalAmount")
* @Expose()
* @Groups({"sale_order","sale_order:item", "sale_order:post", "get:read", "export_order_datatable"})
*
* @return float
*/
public function getTotalAmount(): float
{
return $this->total + $this->shippingPrice + ( $this->feesOrder ?? 0 );
}
/**
* Retourne le cumul en point des produits + frais de port + frais de commande
*
* @Serializer\VirtualProperty()
* @SerializedName("totalRateAmount")
* @Expose()
* @Groups({"sale_order","sale_order:item", "sale_order:post", "get:read", "export_order_datatable"})
*
* @return int
*/
public function getRateTotalAmount(): int
{
return ceil(
( $this->total * $this->getOrderRate() ) + ( $this->shippingPrice * $this->getOrderRate() ) + ( ( $this->feesOrder ?? 0 ) * $this->getOrderRate() )
);
}
/**
* @Serializer\VirtualProperty()
* @Serializer\SerializedName("array_category_values")
*
* @Expose()
* @Groups({ "sale_order:array_category_values", "export_order_datatable" })
*/
public function getArrayCategoryValues()
{
return json_decode( $this->categoryValues, TRUE ) ?? [];
}
/*
* ============================================================================================
* =============================== FONCTIONS CUSTOM ===========================================
* ============================================================================================
*/
/**
* @return string[]
*/
public static function getOrderedStatus(): array
{
return [
\App\Constants\SaleOrder::STATUS_SHIPPED,
\App\Constants\SaleOrder::STATUS_PROCESSING,
\App\Constants\SaleOrder::STATUS_TO_SHIP,
\App\Constants\SaleOrder::STATUS_PARTIALLY_SHIPPED,
];
}
public function __toString()
{
return $this->getSku();
}
public function getSku()
{
return 'SP' . str_pad( $this->getId(), 10, '0', STR_PAD_LEFT );
}
public function getId(): ?int
{
return $this->id;
}
public function getAddressType( SaleOrderAddress $Address )
{
if ( $this->billingAddress === $Address ) {
return SaleOrderAddress::BILLING_ADDRESS;
} elseif ( $this->shippingAddress === $Address ) {
return SaleOrderAddress::SHIPPING_ADDRESS;
}
return FALSE;
}
public function getItemByReferenceWithStatus( $reference, $statuses )
{
foreach ( $this->getItems() as $item ) {
if ( $item->getReference() == $reference && in_array( $item->getStatus(), $statuses ) ) {
return $item;
}
}
return NULL;
}
/**
* @return Collection|SaleOrderItem[]
*/
public function getItems(): Collection
{
return $this->items;
}
/**
* @param Collection $items
*
* @return $this
*/
public function setItems( Collection $items ): SaleOrder
{
$this->items = $items;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus( string $status ): self
{
$this->status = $status;
return $this;
}
public function getItemsByReferenceWithStatus( $reference, $statuses = [] )
{
$items = [];
foreach ( $this->getItems() as $item ) {
if ( $item->getReference() == $reference ) {
if ( empty( $statuses ) || in_array( $item->getStatus(), $statuses ) ) {
$items[] = $item;
}
}
}
return $items;
}
/**
* Count items matching reference & status
*
* @param string $reference
* @param array $statuses
* @param bool $in
*
* @return int
*/
public function countItemsByReferenceWithStatus( string $reference, array $statuses, $in = TRUE ): int
{
$totalRef = $cnt = 0;
foreach ( $this->getItems() as $item ) {
if ( $item->getReference() == $reference ) {
$totalRef++;
if ( in_array( $item->getStatus(), $statuses ) ) {
$cnt++;
}
}
}
return ( $in ) ? $cnt : ( $totalRef - $cnt );
}
/*
* ============================================================================================
* ============================== FIN FONCTIONS CUSTOM ========================================
* ============================================================================================
*/
/**
* Count items matching status
*
* @param $statuses
* @param bool $in
*
* @return int
*/
public function countItemsWithStatus( $statuses, bool $in = TRUE ): int
{
$cnt = 0;
foreach ( $this->getItems() as $item ) {
if ( in_array( $item->getStatus(), $statuses ) ) {
$cnt++;
}
}
return ( $in ) ? $cnt : ( count( $this->getItems() ) - $cnt );
}
/**
* Get an item from order matching reference
*
* @param $reference
*
* @return SaleOrderItem|null
*/
public function getItemByReference( $reference )
{
foreach ( $this->getItems() as $item ) {
if ( $item->getReference() == $reference ) {
return $item;
}
}
return NULL;
}
public function hasAllItemsStatesCanceled()
{
return $this->hasAllItemsState( SaleOrderItem::STATUS_CANCELED );
}
private function hasAllItemsState( $state )
{
foreach ( $this->getItems() as $item ) {
if ( $item->getStatus() != $state ) {
return FALSE;
}
}
return TRUE;
}
public function getTotal(): ?string
{
return $this->total;
}
public function setTotal( string $total ): self
{
$this->total = $total;
return $this;
}
public function getShippingMethod(): ?string
{
return $this->shippingMethod;
}
public function setShippingMethod( ?string $shippingMethod ): self
{
$this->shippingMethod = $shippingMethod;
return $this;
}
public function getCancelMotif(): ?string
{
return $this->cancelMotif;
}
public function setCancelMotif( ?string $cancelMotif ): self
{
$this->cancelMotif = $cancelMotif;
return $this;
}
public function getShippingPrice(): ?string
{
return $this->shippingPrice;
}
public function setShippingPrice( string $shippingPrice ): self
{
$this->shippingPrice = $shippingPrice;
return $this;
}
public function getInternalReference(): ?string
{
return $this->internalReference;
}
public function setInternalReference( ?string $internalReference ): self
{
$this->internalReference = $internalReference;
return $this;
}
public function getComment(): ?string
{
return $this->comment;
}
public function setComment( ?string $comment ): self
{
$this->comment = $comment;
return $this;
}
public function getIsManagedByCustomer(): ?bool
{
return $this->isManagedByCustomer;
}
public function setIsManagedByCustomer( bool $isManagedByCustomer ): self
{
$this->isManagedByCustomer = $isManagedByCustomer;
return $this;
}
public function getFeesOrder(): ?string
{
return $this->feesOrder;
}
public function setFeesOrder( ?string $feesOrder ): self
{
$this->feesOrder = $feesOrder;
return $this;
}
public function getExtraCbPayment(): ?string
{
return $this->extraCbPayment;
}
public function setExtraCbPayment( ?string $extraCbPayment ): self
{
$this->extraCbPayment = $extraCbPayment;
return $this;
}
/**
* @return string|null
* @deprecated NON UTILSÉ
*/
public function getTotalBonusUsed(): ?string
{
return $this->totalBonusUsed;
}
/**
* @param string|null $totalBonusUsed
*
* @return $this
* @deprecated NON UTILSÉ
*/
public function setTotalBonusUsed( ?string $totalBonusUsed ): self
{
$this->totalBonusUsed = $totalBonusUsed;
return $this;
}
public function getNotBillable(): ?bool
{
return $this->notBillable;
}
public function setNotBillable( ?bool $notBillable ): self
{
$this->notBillable = $notBillable;
return $this;
}
public function getOtherinformations(): ?array
{
return $this->otherinformations;
}
public function setOtherinformations( ?array $otherinformations ): self
{
$this->otherinformations = $otherinformations;
return $this;
}
public function getBankReturn(): ?BankReturn
{
return $this->bankReturn;
}
public function setBankReturn( ?BankReturn $bankReturn ): self
{
$this->bankReturn = $bankReturn;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser( ?User $user ): self
{
$this->user = $user;
return $this;
}
/**
* @return Collection|SaleOrder[]
*/
public function getSaleOrders(): Collection
{
return $this->saleOrders;
}
/**
* @param SaleOrder $saleOrder
*
* @return $this
* @deprecated
*/
public function addSaleOrder( SaleOrder $saleOrder ): self
{
if ( !$this->saleOrders->contains( $saleOrder ) ) {
$this->saleOrders[] = $saleOrder;
$saleOrder->setSaleorderGrouped( $this );
}
return $this;
}
/**
* @param SaleOrder $saleOrder
*
* @return $this
* @deprecated
*/
public function removeSaleOrder( SaleOrder $saleOrder ): self
{
if ( $this->saleOrders->removeElement( $saleOrder ) ) {
// set the owning side to null (unless already changed)
if ( $saleOrder->getSaleorderGrouped() === $this ) {
$saleOrder->setSaleorderGrouped( NULL );
}
}
return $this;
}
/**
* @deprecated
*/
public function getSaleorderGrouped(): ?SaleOrder
{
return $this->saleorderGrouped;
}
/**
* @deprecated
*/
public function setSaleorderGrouped( ?self $saleorderGrouped ): SaleOrder
{
$this->saleorderGrouped = $saleorderGrouped;
return $this;
}
public function getShippingAddress(): ?SaleOrderAddress
{
return $this->shippingAddress;
}
public function setShippingAddress( ?SaleOrderAddress $shippingAddress ): self
{
$this->shippingAddress = $shippingAddress;
return $this;
}
public function getBillingAddress(): ?SaleOrderAddress
{
return $this->billingAddress;
}
public function setBillingAddress( ?SaleOrderAddress $billingAddress ): self
{
$this->billingAddress = $billingAddress;
return $this;
}
public function addItem( SaleOrderItem $item ): self
{
if ( !$this->items->contains( $item ) ) {
$this->items[] = $item;
$item->setSaleOrder( $this );
}
return $this;
}
public function removeItem( SaleOrderItem $item ): self
{
if ( $this->items->removeElement( $item ) ) {
// set the owning side to null (unless already changed)
if ( $item->getSaleOrder() === $this ) {
$item->setSaleOrder( NULL );
}
}
return $this;
}
/**
* @return Collection|SaleOrderShipment[]
*/
public function getShipments(): Collection
{
return $this->shipments;
}
public function addShipment( SaleOrderShipment $shipment ): self
{
if ( !$this->shipments->contains( $shipment ) ) {
$this->shipments[] = $shipment;
$shipment->setSaleOrder( $this );
}
return $this;
}
public function removeShipment( SaleOrderShipment $shipment ): self
{
if ( $this->shipments->removeElement( $shipment ) ) {
// set the owning side to null (unless already changed)
if ( $shipment->getSaleOrder() === $this ) {
$shipment->setSaleOrder( NULL );
}
}
return $this;
}
public function getCart(): ?Cart
{
return $this->cart;
}
public function setCart( ?Cart $cart ): self
{
$this->cart = $cart;
return $this;
}
/**
* @Serializer\VirtualProperty()
*
* @Expose
* @Groups ({"get:read"})
* @SerializedName ("shipping_method")
*/
public function getApiShippingMethod()
{
return $this->shippingMethod;
}
/**
* @return Collection|PointTransaction[]
*/
public function getPointTransactions(): Collection
{
return $this->pointTransactions;
}
public function addPointTransaction( PointTransaction $pointTransaction ): self
{
if ( !$this->pointTransactions->contains( $pointTransaction ) ) {
$this->pointTransactions[] = $pointTransaction;
$pointTransaction->setSaleOrder( $this );
}
return $this;
}
public function removePointTransaction( PointTransaction $pointTransaction ): self
{
if ( $this->pointTransactions->removeElement( $pointTransaction ) ) {
// set the owning side to null (unless already changed)
if ( $pointTransaction->getSaleOrder() === $this ) {
$pointTransaction->setSaleOrder( NULL );
}
}
return $this;
}
public function getOldId(): ?int
{
return $this->oldId;
}
public function setOldId( ?int $oldId ): self
{
$this->oldId = $oldId;
return $this;
}
public function getInvoice(): ?SaleOrderInvoice
{
return $this->invoice;
}
public function setInvoice( ?SaleOrderInvoice $invoice ): self
{
$this->invoice = $invoice;
return $this;
}
public function getCategoryValues(): ?string
{
return $this->categoryValues;
}
public function setCategoryValues( ?string $categoryValues ): self
{
$this->categoryValues = $categoryValues;
return $this;
}
public function getCustomQuestion(): ?string
{
return $this->customQuestion;
}
public function setCustomQuestion( ?string $customQuestion ): self
{
$this->customQuestion = $customQuestion;
return $this;
}
public function getOrderRate(): float
{
return $this->orderRate ?? 1;
}
public function setOrderRate( float $orderRate ): self
{
$this->orderRate = $orderRate;
return $this;
}
public function isIsTrip(): ?bool
{
return $this->isTrip;
}
public function setIsTrip( bool $isTrip ): self
{
$this->isTrip = $isTrip;
return $this;
}
}