vendor/simpledot/ecommerce-bundle/AWEcommerceBundle/Manager/OrderManager.php line 193

Open in your IDE?
  1. <?php
  2. namespace AWEcommerceBundle\Manager;
  3. use AppBundle\Entity\Ecommerce\ProductVariantCustom;
  4. use AppBundle\Entity\ItemCustom;
  5. use AppBundle\Entity\Ecommerce\Order;
  6. use AppBundle\Entity\Ecommerce\OrderItem;
  7. use AppBundle\Entity\Ecommerce\ProductVariantCustom as ProductVariant;
  8. use AppBundle\Entity\Ecommerce\Promotion;
  9. use AWEcommerceBundle\Entity\Setting;
  10. use AWEcommerceBundle\Entity\Shipping\ShippingMethodInterface;
  11. use AWEcommerceBundle\Entity\Shipping\ShippingMethod;
  12. use AWEcommerceBundle\Entity\User;
  13. use AWCmsBundle\Entity\Site;
  14. use AWCmsBundle\Manager\SiteManager;
  15. use AWEcommerceBundle\Event\OrderEvent;
  16. use AWEcommerceBundle\Model\AdjustmentInterface;
  17. use AWEcommerceBundle\PromotionAction\FreeShippingPromotionActionCommand;
  18. use AWEcommerceBundle\Repository\OrderRepository;
  19. use AWEcommerceBundle\Service\Shipping\ShippingService;
  20. use Doctrine\Common\Persistence\ObjectManager;
  21. use Doctrine\ORM\EntityManagerInterface;
  22. use FOS\UserBundle\Model\UserInterface;
  23. use Psr\Log\LoggerInterface;
  24. use Sylius\Component\Order\Factory\AdjustmentFactory;
  25. use Sylius\Component\Order\Model\Adjustment;
  26. use Sylius\Component\Order\Model\OrderInterface;
  27. use Sylius\Component\Order\Modifier\OrderItemQuantityModifier;
  28. use Sylius\Component\Promotion\Action\PromotionApplicator;
  29. use Sylius\Component\Promotion\Checker\Eligibility\CompositePromotionEligibilityChecker;
  30. use Sylius\Component\Resource\Factory\Factory;
  31. use Symfony\Component\Console\Helper\ProgressBar;
  32. use Symfony\Component\Console\Output\ConsoleOutput;
  33. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  34. use Symfony\Component\Translation\TranslatorInterface;
  35. class OrderManager
  36. {
  37.     /**
  38.      * @var ShippingService
  39.      */
  40.     protected $shippingService;
  41.     
  42.     /**
  43.      * @var PromotionApplicator
  44.      */
  45.     protected $promotionApplicator;
  46.     /**
  47.      * @var ObjectManager
  48.      */
  49.     protected $em;
  50.     
  51.     /** @var string */
  52.     protected $orderEntity;
  53.     
  54.     /**
  55.      * @var Factory
  56.      */
  57.     protected $orderFactory;
  58.     
  59.     /**
  60.      * @var AdjustmentFactory
  61.      */
  62.     protected $adjustmentFactory;
  63.     /**
  64.      * @var SettingManager
  65.      */
  66.     protected $settingManager;
  67.     
  68.     /**
  69.      * @var SiteManager
  70.      */
  71.     protected $siteManager;
  72.     protected $eligibilityChecker;
  73.     
  74.     /**
  75.      * @var EventDispatcherInterface
  76.      */
  77.     protected $eventDispatcher;
  78.     /**
  79.      * @var FreeShippingPromotionActionCommand
  80.      */
  81.     protected $freeShippingPromotionActionCommand;
  82.     
  83.     protected $orderItemQuantityModifier;
  84.     
  85.     protected $translator;
  86.     
  87.     /** @var OrderItemManager */
  88.     protected $orderItemManager;
  89.     /**
  90.      * @var PromotionManager
  91.      */
  92.     protected PromotionManager $promotionManager;
  93.     protected LoggerInterface $logger;
  94.     public function __construct(
  95.         EntityManagerInterface $em,
  96.         $orderEntity,
  97.         ShippingService $shippingService,
  98.         PromotionApplicator $promotionApplicator,
  99.         Factory $orderFactory,
  100.         SettingManager $settingManager,
  101.         SiteManager $siteManager,
  102.         AdjustmentFactory $adjustmentFactory,
  103.         CompositePromotionEligibilityChecker $eligibilityChecker,
  104.         FreeShippingPromotionActionCommand $freeShippingPromotionActionCommand,
  105.         EventDispatcherInterface $eventDispatcher,
  106.         OrderItemQuantityModifier $orderItemQuantityModifier,
  107.         OrderItemManager $orderItemManager,
  108.         PromotionManager $promotionManager,
  109.         TranslatorInterface $translator,
  110.         LoggerInterface $logger
  111.     ){
  112.         $this->em $em;
  113.         $this->orderEntity $orderEntity;
  114.         $this->shippingService $shippingService;
  115.         $this->promotionApplicator $promotionApplicator;
  116.         $this->orderFactory $orderFactory;
  117.         $this->settingManager $settingManager;
  118.         $this->siteManager $siteManager;
  119.         $this->adjustmentFactory $adjustmentFactory;
  120.         $this->eligibilityChecker $eligibilityChecker;
  121.         $this->freeShippingPromotionActionCommand $freeShippingPromotionActionCommand;
  122.         $this->eventDispatcher $eventDispatcher;
  123.         $this->orderItemQuantityModifier $orderItemQuantityModifier;
  124.         $this->translator $translator;
  125.         $this->orderItemManager $orderItemManager;
  126.         $this->promotionManager $promotionManager;
  127.         $this->logger $logger;
  128.     }
  129.     
  130.     /**
  131.      * @return OrderRepository|\Doctrine\ORM\EntityRepository
  132.      */
  133.     public function getRepository(){
  134.         return $this->em->getRepository($this->orderEntity);
  135.     }
  136.     
  137.     /**
  138.      * @param User $user
  139.      * @return Order|object
  140.      */
  141.     public function getCartOrder(?User $user)
  142.     {
  143.         return $this->getRepository()->findOneBy([
  144.             'user' => $user,
  145.             'state' => OrderInterface::STATE_CART,
  146.             'site' => $this->siteManager->getSite()
  147.         ]);
  148.     }
  149.     
  150.     /**
  151.      * @param User|\AppBundle\Entity\User $user
  152.      * @param bool $save
  153.      * @return Order|mixed|object
  154.      * @throws \Exception
  155.      */
  156.     public function getOrCreateCartOrder(User $user$save true){
  157.         /** @var Order $order */
  158.         $order $this->getCartOrder($user);
  159.         $site $this->siteManager->getSite();
  160.     
  161.         if(empty($order)) {
  162.             $order $this->orderFactory->createNew();
  163.             $order->setUser($user);
  164.             $setting $this->settingManager->findBySite($site);
  165.             $order->setTaxPercentage($setting->getTaxes());
  166.             $order->setSite($site);
  167.             if($save){
  168.                 $this->save($order);
  169.                 $order->generateNumber();
  170.                 $this->save($order);
  171.             }
  172.         }
  173.         
  174.         return $order;
  175.     }
  176.     
  177.     /**
  178.      * @param User $user
  179.      * @param ProductVariant $productVariant
  180.      * @param int $quantity
  181.      * @return OrderItem
  182.      * @throws \AWEcommerceBundle\Exception\OutOfStockException
  183.      */
  184.     public function addProductVariantToUser(User $userProductVariant $productVariant$quantity 1$customText null)
  185.     {
  186.         /** @var Order $order */
  187.         $order $this->getOrCreateCartOrder($user);
  188.         $this->eventDispatcher->dispatch(new OrderEvent($order), OrderEvent::POST_CREATED_EVENT);
  189.         $this->eventDispatcher->dispatch( new OrderEvent($order), OrderEvent::PRE_UPDATED_EVENT);
  190.         $this->orderItemManager->createOrderItem($order$productVariant$quantity$customText);
  191.         $this->eventDispatcher->dispatch(new OrderEvent($order), OrderEvent::POST_UPDATED_EVENT);
  192.         
  193.         return $order;
  194.     }
  195.     
  196.     public function updateOrderPackagingWeight(Order $order$flush true)
  197.     {
  198.         $site $order->getSite();
  199.         $setting $this->settingManager->findBySite($site);
  200.     
  201.         $weight 0;
  202.         /** @var OrderItem $item */
  203.         foreach ($order->getItems() as $item){
  204.             if($weight $item->getProduct()->getPackagingWeight()){
  205.                 $weight $item->getProduct()->getPackagingWeight();
  206.             }
  207.         }
  208.         
  209.         $weight = ($weight === and $setting) ? $setting->getDefaultPackagingWeight() : $weight;
  210.         $order->setPackagingWeight($weight);
  211.         if($flush) {
  212.             $this->save($order);
  213.         }
  214.     }
  215.     
  216.     
  217.     public function getOrdersByState(User $user$state)
  218.     {
  219.         return $this->getRepository()->findBy(['user' => $user'state' => $state]);
  220.     }
  221.     
  222.     public function save(Order $order){
  223.         $this->em->persist($order);
  224.         $this->em->flush();
  225.     }
  226.     
  227.     public function delete(Order $order){
  228.         $this->em->remove($order);
  229.         $this->em->flush();
  230.     }
  231.     
  232.     /**
  233.      * @param User $oldUser
  234.      * @param User|UserInterface $newUser
  235.      */
  236.     public function moveOrderToCustomer(User $oldUserUser $newUser)
  237.     {
  238.         $oldUserCart $this->getCartOrder($oldUser);
  239.         $newUserCart $this->getCartOrder($newUser);
  240.     
  241.         if($newUserCart)
  242.             $this->eventDispatcher->dispatch(OrderEvent::PRE_UPDATED_EVENT, new OrderEvent($newUserCart));
  243.     
  244.         if($oldUserCart and $newUserCart){
  245.             /** @var OrderItem $oldItem */
  246.             foreach ($oldUserCart->getItems() as $oldItem) {
  247.                 $added false;
  248.                 if(!$oldItem->getProduct()->isEditable()){
  249.                     /** @var OrderItem $newItem */
  250.                     foreach ($newUserCart->getItems() as $newItem) {
  251.                         if($newItem->getVariant()->getId() === $oldItem->getVariant()->getId()){
  252.                             $quantity $newItem->getQuantity() + $oldItem->getQuantity();
  253.                             $this->orderItemQuantityModifier->modify($newItem$quantity);
  254.                             $added true;
  255.                         }
  256.                     }
  257.                 }
  258.                 if(!$added){
  259.                     $oldItem->setOrder($newUserCart);
  260.                     $this->em->persist($oldItem);
  261.                 }
  262.             }
  263.             $this->em->remove($oldUserCart);
  264.             $this->em->flush();
  265.         }
  266.         
  267.         if($newUserCart)
  268.             $this->eventDispatcher->dispatch(OrderEvent::POST_UPDATED_EVENT, new OrderEvent($newUserCart));
  269.     
  270.         /** @var Order[] $orders */
  271.         $orders $this->getRepository()->findBy(['user' => $oldUser]);
  272.         foreach ($orders as $order) {
  273.             $order->setUser($newUser);
  274.             $this->save($order);
  275.         }
  276.     }
  277.     
  278.     /**
  279.      * @param Order $order
  280.      * @param bool $flush
  281.      */
  282.     public function setDefaultShipping(Order $order$flush true)
  283.     {
  284.         if ($order->getShippingMethod() == null OR ($order->getShippingMethod() != null AND
  285.                 ($order->getShippingMethod()->getMaxWeight() < $order->getTotalWeight() OR $order->getShippingMethod()->getMinWeight() > $order->getTotalWeight()))) {
  286.             $shippingMethod $this->shippingService->findFirstShipping($order->getTotalWeight(), $order->getUser()->getLocationCode());
  287.             if($shippingMethod){
  288.                 $order->setShippingMethod($shippingMethod);
  289.             }else{
  290.                 $order->setShippingMethod(null);
  291.             }
  292.             if($flush) {
  293.                 $this->save($order);
  294.             }
  295.         }
  296.     }
  297.     
  298.     public function reCalculate(Order $order$flush true): void
  299.     {
  300.         $this->setDefaultShipping($order$flush);
  301.         if($order->getShippingMethod()){
  302.             $countryCodeAlpha2 = ($order->getShippingAddress() and $order->getShippingAddress()->getCountryCode())
  303.                 ? $order->getShippingAddress()->getCountryCode()
  304.                 : $order->getUser()->getLocationCode();
  305.             $amount ceil($order->getShippingMethod()->getPriceByCountryCodeAlpha2($countryCodeAlpha2)) * 100;
  306.             /** @var Adjustment|null $shippingAdjustment */
  307.             $shippingAdjustment $order->getAdjustments(AdjustmentInterface::SHIPPING_ADJUSTMENT)->first();
  308.             if(!$shippingAdjustment OR $amount != $shippingAdjustment->getAmount()){
  309.                 $order->removeShippingAdjustment();
  310.                 $adjustment $this->adjustmentFactory->createNew();
  311.                 $adjustment->setType(AdjustmentInterface::SHIPPING_ADJUSTMENT);
  312.                 $adjustment->setAmount(ceil($order->getShippingMethod()->getPriceByCountryCodeAlpha2($countryCodeAlpha2)) * 100);
  313.                 $adjustment->setNeutral(false);
  314.                 $adjustment->setLabel('Shipping - '.$order->getShippingMethod()->getName());
  315.                 $order->addAdjustment($adjustment);
  316.             }
  317.         }
  318.     
  319.         $order->recalculateAdjustmentsTotal();
  320.         $order->calculateTotalItems();
  321.         $order->recalculateItemsTotal();
  322.     }
  323.     /**
  324.      * @param Order $order
  325.      * @return bool
  326.      */
  327.     public function generateBillingNumber(Order $order){
  328.         // FORMAT : F16-01-0001 -> FYY-MM-0001
  329.         if($order->getBillingNumber() != null OR $order->getState() != OrderInterface::STATE_CART){
  330.             return false;
  331.         }
  332.         /** @var Order $lastOrder */
  333.         $lastOrder $this->getRepository()->findLatest(1);
  334.         $lastOrder = (!empty($lastOrder)) ? $lastOrder[0] : null;
  335.         if ($lastOrder AND $lastOrder->getCheckoutCompletedAt() AND $lastOrder->getCheckoutCompletedAt()->format('y-m') == date('y-m')) {
  336.             $num = (int) substr($lastOrder->getBillingNumber(), -4);
  337.             $num++;
  338.         } else {
  339.             $num 1;
  340.         }
  341.         $num sprintf("%04d"$num);
  342.         $order->setBillingNumber('F' date('y-m') . '-' $num);
  343.         $order->setCheckoutCompletedAt(new \DateTime());
  344.         return true;
  345.     }
  346.     /**
  347.      * @param Order $order
  348.      */
  349.     public function newOrder(Order $order)
  350.     {
  351.         $this->generateBillingNumber($order);
  352.         if($order->getUser()->getBillingAddress()){
  353.             $billingAddress = clone $order->getUser()->getBillingAddress();
  354.         }
  355.         elseif($order->getUser()->getShippingAddress()){
  356.             $billingAddress = clone $order->getUser()->getShippingAddress();
  357.         }
  358.         else {
  359.             throw new \Exception("The user ".$order->getUser()->getEmail().' #'.$order->getUser()->getId().' don\'t have any address to finish the order !');
  360.         }
  361.         $shippingAddress = clone $order->getUser()->getShippingAddress();
  362.         $this->updateState($orderOrder::STATE_NEW);
  363.     
  364.         $order->setBillingAddress($billingAddress);
  365.         $order->setShippingAddress($shippingAddress);
  366.         /** @var Promotion $promotion */
  367.         $promotion $order->getPromotion();
  368.         if($promotion){
  369.             $promotion->setUsed($promotion->getUsed() + 1);
  370.             $this->em->persist($promotion);
  371.             $this->em->flush();
  372.         }
  373.         $this->save($order);
  374.     }
  375.     
  376.     public function updateState(Order $order$state){
  377.         $order->setState($state);
  378.         $this->eventDispatcher->dispatch(new OrderEvent($order), OrderEvent::STATE_CHANGED_EVENT);
  379.         $this->em->persist($order);
  380.         $this->em->flush();
  381.     }
  382.     public function updateShippingMethodFreeShipping(Order $orderShippingMethodInterface $shippingMethod)
  383.     {
  384.         if($shippingMethod->isEligibleFreeShipping() && $order->getTotalItems() >= $this->freeShippingPromotionActionCommand->getAmountForFreeShipping()){
  385.             $shippingMethod->setIsEligibleFreeShipping(true);
  386.         }else{
  387.             $shippingMethod->setIsEligibleFreeShipping(false);
  388.         }
  389.     }
  390.     
  391.     /**
  392.      * @param Order $order
  393.      */
  394.     protected function removeOrderWalletAdjustment(Order $order): void
  395.     {
  396.         foreach ($order->getAdjustments() as $adjustment) {
  397.             if($adjustment->getType() === AdjustmentInterface::WALLET_ADJUSTMENT){
  398.                 $adjustmentAmount $adjustment->getAmount();
  399.                 $order->getUser()->setWallet($order->getUser()->getWallet() + abs($adjustmentAmount));
  400.                 $order->removeAdjustment($adjustment);
  401.             }
  402.         }
  403.     }
  404.     
  405.     public function triggerUpdateEvent(ConsoleOutput $output null){
  406.     
  407.     
  408.         /** @var Order[] $orders */
  409.         $orders $this->getRepository()->findBy(['state' => OrderInterface::STATE_CART]);
  410.         
  411.         if($output){
  412.             $progressBar = new ProgressBar($outputcount($orders));
  413.         }
  414.         $count 0;
  415.     
  416.         foreach ($orders as $order){
  417.             if($order->getId() == 2281){
  418.                 $this->eventDispatcher->dispatch(OrderEvent::PRE_UPDATED_EVENT, new OrderEvent($order));
  419.                 $this->eventDispatcher->dispatch(OrderEvent::POST_UPDATED_EVENT, new OrderEvent($order));
  420.             }
  421.             if(isset($progressBar))
  422.                 $progressBar->advance();
  423. //
  424. //            $shippingMethod = $this->shippingService->findFirstShipping($order->getTotalWeight(), $order->getUser()->getLocationCode());
  425. //            if($shippingMethod){
  426. //                $order->setShippingMethod($shippingMethod);
  427. //            }
  428. //            $this->em->persist($order);
  429. //
  430. //            if($count % 50 === 0){
  431. //                $this->em->flush();
  432. //            }
  433. //            $count++;
  434. //
  435. //            if(isset($progressBar))
  436. //                $progressBar->advance();
  437.         }
  438.     }
  439.     
  440.     public function getOptionState(){
  441.         $stateOptions[''] = $this->translator->trans("front.account.orders.states.all");
  442.         foreach ($this->orderEntity::EDITABLE_STATES as $STATE){
  443.             $nb $this->getRepository()->countOrdersByStateAndSite($STATE$this->siteManager->getSite());
  444.             $stateOptions[$STATE] = $this->translator->trans("front.account.orders.states.$STATE")." ($nb)";
  445.         }
  446.         
  447.         return $stateOptions;
  448.     }
  449. }