<?php
namespace Shopping\Service\Cart;
use Core\Service\Session\Session;
use Doctrine\Common\Persistence\ManagerRegistry;
use Shopping\Entity\Attribute;
use Shopping\Entity\AttributeGroup;
use Shopping\Service\Tools;
/**
* CartManager - Gestion du panier et des prix appliqués
*/
class CartManager
{
private $cart;
private $cart_session;
private $entityManager;
private $user;
/**
* Constructeur
*/
public function __construct(Session $session, ManagerRegistry $entityManager, $user = null)
{
$this->entityManager = $entityManager;
$this->user = $user;
// Création de la session de panier
$this->cart_session = new CartSession($session);
// Récupère le panier depuis la session
$this->cart = $this->cart_session->getCartFromSession();
}
/**
* Ajoute $quantity de $product au panier
*/
public function add($product, $quantity, $options)
{
$declinaison = $product->getDeclinaison();
$attributes = [];
if ($declinaison != null) {
$attributes = $declinaison->serialize();
}
if ($this->checkProductConformity($product, $quantity)) {
// Ajoute le produit au panier
$this->cart->add($product->getProduct()->getId(), $quantity, $attributes, null, $options);
// Modifie le panier en session
$this->cart_session->persist($this->cart);
return true;
} else {
return false;
}
}
/**
* Mise à jours de $quantity de $product au panier
*/
public function update($product, $quantity, $reference)
{
$declinaison = $product->getDeclinaison();
$attributes = [];
if ($declinaison != null) {
$attributes = $declinaison->serialize();
}
if ($this->checkProductConformity($product, $quantity)) {
// Ajoute le produit au panier
$this->cart->update($product->getProduct()->getId(), $quantity, $attributes, $reference);
// Modifie le panier en session
$this->cart_session->persist($this->cart);
return true;
} else {
return false;
}
}
/**
* Supprime $quantity de $product au panier
*/
public function remove($product, $quantity = null, $product_cart_reference = null)
{
// Supprime le produit du panier
$this->cart->remove($product->getId(), $quantity, $product_cart_reference);
// Modifie le panier en session
$this->cart_session->persist($this->cart);
}
/**
* Supprime le panier
*/
public function clear()
{
// Réinitialise le panier
$this->cart = new Cart();
// Réinitialize le panier en session
$this->cart_session->clear();
}
/*
* Fonctions sur une "ligne" de produits
*/
/**
* Prix HT pour les produits de $row
*/
public function getProductRowTotalHT($row)
{
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
$totalHT = (float)($product->getPriceHT() * $row->getQuantity());
if ($totalHT < 0) {
throw new \Exception('Une erreur est survenue lors du calcule HT des produits', 500);
}
return $totalHT;
}
public function getProductRowTotalHTWhitoutPercentage($row)
{
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
$totalHT = (float)($product->getPriceHT(false) * $row->getQuantity());
if ($totalHT < 0) {
throw new \Exception('Une erreur est survenue lors du calcule HT des produits', 500);
}
return $totalHT;
}
/**
* TVA pour les produits de $row
*/
public function getProductRowTotalTVA($row)
{
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
// $totalHT = (float)($product->getPriceTva() * $row->getQuantity());
$totalHT = (float)($product->getPriceHT() * $row->getQuantity());
$totalHT = Tools::calculateProductTVA($totalHT, $product->getProduct()->getTax()->getRate());
if ($totalHT < 0) {
throw new \Exception('Une erreur est survenue lors du calcule HT des produits', 500);
}
return $totalHT;
}
/**
* Prix TTC pour les produits de $row
*/
public function getProductRowTotalTTC($row)
{
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
$totalHT = (float)($product->getPriceHT() * $row->getQuantity());
$totalTVA = Tools::calculateProductTVA($totalHT, $product->getProduct()->getTax()->getRate());
$totalTTC = Tools::calculateProductTTC($totalHT, $totalTVA);
$totalTTC = Tools::formatPriceRound($totalTTC);
if ($totalTTC < 0) {
throw new \Exception('Une erreur est survenue lors du calcule TTC des produits', 500);
}
return $totalTTC;
}
/**
* Poids pour les produits de $row
*/
public function getProductRowTotalWeight($row)
{
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
$totalWeight = (float)($product->getWeight() * $row->getQuantity());
if ($totalWeight < 0) {
throw new \Exception('Une erreur est survenue lors du calcule du poids des produits', 500);
}
return number_format($totalWeight, 2);
}
/**
* Nombre de produits de $row
*/
public function getProductRowTotalCount($row)
{
$totalCount = $row->getQuantity();
if ($totalCount < 0) {
throw new \Exception('Une erreur est survenue lors du calcule du nombre de produits', 500);
}
return $totalCount;
}
/*
* Fonctions sur un produit spécifique
*/
/**
* Prix HT pour les produits avec son $product_id
*/
public function getProductRowTotalHTByProductId($product_id)
{
foreach ($this->cart->getProducts() as $row) {
if ($row->getProduct() == $product_id) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
// Vérifie la conformité et la disponibilité du produit
if ($this->checkProductConformity($product)) {
return $this->getProductRowTotalHT($row);
}
}
}
return null;
}
/**
* TVA pour les produits avec son $product_id
*/
public function getProductRowTotalTVAByProductId($product_id)
{
foreach ($this->cart->getProducts() as $row) {
if ($row->getProduct() == $product_id) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
// Vérifie la conformité et la disponibilité du produit
if ($this->checkProductConformity($product)) {
return $this->getProductRowTotalTVA($row);
}
}
}
return null;
}
/**
* Prix TTC pour les produits avec son $product_id
*/
public function getProductRowTotalTTCByProductId($product_id)
{
foreach ($this->cart->getProducts() as $row) {
if ($row->getProduct() == $product_id) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
// Vérifie la conformité et la disponibilité du produit
if ($this->checkProductConformity($product)) {
return $this->getProductRowTotalTTC($row);
}
}
}
return null;
}
/**
* Poids pour les produits avec son $product_id
*/
public function getProductRowTotalWeightByProductId($product_id)
{
foreach ($this->cart->getProducts() as $row) {
if ($row->getProduct() == $product_id) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
// Vérifie la conformité et la disponibilité du produit
if ($this->checkProductConformity($product)) {
return $this->getProductRowTotalWeight($row);
}
}
}
return null;
}
/**
* Nombre de produits avec $product_id
*/
public function getProductRowTotalCountByProductId($product_id)
{
foreach ($this->cart->getProducts() as $row) {
if ($row->getProduct() == $product_id) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
// Vérifie la conformité et la disponibilité du produit
if ($this->checkProductConformity($product)) {
return $this->getProductRowTotalCount($row);
}
}
}
return null;
}
/*
* Fonctions sur le panier
*/
/**
* Prix HT de tous les produits du panier
*/
public function getCartTotalHT()
{
$totalHT = 0;
foreach ($this->cart->getProducts() as $row) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
if ($this->checkProductConformity($product)) {
$totalHT += $this->getProductRowTotalHT($row);
}
}
return $totalHT;
}
public function getCartTotalHTWhitoutPercentage()
{
$totalHT = 0;
foreach ($this->cart->getProducts() as $row) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
if ($this->checkProductConformity($product)) {
$totalHT += $this->getProductRowTotalHTWhitoutPercentage($row);
}
}
return $totalHT;
}
/**
* Prix TTC de tous les produits du panier
*/
public function getCartTotalTTC()
{
$totalTTC = 0;
foreach ($this->cart->getProducts() as $row) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
if ($this->checkProductConformity($product)) {
$totalTTC += $this->getProductRowTotalTTC($row);
}
}
return $totalTTC;
}
/**
* Prix TVA de tous les produits du panier
*/
public function getCartTotalTVA()
{
$totalTVA = 0;
foreach ($this->cart->getProducts() as $row) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
if ($this->checkProductConformity($product)) {
$totalTVA += $this->getProductRowTotalTVA($row);
}
}
return $totalTVA;
}
/**
* Poids de tous les produits du panier
*/
public function getCartTotalWeight()
{
$totalWeight = 0;
foreach ($this->cart->getProducts() as $row) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
if ($this->checkProductConformity($product)) {
$totalWeight += $this->getProductRowTotalWeight($row);
}
}
return $totalWeight;
}
/**
* Nombre de produits du panier
*/
public function getCartTotalProductsCount()
{
$totalCount = 0;
foreach ($this->cart->getProducts() as $row) {
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
if ($this->checkProductConformity($product)) {
$totalCount += $this->getProductRowTotalCount($row);
}
}
return $totalCount;
}
/**
* Retourne le panier
*/
public function getCart()
{
$cart = [];
$cart['products'] = [];
// Parcours des CartProduct du panier
foreach ($this->cart->getProducts() as $row) {
// Création du produit
$product = new \Shopping\Service\Product\Product($this->entityManager, $this->user);
$product->createProduct($row->getProduct(), $row->getAttributes());
if ($this->checkProductConformity($product)) {
// Informations sur les produits
$cart['products'][] = [
'product_manager' => $product,
'product_cart_reference' => $row->getReference(),
'product' => $product->getProduct(),
'quantity' => $row->getQuantity(),
'options' => $row->getOptions(),
'productTotalWeight' => $this->getProductRowTotalWeight($row),
'productTotalHT' => $this->getProductRowTotalHT($row),
'productTotalTVA' => $this->getProductRowTotalTVA($row),
'productTotalTTC' => $this->getProductRowTotalTTC($row),
];
}
}
// Informations sur le panier
$cart['cartTotalWeight'] = Tools::formatPrice($this->getCartTotalWeight());
$cart['cartTotalHT'] = Tools::formatPrice($this->getCartTotalHT());
$cart['cartTotalTVA'] = Tools::formatPrice($this->getCartTotalTVA());
$cart['cartTotalTTC'] = Tools::formatPrice($this->getCartTotalTTC());
$cart['cartTotalProductsCount'] = $this->getCartTotalProductsCount();
return $cart;
}
/*
* Fonctions privées
*/
/**
* Vérification de la validité du produit pour le mettre dans le panier
*/
private function checkProductConformity($object, $quantity = null)
{
$productValide = true;
$product = $object->getproduct();
// Produit introuvable
if ($product == null) {
return false;
}
// Produit en ligne
if (!$product->getIsEnabled()) {
$productValide = false;
}
// Disponibilité à la commande
// if ($product->getAvailableForOrder() != 1) {
// $productValide = false;
// }
// Date de la disponibilité
// $date = new \DateTime('NOW');
// $disponibility = $product->getAvailableDate();
// if ($disponibility != null && $disponibility != '' && $date < new \DateTime($disponibility)) {
// $productValide = false;
// }
// Lieu de Disponibilité du produit
// if ($product->getOnlineOnly() != 0 and $product->getOnlineOnly() != 1) {
// $productValide = false;
// }
// Stock disponible
// if ($product->getUseStock() && ($product->getStock() < $product->getMinimalQuantity())) {
// $productValide = false;
// }
// Redirection du produit
// if ($product->getRedirect() != 0) {
// $productValide = false;
// }
// Vérification de la quantité restante
// if ($product->getUseStock() && ($quantity != null && ($product->getStock() - $quantity) < 0)) {
// $productValide = false;
// }
// Produit devenu invalide
if (!$productValide && $quantity == null) {
// Suppression du produit du panier
$this->remove($product);
}
return $productValide;
}
}