<?php
namespace App\Services;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
/**
* Cart management, include sending emails for both customer et provider
*/
class Cart
{
private $session;
private $cartContent = [];
private $cartTotalQuantity;
private $maxQuantityAllowed = 100;
private $weightPrice = false;
public function __construct($session)
{
$this->session = $session;
}
/**
* Add product by its id to the cart session.
* Add the correct product quantity if this function
* is called again.
*
* Example of $cartContent added to the session:
* $cartContent = [
* $id => ["quantity" => 3],
* ["product-custom-data" => ["message" => "Message preso", "police" => 1, "image" => 1]],
* $id => ["quantity" => 1]
* ]
*
* @param [type] $id
* @return void
*/
public function addToCart($id, $quantity, $customerCustomMessage, $customerCustomPolice, $customerCustomImage)
{
$this->cartContent = [];
//Récupérer les valeurs custom du client et procéder au vérifications de leurs intégrités via des methodes
//Ajouter ces valeurs à $this->cartContent[$id]
if ($this->cartSessionExists())
{
$this->cartContent = $this->getCart();
if (isset($this->cartContent[$id]) && $quantity == 1)
{
$this->cartContent[$id]['quantity']++;
}
elseif(isset($this->cartContent[$id]) && $quantity > 1 && $quantity <= $this->maxQuantityAllowed)
{
$this->cartContent[$id]['quantity'] += $quantity;
}
elseif($quantity != 0 && $quantity <= $this->maxQuantityAllowed)
{
//Ajouter le nouveau produit
$this->cartContent[$id] = ['quantity' => $quantity];
}
//Ajout des éléments de personnalisations
if ($this->isCustomizableProduct($customerCustomMessage))
{
if ($customerCustomMessage && $customerCustomPolice && $customerCustomImage)
{
$this->cartContent[$id]['product-custom-data'] = ['message' => $customerCustomMessage, 'police' => $customerCustomPolice, 'image' => $customerCustomImage];
}
}
}
if (!$this->cartSessionExists())
{
$this->cartContent[$id] = ['quantity' => $quantity];
//Ajout des éléments de personnalisations
if ($this->isCustomizableProduct($customerCustomMessage))
{
if ($customerCustomMessage && $customerCustomPolice && $customerCustomImage)
{
$this->cartContent[$id]['product-custom-data'] = ['message' => $customerCustomMessage, 'police' => $customerCustomPolice, 'image' => $customerCustomImage];
}
}
}
$this->setCartTotalQuantity($this->getCartContent());
$this->setCartContent($this->cartContent);
}
/**
* Check if is a products is customizable when checking
* $customerCustomMessage that is required when a product is recognized as a customizable
* product by twig (twig shows form input to select a custom message when a product customizable is detected when
* reading product.customizable entity if exists)
*
* @return boolean
*/
public function isCustomizableProduct($customerCustomMessage)
{
if ($customerCustomMessage)
{
return true;
}
}
public function getMaxQuantityAllowed()
{
return $this->maxQuantityAllowed;
}
public function getCartTotalQuantity(): int
{
$cartSession = $this->getCart();
if($cartSession)
{
$totalQuantity = 0;
foreach ($cartSession as $product)
{
$totalQuantity += $product['quantity'];
}
$this->cartTotalQuantity =$totalQuantity;
}
return (int)$this->cartTotalQuantity;
}
/**
* Save cart Total Quantity in $this->cartTotalQuantity
* cartTotalQuantity is obtained from current session.
*
* @param array $cartContent cart content from current session.
* @return void
*/
public function setCartTotalQuantity($cartContent)
{
$quantity = 0;
foreach($cartContent as $value)
{
$quantity += $value['quantity'];
}
$this->cartTotalQuantity = $quantity;
}
/**
* Return the cart session content
*
*/
public function getCart()
{
if ($this->cartSessionExists())
{
return $this->session->get('cart');
}
return false;
}
/**
* Get cart content from attribute this->cartContent
* ONLY USE THIS METHOD WHEN setCartContent() methode WASE USE ONCE.
* OTHERWISE, USE getCart() INSTEAD
* (See setCartContent method)
*
* @return void
*/
public function getCartContent()
{
if (!empty($this->cartContent))
{
return $this->cartContent;
}
return 'The cart is empty';
}
/**
* Get cart products object alongsides products quantity for
* twig display.
*
* @param [productRepository object] $productRepository
* @return void
*/
public function getCartProducts($productRepository)
{
$cartContent = $this->getCart();
$cartProducts = [];
if($this->cartSessionExists())
{
foreach ($cartContent as $id => $productData)
{
$cartProducts[] = ['product' => $productRepository->find($id), 'quantity' => $productData['quantity'], 'product_custom_data' => $productData['product-custom-data'] ?? null];
}
}
//dd($cartProducts);
return $cartProducts;
}
public function getTotalPrice($productRepository)
{
$cartProducts = $this->getCart();
$products = [];
$totalPrice = 0;
if($this->cartSessionExists())
{
foreach ($cartProducts as $id => $product)
{
$productPrice = $productRepository->find($id);
$productPrice = floatval($productPrice->getPrice());
$totalPrice += $product["quantity"] * $productPrice;
}
}
return $totalPrice;
}
/**
* Get total weight for displaying via twig / html for user view
*
* @param [type] $productRepo
* @return void
*/
public function getTotalWeightForDisplay($productRepo)
{
$weightToDisplay = $this->getTotalWeight($productRepo);
if (!is_string($weightToDisplay))
{
if ($weightToDisplay >= 1000)
{
$weightToDisplay = $weightToDisplay / 1000;
//$weightToDisplay = number_format($weightToDisplay, 3);
$weightToDisplay = $weightToDisplay.' Kg';
return $weightToDisplay;
}
if ($weightToDisplay < 1000)
{
$weightToDisplay = $weightToDisplay.' g';
return $weightToDisplay;
}
}
return $weightToDisplay;
}
/**
* Get ttcPrice AND Set weightPrice
*
* @param [ProductRepository] $productRepo
* @return void
*/
public function getTtcPrice($productRepo)
{
$totalPrice = $this->getTotalPrice($productRepo);
$totalWeight = $this->getTotalWeight($productRepo);
$weightPrice = 0;
$ttcPrice = 0;
switch ($totalWeight)
{
case $totalWeight >= 0 && $totalWeight <= 19;
$weightPrice = 3;
break;
case $totalWeight >= 20 && $totalWeight <= 99;
$weightPrice = 4.80;
break;
case $totalWeight >= 100 && $totalWeight <= 249;
$weightPrice = 6.80;
break;
case $totalWeight >= 250 && $totalWeight <= 499;
$weightPrice = 8.20;
break;
case $totalWeight >= 500 && $totalWeight <= 999;
$weightPrice = 9.80;
break;
case $totalWeight >= 1000 && $totalWeight <= 1999;
$weightPrice = 15.50;
break;
case $totalWeight >= 2000;
$weightPrice = 20.50;
break;
}
$this->weightPrice = $weightPrice;
$ttcPrice = $totalPrice += $weightPrice;
return $ttcPrice;
}
/**
* MUST BE USED AFTER GET TTCPRICE.
* Beacause getTtcPrice() is the setter for weightPrice
*
* @return float
*/
public function getWeightPrice()
{
return $this->weightPrice;
}
/**
* Get total weight in Grammes from all products
*
* @param [ProductRepository] $productRepo
* @return void
*/
public function getTotalWeight($productRepo)
{
if (!$this->cartSessionExists())
{
return 'Le panier est vide';
}
$cartProducts = $this->getCartProducts($productRepo);
$totalWeight = 0;
foreach ($cartProducts as $product)
{
$productWeightUnit = $product['product']->getWeightUnit();
if ($productWeightUnit == 'kg')
{
$productWeightInGramme = $product['product']->getWeight() * 1000;
$totalWeight += $productWeightInGramme * $product['quantity'];
}
if ($productWeightUnit == 'g')
{
$productWeight = $product['product']->getWeight();
$totalWeight += $productWeight * $product['quantity'];
}
}
return $totalWeight;
}
/**
* Save cartContent to the cart session
*
* @param array $cartContent
* @return void
*/
public function setCartContent(array $cartContent)
{
$this->session->set('cart', $cartContent);
}
/**
* Check if the cart attribut exist inside the
* current session.
*
* @return boolean
*/
public function cartSessionExists()
{
if ($this->session->get('cart'))
{
return true;
}
}
/**
* Clear cart content session
*
* @return void
*/
public function clearCart()
{
$this->session->remove('cart');
}
/**
* Send an email with billing summary for the custommer and to the provider at the end of the transaction
* Flush cart session at the end.
*
* @param [type] $user
* @param [type] $mailer
* @param [type] $billingDetails
* @param [type] $productRepo
* @return void
*/
public function sendEndTransactionMail($user, $mailer, $billingDetails, $productRepo)
{
$cartProducts = $this->getCartProducts($productRepo);
$totalPrice = $this->getTotalPrice($productRepo);
$this->getTtcPrice($productRepo); //Must be used to set weightPrice Cart object's attribute to get getWeightPrice used, a default from my part ...
$totalWeight = $this->getTotalWeightForDisplay($productRepo);
$weightPrice = $this->getWeightPrice();
$transactionId = $billingDetails['captureResponse']['jsonResponse']['purchase_units'][0]['payments']['captures'][0]['id'];
$selectedUserEmail = $billingDetails["email"];
//TO CUSTOMER MAIL
$customerMail = (new TemplatedEmail())
->from('no-reply@lestresorsdeluna.fr')// METTRE LE BON MAIL correspondant à celui d'ovh (A faire corresspodre avec le .env) (celui des trésors de luna)
->to($selectedUserEmail)
->subject('Les trésors de Luna. Récapitulatif d\'achat')
->context([
'surname' => $user->getSurname(),
'firstname' => $user->getFirstname(),
'cartProducts' => $cartProducts,
'totalPrice' => $totalPrice,
'totalWeight' => $totalWeight,
'weightPrice' => $weightPrice,
'transactionId' => $transactionId
])
->htmlTemplate('emails/buyingSummary.html.twig');
//TO PROVIDER MAIL
$providerMail = (new TemplatedEmail())
->from('no-reply@lestresorsdeluna.fr')
->to(new Address('contact.tresorsdeluna@gmail.com'))// METTRE LE BON MAIL (celui des trésors de luna gmail: contact.tresorsdeluna@gmail.com)
->subject("Demande d'achat")
->context([
'surname' => $billingDetails["lastname"],
'firstname' => $billingDetails["firstname"],
'mail' => $selectedUserEmail,
'phone' => !empty($billingDetails["phone"]) ? $billingDetails["phone"] : null ,
'city' => $billingDetails["city"],
'zip' => $billingDetails["zip"],
'adress' => $billingDetails["address"],
'additionalAdressInfo' => !empty($billingDetails["additional-address-information"]) ? $billingDetails["additional-address-information"] : null,
'additionalInformation' => !empty($billingDetails["additionalInformation"]) ? $billingDetails["additionalInformation"] : null,
'cartProducts' => $cartProducts,
'totalPrice' => $totalPrice,
'totalWeight' => $totalWeight,
'weightPrice' => $weightPrice,
'transactionId' => $transactionId
])
->htmlTemplate('emails/buying_order.html.twig');
try
{
$mailer->send($customerMail);
$mailer->send($providerMail);
return true;
}
catch(TransportExceptionInterface $e)
{
return false;
}
}
/**
* Method for testing purpose.
*
* @return void
*/
public function test()
{
$session = $this->session->get('cart');
return $session;
}
}
?>