src/Manager/CartManager.php line 318

Open in your IDE?
  1. <?php
  2. namespace App\Manager;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use App\Entity\Cart;
  5. use App\Service\Mailer;
  6. use App\Manager\CustomerManager;
  7. use App\Entity\Product;
  8. use App\Entity\Coupon;
  9. class CartManager {
  10. private $em;
  11. private $mailer;
  12. private $customerMgr;
  13. private $priceMgr;
  14. private $session;
  15. private $translator;
  16. public function __construct(\Symfony\Component\HttpFoundation\Session\SessionInterface $session, EntityManagerInterface $em, Mailer $mailer, CustomerManager $customerMgr, \Symfony\Contracts\Translation\TranslatorInterface $translator)
  17. {
  18. $this->em = $em;
  19. $this->mailer = $mailer;
  20. $this->customerMgr = $customerMgr;
  21. $this->session = $session;
  22. $this->translator = $translator;
  23. }
  24. public function getCustomer()
  25. {
  26. return $this->customerMgr->getCustomer();
  27. }
  28. public function isExpert()
  29. {
  30. return $this->customerMgr->isExpert();
  31. }
  32. public function getPriceContext()
  33. {
  34. return $this->customerMgr->getPriceContext();
  35. }
  36. public function getCartByCustomerId($cid)
  37. {
  38. $customer = $this->em->getRepository('App:Customer')->find($cid);
  39. if($customer){
  40. return $this->getCartByCustomer($customer);
  41. }
  42. return null;
  43. }
  44. public function getCartByCustomer($customer)
  45. {
  46. return $this->em->getRepository('App:Cart')->findOneByCustomer($customer);
  47. }
  48. public function remindCustomer(Cart $cart)
  49. {
  50. $this->markCartAsReminded($cart);
  51. return $this->mailer->remindCart($cart);
  52. }
  53. protected function markCartAsReminded(Cart $cart)
  54. {
  55. // $items = $cart->getItems();
  56. // if(!empty($items)){
  57. // foreach ($items as $item){
  58. // $item->setReminded(new \DateTime);
  59. // $this->em->persist($item);
  60. // }
  61. // $this->em->flush();
  62. // }
  63. return true;
  64. }
  65. public function getLastUnremindedCarts()
  66. {
  67. $carts = [];
  68. $customerIds = $this->getLastUnremindedCustomerIds();
  69. if(!empty($customerIds)){
  70. foreach ($customerIds as $cid){
  71. $cart = $this->getCartByCustomerId($cid);
  72. if($cart)
  73. $carts[] = $cart;
  74. }
  75. }
  76. return $carts;
  77. }
  78. public function getLastUnremindedCustomerIds() {
  79. $yesterday = new \DateTime();
  80. $yesterday->modify('-1 day');
  81. $conn = $this->em->getConnection();
  82. $stmt = $conn->prepare('SELECT distinct(customers_id) FROM customers_basket where customers_basket_reminded is null and `customers_basket_date_added`=\''.$yesterday->format('Ymd').'\'');
  83. $stmt->execute();
  84. $customerIds = [];
  85. $lines = $stmt->fetchAll();
  86. foreach($lines as $row){
  87. $customerIds[] = $row['customers_id'];
  88. }
  89. return $customerIds;
  90. }
  91. public function getLastCarts($sinceNbDays=180) {
  92. $yesterday = new \DateTime();
  93. $yesterday->modify('-'.$sinceNbDays.' day');
  94. $conn = $this->em->getConnection();
  95. $stmt = $conn->prepare('SELECT distinct(customers_id) FROM customers_basket where `customers_basket_date_added`>=\''.$yesterday->format('Ymd').'\'');
  96. $stmt->execute();
  97. $carts = [];
  98. $lines = $stmt->fetchAll();
  99. foreach($lines as $row){
  100. $cart = $this->getCartByCustomerId($row['customers_id']);
  101. if($cart)
  102. $carts[] = $cart;
  103. }
  104. return $carts;
  105. }
  106. public function getCartSession()
  107. {
  108. return $this->session->get('cart',$this->getEmptyCart());
  109. }
  110. private function getEmptyCart()
  111. {
  112. return ['products'=>[],'id'=>null,'createdAt'=>(new \DateTime())->format('Y-m-d H:i:s'),'updatedAt'=>'0000-00-00 00:00:00', 'coupons'=>[]];
  113. }
  114. public function getGifts()
  115. {
  116. return $this->em->getRepository('App:Product')->getGifts();
  117. }
  118. public function fillCartFromSession(&$cart)
  119. {
  120. $cart->setItems([]);
  121. $cartSession = $this->getCartSession();
  122. if(empty($cartSession['products']))
  123. return;
  124. foreach($cartSession['products'] as $item){
  125. $product = $this->em->getRepository('App:Product')->find($item['product']['id']);
  126. if(!empty($product))
  127. $cart->addItem(
  128. $product,
  129. $item['qty']
  130. );
  131. }
  132. }
  133. public function getCart($reload=false) : Cart
  134. {
  135. $customer = $this->customerMgr->getCustomer();
  136. $cartSession = $this->getCartSession();
  137. $cart = null;
  138. $fillFromSession = false;
  139. $priceGroup = $this->customerMgr->getPriceContext();
  140. if($customer){
  141. $cart = $this->em->getRepository('App:Cart')->findOneBy([
  142. 'customer' => $customer->getId(),
  143. 'priceGroup' => $priceGroup,
  144. ]);
  145. if($cart)
  146. $cart->setCustomer($customer);
  147. }else if(!empty($cartSession['id'])){
  148. $cart = $this->em->getRepository('App:Cart')->find($cartSession['id']);
  149. }
  150. if(empty($cart)){
  151. $cart = new Cart();
  152. $cart->setPriceGroup($priceGroup);
  153. if($customer){
  154. $cart->setCustomer($customer);
  155. }
  156. }
  157. if(!isset($cartSession['coupons'])){
  158. $cartSession['coupons'] = [];
  159. }
  160. foreach($cartSession['coupons'] as $c){
  161. $coupon = $this->em->getRepository(\App\Entity\Coupon::class)->find($c['id']);
  162. if(!empty($coupon))
  163. $cart->addCoupon($coupon);
  164. }
  165. $this->cart = $cart;
  166. return $this->cart;
  167. }
  168. public function add(Product $product,$qty,$actionType=null,$genericProductId=null,$categoryId=null,$force=false)
  169. {
  170. if(!$this->customerMgr->isLogged()){
  171. return [
  172. 'success'=>false,
  173. 'error'=>'',
  174. 'requestQty'=>$qty,
  175. 'totalQty'=>$qty
  176. ];
  177. }
  178. $cart = $this->getCart();
  179. if($cart->hasProduct($product)){
  180. $qtyUpdate = $cart->getItemQuantityByProduct($product)+$qty;
  181. if($qtyUpdate<=0){
  182. return $this->remove($product);
  183. }
  184. return $this->update($product, $qtyUpdate);
  185. }
  186. if($product->isGift()){
  187. $qty = 1;
  188. }
  189. $cart->addItem($product,$qty);
  190. $checkQuantity = $this->checkQuantityForProduct($product, $qty, $force);
  191. if($checkQuantity === true){
  192. return $this->save($cart);
  193. }else{
  194. return [
  195. 'success'=>false,
  196. 'error'=>$checkQuantity,
  197. 'requestQty'=>$qty,
  198. 'totalQty'=>$qty
  199. ];
  200. }
  201. return [
  202. 'success'=>false,
  203. 'error'=>'',
  204. 'requestQty'=>$qty,
  205. 'totalQty'=>$qty
  206. ];
  207. }
  208. public function update(Product $product,$qty)
  209. {
  210. $cart = $this->getCart();
  211. if(empty($cart)){
  212. $cart = [];
  213. }
  214. if(!$cart->hasProduct($product)){
  215. return $this->add($product, $qty, null, null, null, $force);
  216. }
  217. if($qty<=0){
  218. return $this->remove($product);
  219. }
  220. if($product->isGift()){
  221. $qty = 1;
  222. }
  223. $cart->updateItem($product,$qty);
  224. $cart = $this->save($cart);
  225. return $cart;
  226. }
  227. public function qtyInCart(Product $product)
  228. {
  229. $cart = $this->getCart();
  230. if(empty($cart))
  231. return 0;
  232. return $cart->getItemQuantityByProduct($product);
  233. }
  234. public function setAddress(\App\Entity\Address $address, $type) {
  235. $cart = $this->getCart();
  236. if($type == 'shipping'){
  237. $cart->setShippingAddress($address);
  238. }else if($type == 'billing'){
  239. $cart->setBillingAddress($address);
  240. }else{
  241. throw new \Exception("Type d'adresse inconnu (".$type.")");
  242. }
  243. return $this->save($cart);
  244. }
  245. public function setCarrier(\App\Entity\Carrier $carrier) {
  246. $cart = $this->getCart();
  247. $cart->setCarrier($carrier);
  248. return $this->save($cart);
  249. }
  250. public function checkQuantityForProduct(Product $product, $qty, $force){
  251. return $product->getQuantity()>=$qty;
  252. }
  253. public function checkCartDisponibility(Cart $cart) {
  254. // $output = [
  255. // 'products' => [],
  256. // 'message' => ''
  257. // ];
  258. // foreach($cart->getItems() as $item){
  259. // $product = $item->getProduct();
  260. // if(!$item->getProduct()->isAvailable()){
  261. // $cart->removeItem($product);
  262. // $output['products'][] = $product;
  263. // }
  264. // }
  265. // if(!empty($output['products'])){
  266. // $this->save($cart);
  267. // return false;
  268. // }
  269. return true;
  270. }
  271. public function remove(Product $product)
  272. {
  273. $cart = $this->getCart();
  274. if(empty($cart)){
  275. return false;
  276. }
  277. $item = $cart->getItemByProduct($product);
  278. if($item){
  279. $this->em->remove($item);
  280. $this->em->flush();
  281. $cart = $this->save($cart);
  282. }
  283. return $this->save($cart);
  284. }
  285. public function empty()
  286. {
  287. $cart = $this->getCart();
  288. $this->em->remove($cart);
  289. $this->em->flush();
  290. $this->session->remove('cart');
  291. }
  292. public function save(Cart $cart)
  293. {
  294. $customer = $this->customerMgr->getCustomer();
  295. $cartId = $cart->getId();
  296. $items = $cart->getItems();
  297. if($customer){
  298. if(empty($cartId))
  299. $cart->setCustomer($customer);
  300. }
  301. if(empty($items)){
  302. $this->em->remove($cart);
  303. }else{
  304. $this->em->persist($cart);
  305. }
  306. $this->em->flush();
  307. $this->session->set('cart',$cart->toArray());
  308. $this->cart = $cart;
  309. return $this->cart;
  310. }
  311. public function assignCartToCustomer($cartId, Customer $customer)
  312. {
  313. // utilisation d'une requête SQL pour empecher l'ecrasement de la date de mise à jour.
  314. $conn = $this->em->getConnection();
  315. $conn->executeQuery("update Cart set CustomerId=".$customer->getId()." where Id=:id",['id'=>$cartId]);
  316. }
  317. public function checkCartItems(Cart $cart) {
  318. // Available
  319. $refs = [];
  320. foreach($cart->getItems() as $item){
  321. $product = $item->getProduct();
  322. if(!$item->getProduct()->isAvailable() || $item->getProduct()->isStopped()){
  323. $cart->removeItem($product);
  324. $refs[] = $product->getReference();
  325. }
  326. }
  327. if(!empty($refs)){
  328. $this->session->getFlashBag()->add('error', $this->translator->trans('Les articles suivants ne sont plus disponibles à la vente : ') . ' ' . implode(', ',$refs));
  329. $this->save($cart);
  330. return false;
  331. }
  332. $refs = [];
  333. foreach($cart->getItems() as $item){
  334. $product = $item->getProduct();
  335. if($item->getProduct()->getQuantity() < $item->getQuantity()){
  336. $refs[] = $product->getReference();
  337. }
  338. }
  339. if(!empty($refs)){
  340. $this->session->getFlashBag()->add('error', $this->translator->trans('La quantité demandée pour les articles suivants n\'est pas disponible : ') . ' ' . implode(', ',$refs));
  341. $this->save($cart);
  342. return false;
  343. }
  344. $refs = [];
  345. $country = $this->customerMgr->getCustomerCountry();
  346. foreach($cart->getItems() as $item){
  347. $product = $item->getProduct();
  348. if(!$item->getProduct()->isAvailableForCountry($country)){
  349. $cart->removeItem($product);
  350. $refs[] = $product->getReference();
  351. }
  352. }
  353. if(!empty($refs)){
  354. $this->session->getFlashBag()->add('error', $this->translator->trans('Les articles suivants ne sont pas disponibles à la vente pour votre zone géographique : ') . ' ' . implode(', ',$refs));
  355. $this->save($cart);
  356. return false;
  357. }
  358. return true;
  359. }
  360. public function checkShippingRate(Cart $cart) {
  361. $shippingRate = $cart->getShippingRate();
  362. return empty($shippingRate) ? false : true;
  363. }
  364. public function checkDropShipping(Cart $cart) {
  365. if($cart->getCarrier()->getCode() != 'dropshipping')
  366. return true;
  367. return $cart->getBillingAddress()->getId() != $cart->getShippingAddress()->getId();
  368. }
  369. public function addCoupon(Coupon $coupon) {
  370. $cart = $this->getCart();
  371. $result = $cart->addCoupon($coupon);
  372. if($result === true){
  373. return $this->save($cart);
  374. }
  375. return $result;
  376. }
  377. }