src/Service/Cart/Cart.php line 66

Open in your IDE?
  1. <?php
  2. namespace App\Service\Cart;
  3. use App\Env;
  4. use App\DTO\AppDTO;
  5. use App\DTO\CartDTO;
  6. use App\Entity\Prod;
  7. use App\Model\ProdColor;
  8. use App\Service\Auth\Auth;
  9. use App\ValueObject\Money;
  10. use App\Entity\CartUnsaved;
  11. use App\Entity\Cart as EntityCart;
  12. use App\Repository\CartRepository;
  13. use App\Repository\ProdRepository;
  14. use App\Service\Discount\NumDiscount;
  15. use App\Service\Discount\SumDiscount;
  16. use App\Service\Discount\UserDiscount;
  17. use Doctrine\ORM\EntityManagerInterface;
  18. use App\Repository\CartUnsavedRepository;
  19. use Symfony\Component\Security\Core\Security;
  20. use Symfony\Component\HttpFoundation\RequestStack;
  21. use Symfony\Component\HttpFoundation\Session\Session;
  22. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  23. class Cart
  24. {
  25.     protected EntityManagerInterface $em;
  26.     protected AppDTO $app;
  27.     protected Auth $Auth;
  28.     protected SessionInterface $Session;
  29.     protected ProdColor $prodColor;
  30.     protected RequestStack $rs;
  31.     protected $cart;
  32.     protected $prods_limited = [];
  33.     protected $order_id;
  34.     protected NumDiscount $NumDiscount;
  35.     protected SumDiscount $SumDiscount;
  36.     protected UserDiscount $UserDiscount;
  37.     //Repository
  38.     protected ProdRepository $Prods;
  39.     protected CartUnsavedRepository $CartUnsaved;
  40.     protected CartRepository $Carts;
  41.     public function __construct(EntityManagerInterface $emAppDTO $appAuth $AuthNumDiscount $NumDiscountSumDiscount $SumDiscountUserDiscount $UserDiscountProdColor $prodColorRequestStack $rsSecurity $security)
  42.     {
  43.         $this->em $em;
  44.         $this->app $app;
  45.         $this->Auth $Auth;
  46.         $this->Auth->setUser($security->getUser());
  47.         $this->prodColor $prodColor;
  48.         $this->rs $rs;
  49.         $this->Session $rs->getSession();
  50.         $this->Prods $this->em->getRepository(Prod::class);
  51.         $this->CartUnsaved $this->em->getRepository(CartUnsaved::class);
  52.         $this->Carts $this->em->getRepository(EntityCart::class);
  53.         $this->NumDiscount $NumDiscount;
  54.         $this->SumDiscount $SumDiscount;
  55.         $this->UserDiscount $UserDiscount;
  56.         $this->cart $this->Session->get('cart');
  57.         
  58.         if (empty($this->cart)) {
  59.             $this->cart = [];
  60.         }
  61.         if (empty($this->cart)) {
  62.             $this->load_session();
  63.         }
  64.         $this->recount();
  65.         $this->flush();
  66.     }
  67.     public function getCart(): array
  68.     {
  69.         $deleted 0;
  70.         foreach ($this->cart as $k => $v) {
  71.             $prod $this->Prods->find($v['id']);
  72.             if ($prod == null) {
  73.                 $deleted 1;
  74.                 unset ($this->cart[$k]);
  75.             }
  76.         }
  77.         if ($deleted) {
  78.             $this->save_session();
  79.             $this->flush();
  80.         }
  81.         return $this->cart;
  82.     }
  83.     public function isFreeDelivery(float $free_delivery_min): bool
  84.     {
  85.         $freedelivery false;
  86.         if ($this->getAmount() >= $free_delivery_min && !$this->Auth->isOpt()) {
  87.             $freedelivery true;
  88.         }
  89.         return $freedelivery;
  90.     }
  91.     public function getFromOrder(int $order_id): array
  92.     {
  93.         $Prods $this->em->getRepository(Prod::class);
  94.         $cart $this->loadFromOrder2($order_id);
  95.         // $cart = $this->getCart();
  96.         
  97.         foreach ($cart as $k => $v) {
  98.             $cart[$k]['prod'] = $Prods->find($v['id']);
  99.         }
  100.         
  101.         return $cart;
  102.     }
  103.     public function loadFromOrder(int $order_id)
  104.     {
  105.         $this->order_id $order_id;
  106.         /** @var \App\Entity\Cart[] $prods */
  107.         $prods $this->em->createQuery("SELECT c FROM App\Entity\Cart c WHERE c.order_id = ".$order_id)->getResult();
  108.                 
  109.         foreach($prods as $prod) {
  110.             $this->cart[$this->getCartId($prod->getProd()->getId(), 0)] = [
  111.                 'cid' => $prod->getId(),
  112.                 'id' => $prod->getProd()->getId(),
  113.                 'var' => $prod->getVar(),
  114.                 'num' => $prod->getNum(),
  115.                 'baseprice' => (new Money($prod->getPrice()))->getAmount(),
  116.                 'price' => 0,
  117.                 'skidka' => $prod->getSkidka(),
  118.                 'numdiscount' => $prod->getNumdiscount(),
  119.                 'userdiscount' => $prod->getUserdiscount(),
  120.             ];
  121.         }
  122.         $this->flush();
  123.     }
  124.     public function loadFromOrder2(int $order_id)
  125.     {
  126.         $cart = [];
  127.         $this->order_id $order_id;
  128.         /** @var \App\Entity\Cart[] $prods */
  129.         $prods $this->em->createQuery("SELECT c FROM App\Entity\Cart c WHERE c.order_id = ".$order_id)->getResult();
  130.                 
  131.         foreach($prods as $prod) {
  132.             if ($prod->getProd() == null) {
  133.                 continue;
  134.             }
  135.             $cart[$this->getCartId($prod->getProd()->getId(), 0)] = [
  136.                 'cid' => $prod->getId(),
  137.                 'id' => $prod->getProd()->getId(),
  138.                 'var' => $prod->getVar(),
  139.                 'num' => $prod->getNum(),
  140.                 'baseprice' => (new Money($prod->getPrice()))->getAmount(),
  141.                 'price' => (new Money($prod->getPrice()))->getAmount(),
  142.                 'skidka' => $prod->getSkidka(),
  143.                 'numdiscount' => $prod->getNumdiscount(),
  144.                 'userdiscount' => $prod->getUserdiscount(),
  145.             ];                       
  146.         }
  147.         $cart $this->recount($cart);
  148.         return $cart;
  149.     }
  150.     public function getCartId(int $prod_idint $var 0, array $chars = [], int $user_id 0) {
  151.         $id $prod_id."_".$var;
  152.             
  153.         if (!empty($chars)) {
  154.             ksort($chars);
  155.             $id .= "_".json_encode($chars);                
  156.         }
  157.             
  158.         if ($user_id) {
  159.             $id .= "_".$user_id;
  160.         }
  161.             
  162.         return md5($id);
  163.     }
  164.     public function addItem($id 0$var 0$num 1$price 0$skidka 0$numdiscount = [], $weight 0){
  165.         $cart_id $this->getCartId($id$var);
  166.             
  167.         if(isset($this->cart[$cart_id])){
  168.             $this->cart[$cart_id]['num'] += $num;
  169.             if($this->cart[$cart_id]['skidka'] == 0){
  170.                 $this->cart[$cart_id]['numdiscount'] = $this->NumDiscount->getDiscount($num$numdiscount);
  171.                 $this->cart[$cart_id]['userdiscount'] = $this->UserDiscount->getValue();
  172.             }else{
  173.                 $this->cart[$cart_id]['numdiscount'] = 0;
  174.                 $this->cart[$cart_id]['userdiscount'] = $this->UserDiscount->getValue();
  175.             }
  176.         }else{
  177. //            array_unshift($this->cart, array($cart_id => array('id' => intval($id), 'var' => intval($var), 'num' => intval($num), 'baseprice' => floatval($price), 'price' => floatval($price), 'skidka' => floatval($skidka), 'weight' => floatval($weight))));
  178.             $this->cart[$cart_id] = array('id' => intval($id), 'var' => intval($var), 'num' => intval($num), 'baseprice' => floatval($price), 'price' => floatval($price), 'skidka' => floatval($skidka), 'weight' => floatval($weight));
  179.     
  180.             if($this->cart[$cart_id]['skidka'] == 0){
  181.                 $this->cart[$cart_id]['numdiscount'] = $this->NumDiscount->getDiscount($num$numdiscount);
  182.                 $this->cart[$cart_id]['userdiscount'] = $this->UserDiscount->getValue();
  183.             }else{
  184.                 $this->cart[$cart_id]['numdiscount'] = 0;
  185.                 $this->cart[$cart_id]['userdiscount'] = $this->UserDiscount->getValue();
  186.             }
  187.         }
  188.         $this->recount();
  189.         $this->save_session();
  190.         $this->flush();
  191.     }
  192.     public function updateItem($cart_id ''$num 0$numdiscount = []){
  193.         if($num == 0){
  194.             $prod $this->cart[$cart_id]['id'];
  195.             $prodvar $this->cart[$cart_id]['var'];
  196.             unset($this->cart[$cart_id]);
  197.         }else{
  198.             $this->cart[$cart_id]['num'] = intval($num);
  199.             if($this->order_id == 0) {
  200.                 if($this->cart[$cart_id]['skidka'] == 0){
  201.                     $this->cart[$cart_id]['numdiscount'] = $this->NumDiscount->getDiscount($num$numdiscount);
  202.                     $this->cart[$cart_id]['userdiscount'] = $this->UserDiscount->getValue();
  203.                 }else{
  204.                     $this->cart[$cart_id]['numdiscount'] = 0;
  205.                     $this->cart[$cart_id]['userdiscount'] = $this->UserDiscount->getValue();
  206.                 }
  207.             } else {
  208.                 if($this->cart[$cart_id]['skidka'] == 0){
  209.                     $this->cart[$cart_id]['numdiscount'] = $this->NumDiscount->getDiscount($num$numdiscount);
  210.                     $this->cart[$cart_id]['userdiscount'] = $this->UserDiscount->getValue();
  211.                 }else{
  212.                     $this->cart[$cart_id]['numdiscount'] = 0;
  213.                     $this->cart[$cart_id]['userdiscount'] = 0;
  214.                 }
  215.             }
  216.                 
  217.             $this->recount();
  218.             $prod intval($this->cart[$cart_id]['id']);
  219.             $prodvar intval($this->cart[$cart_id]['var']);
  220.         }
  221.         $this->save_session();
  222.         $this->flush();
  223.     }
  224.     public function deleteItem(string $cart_id)
  225.     {
  226.         $prod $this->cart[$cart_id]['id'];
  227.         $prodvar $this->cart[$cart_id]['var'];
  228.         unset($this->cart[$cart_id]);
  229.         $this->recount();
  230.         $this->save_session();
  231.         $this->flush();
  232.     }
  233.     public function deleteAll()
  234.     {
  235.         $this->cart = [];
  236.         $this->delete_session();
  237.         $this->flush();
  238.     }    
  239.     public function cart_id($prod 0$var 0$chars = array(), $user_id 0)
  240.     {
  241.         $this->getCartId($prod$var$chars$user_id);        
  242.     }
  243.                 
  244.     public function getAmount(): float
  245.     {
  246.         $amount 0;
  247.         foreach($this->cart as $k => $v)
  248.             $amount += round($v['price'], Env::price_precission()) * $v['num'];
  249.             
  250.         return $amount;
  251.     }
  252.     public function getBaseAmount(): float 
  253.     {
  254.         $amount 0;
  255.         foreach($this->cart as $k => $v)
  256.             $amount += round($v['baseprice'], Env::price_precission()) * $v['num'];
  257.             
  258.         return $amount;
  259.     }
  260.     public function getAmountWithoutDiscount()
  261.     {
  262.         $amount 0;
  263.             
  264.         foreach ($this->cart as $k => $v) {
  265.             $amount += round($v['baseprice'], Env::price_precission()) * $v['num'];
  266.         }
  267.             
  268.         return $amount;
  269.     }
  270.     public function getAmountDelivery()
  271.     {
  272.         return (float)@$_SESSION['_sf2_attributes']['checkout']['delivery_cost'];
  273.     }
  274.     public function getAmountWithDelivery()
  275.     {
  276.         if (($this->getAmount() < $this->app->sett->get('free_delivery_amount')) || ($this->Auth->isOpt())) {
  277.             return $this->getAmount() + $this->getAmountDelivery();
  278.         } else {
  279.             return $this->getAmount();
  280.         }
  281.     }
  282.     public function userLogin($user_id)
  283.     {
  284.         $this->load_session($user_id);
  285.         $discount $this->UserDiscount->getValue();
  286.         if ($discount >= 0) {
  287.             foreach ($this->cart as $k => $v) {
  288.                 $prod $this->Prods->find((int)$v['id']);
  289.                 $numdiscount $prod->getNumdiscount();
  290.         
  291.                 if($v['var'] == 2){
  292.                     $numdiscount $prod->getNumdiscount2();
  293.                 }
  294.     
  295.                 if($v['var'] == 3){
  296.                     $numdiscount $prod->getNumdiscount3();
  297.                 }
  298.                 
  299.                 $this->cart[$k]['userdiscount'] = $discount;
  300.                 if($this->Auth->isOpt()) {
  301.                     $this->cart[$k]['numdiscount'] = $this->NumDiscount->getDiscount((int) $this->cart[$k]['num'], $numdiscount);
  302.                 }
  303.             }
  304.         }
  305.         $this->recount();
  306.         $this->save_session();
  307.         $this->em->createQuery("DELETE App\Entity\CartUnsaved c WHERE c.user_id = '".$this->Auth->guestId()."'")->getResult();
  308.         $this->flush();
  309.     }
  310.         
  311.     public function setUserDiscount($discount){
  312.         if($discount){
  313.             foreach($this->cart as $k => $v){
  314.                 $this->cart[$k]['userdiscount'] = $discount;
  315.             }
  316.         }
  317.         $this->recount();
  318.         $this->save_session();
  319.         $this->flush();
  320.     }
  321.         
  322.     protected function recount($cart = [])
  323.     {
  324.         if (!empty($cart)) {
  325.             foreach ($cart as $k => $v) {
  326.                 if (!isset($v['userdiscount'])) $cart[$k]['userdiscount'] = 0;
  327.                 if (!isset($v['numdiscount'])) $cart[$k]['numdiscount'] = 0;
  328.                 if (!isset($v['skidka'])) $cart[$k]['skidka'] = 0;                
  329.                 
  330.                 $cart[$k]['baseprice'] = (new Money($v['baseprice']))->getAmount();
  331.                 if ($v['skidka']) {
  332.                     $cart[$k]['price'] = (new Money(($v['baseprice']) * (100 $v['skidka']) / 100))->getAmount();
  333.                 } else {
  334.                     $cart[$k]['price'] = (new Money((($v['baseprice']) * (100 $v['userdiscount']) * (100 $v['numdiscount']) / 100 100)))->getAmount();
  335.                 }                
  336.             }
  337.             return $cart;
  338.         }
  339.         foreach ($this->cart as $k => $v) {
  340.             if (!isset($v['userdiscount'])) $this->cart[$k]['userdiscount'] = 0;
  341.             if (!isset($v['numdiscount'])) $this->cart[$k]['numdiscount'] = 0;
  342.             if (!isset($v['skidka'])) $this->cart[$k]['skidka'] = 0;
  343.             
  344.             if ($this->order_id == 0) {
  345.                 $prod $this->Prods->find((int) $v['id']);
  346.                 if ($prod) {
  347.                     $skidka $prod->getSkidka();
  348.             
  349.                     if ($v['var'] == 2) {
  350.                         $skidka $prod->getSkidka2();
  351.                     }
  352.     
  353.                     if ($v['var'] == 3) {
  354.                         $skidka $prod->getSkidka3();
  355.                     }
  356.                 
  357.                     $this->cart[$k]['skidka'] = $skidka;
  358.                 }                
  359.             }
  360.             
  361.             $this->cart[$k]['baseprice'] = (new Money($v['baseprice']))->getAmount();
  362.             if ($v['skidka']) {
  363.                 $this->cart[$k]['price'] = (new Money(($v['baseprice']) * (100 $v['skidka']) / 100))->getAmount();
  364.             } else {
  365.                 $this->cart[$k]['price'] = (new Money((($v['baseprice']) * (100 $v['userdiscount']) * (100 $v['numdiscount']) / 100 100)))->getAmount();
  366.             }                
  367.         }    
  368.     }
  369.         
  370.     public function getProdNum()
  371.     {
  372.         return (empty($this->cart)) ? count($this->cart);
  373.     }
  374.     public function getPackNum()
  375.     {
  376.         $num 0;
  377.         foreach($this->cart as $k => $v)
  378.             $num += $v['num'];
  379.         return $num;
  380.     }
  381.     public function getWeight()
  382.     {
  383.         $weight 0;
  384.         foreach($this->cart as $k => $v)
  385.         {
  386.             $n $v['num'] ?? 0;
  387.             $w $v['weight'] ?? 0;
  388.             $weight += $n $w;
  389.         }
  390.             
  391.         return round($weight 10002);
  392.     }
  393.     protected function load_session()
  394.     {
  395.         $uid $this->Auth->getUserId() ? $this->Auth->getUserId(): $this->Auth->guestId();
  396.         $unsaved_cart $this->CartUnsaved->findOneBy(["user_id" => $uid]);
  397.         if ($unsaved_cart) {
  398.             $cart json_decode($unsaved_cart->getCart(), true);    
  399.             foreach ($cart as $k => $v) {
  400.                 $prod $this->Prods->find((int) $v['id']);
  401.                 
  402.                 $v['baseprice'] = $prod->getPrice();
  403.                 if ($v['var'] == 2) { 
  404.                     $v['baseprice'] = $prod->getPrice2();
  405.                 } elseif ($v['var'] == 3) {
  406.                     $v['baseprice'] = $prod->getPrice3();
  407.                 }
  408.                 
  409.                 if (!isset($this->cart[$k])) {
  410.                     $this->cart[$k] = $v;
  411.                 }                
  412.             }
  413.         }
  414.         $this->flush();
  415.     }
  416.     private function flush()
  417.     {
  418.         $this->Session->set('cart'$this->cart);
  419.     }
  420.     public function save_session()
  421.     {
  422.         $uid $this->Auth->getUserId() ? $this->Auth->getUserId(): $this->Auth->guestId();
  423.         $cart json_encode($this->cartJSON_UNESCAPED_UNICODE);
  424.         $unsaved_cart $this->CartUnsaved->findOneBy(["user_id" => $uid]);
  425.         if ($unsaved_cart) {
  426.             $unsaved_cart->setCart($cart);
  427.         } else {
  428.             $unsaved_cart = new CartUnsaved();
  429.             $unsaved_cart->setUserId($uid);
  430.             $unsaved_cart->setCart($cart);
  431.             $this->em->persist($unsaved_cart);
  432.         }
  433.         $this->em->flush();
  434.     }
  435.     public function delete_session()
  436.     {
  437.         $uid $this->Auth->getUserId() ? $this->Auth->getUserId(): $this->Auth->guestId();
  438.         $unsaved_cart $this->CartUnsaved->findOneBy(["user_id" => $uid]);
  439.         if ($unsaved_cart) {
  440.             $this->em->remove($unsaved_cart);
  441.             $this->em->flush();
  442.         }
  443.     }
  444.         
  445.     public function saveCart(int $order_id) {
  446.         // if ($this->Auth->isAuth() || !$this->Auth->isOpt()) {
  447.         //     $userdiscount = $this->UserDiscount->calculateUserDiscount(new Model_Discount, new Model_Order(), new Model_User(), Auth::userid());
  448.         // } else {
  449.         //     $userdiscount = 0;
  450.         // }
  451.         
  452.         foreach ($this->cart as $k => $v) {
  453.             $prod $this->Prods->find((int) $v['id']);
  454.             $price $prod->getPrice();
  455.             $num $prod->getNum();
  456.             
  457.             if ($v['skidka']) {
  458.                 $v['numdiscount'] = 0;
  459.             }
  460.                 
  461.             $Cart = new EntityCart();
  462.             $Cart->setOrderId($order_id);
  463.             $Cart->setProd($prod);
  464.             $Cart->setVar((int) $v['var']);
  465.             $Cart->setNum((int) $v['num']);
  466.             $Cart->setPrice(round($priceEnv::price_precission()));
  467.             $Cart->setSkidka((int) $v['skidka']);
  468.             $Cart->setNumdiscount((int) $v['numdiscount']);
  469.             $Cart->setUserdiscount((int) $v['userdiscount']);
  470.             //$Cart->setSumdiscount((int) $v['sumdiscount']);
  471.             $this->em->persist($Cart);                
  472.         }
  473.         $this->em->flush();
  474.         $this->flush();
  475.     }
  476.     //Удалить товары с нулевыми остатками из цветов
  477.     public function deleteNullFromColors()
  478.     {
  479.         foreach ($this->cart as $k => $v) {
  480.             $prod $this->Prods->find((int) $v['id']);
  481.             $prod_num $prod->getNum();
  482.             if ($v['var'] == 2$prod_num $prod->getNum2();
  483.             if ($v['var'] == 3$prod_num $prod->getNum3();
  484.             if ($prod->getId() == $v['id'] && $prod_num && $prod_num $v['num']) {
  485.                 $this->prods_limited[] = $v['id'];
  486.                 $this->cart[$k]['num'] = $prod_num;
  487.             }
  488.             if ($prod->getId() == $v['id'] && $prod_num <= 0) {
  489.                 $this->prodColor->deleteColor($prod->getId());
  490.             }
  491.         }
  492.         $this->flush();
  493.     }
  494.     public function save_cart_admin($order_id) {
  495.         $this->em->createQuery("DELETE App\Entity\Cart c WHERE c.order = ".$order_id)->getResult();
  496.         
  497.         foreach ($this->cart as $v) {
  498.             $prod $this->Prods->find((int) $v['id']);
  499.             if ($v['skidka']) {
  500.                 $v['numdiscount'] = 0;
  501.             }
  502.             $Cart = new EntityCart();
  503.             $Cart->setOrderId($order_id);
  504.             $Cart->setProd($prod);
  505.             $Cart->setVar((int) $v['var']);
  506.             $Cart->setNum((int) $v['num']);
  507.             $Cart->setPrice(round($v['baseprice'], Env::price_precission()));
  508.             $Cart->setSkidka((int) $v['skidka']);
  509.             $Cart->setNumdiscount((int) $v['numdiscount']);
  510.             $Cart->setUserdiscount((int) $v['userdiscount']);
  511.             $Cart->setSumdiscount((int) $v['sumdiscount']);
  512.             $this->em->persist($Cart);
  513.         }
  514.         $this->em->flush();
  515.         $this->flush();
  516.     }
  517.     
  518.     public function prods_limited() {
  519.         foreach ($this->cart as $k => $v) {
  520.             $prod $this->Prods->find((int) $v['id']);
  521.             $prod_num $prod->getNum();
  522.             if ($v['var'] == 2$prod_num $prod->getNum2();
  523.             if ($v['var'] == 3$prod_num $prod->getNum3();
  524.         
  525.             if ($prod->getId() == $v['id'] && $prod_num && $prod_num $v['num']) {
  526.                 $this->prods_limited[] = $v['id'];
  527.                 $this->cart[$k]['num'] = $prod_num;
  528.             }
  529.             if ($prod->getId() == $v['id'] && $prod_num <= 0) {
  530.                 unset($this->cart[$k]);
  531.             }
  532.         }
  533.         $this->flush();
  534.         $this->save_session();
  535.         if (!empty($this->prods_limited)) return true;
  536.         else return false;
  537.     }
  538.     public function getProdsLimited (): array
  539.     {
  540.         return $this->prods_limited;
  541.     }
  542. }