src/Controller/IikoOrderController.php line 97

Open in your IDE?
  1. <?php
  2. namespace Slivki\Controller;
  3. use Doctrine\DBAL\Connection;
  4. use Doctrine\Persistence\ManagerRegistry;
  5. use libphonenumber\PhoneNumberUtil;
  6. use Slivki\BusinessFeature\OnlineOrder\Delivery\Service\YandexDeliveryCalculatorInterface;
  7. use Slivki\BusinessFeature\VirtualWallet\Service\VirtualWalletChecker;
  8. use Slivki\Dao\FastDelivery\OfferFastDeliveryDaoInterface;
  9. use Slivki\Dao\Offer\DeliveryZoneDaoInterface;
  10. use Slivki\Dao\Order\OfferOrderPurchaseCountDaoInterface;
  11. use Slivki\Entity\City;
  12. use Slivki\Entity\Director;
  13. use Slivki\Entity\EntityOption;
  14. use Slivki\Entity\FoodOfferExtension;
  15. use Slivki\Entity\FoodOfferOptionExtension;
  16. use Slivki\Entity\FoodOrder;
  17. use Slivki\Entity\GeoLocation;
  18. use Slivki\Entity\Media\OfferExtensionMedia;
  19. use Slivki\Entity\Offer;
  20. use Slivki\Entity\OfferExtension;
  21. use Slivki\Entity\OfferExtensionOnlineCategory;
  22. use Slivki\Entity\OfferExtensionVariant;
  23. use Slivki\Entity\OfferOrder;
  24. use Slivki\Entity\OfferOrderDetails;
  25. use Slivki\Entity\OnlineOrderHistory;
  26. use Slivki\Entity\PriceDeliveryType;
  27. use Slivki\Entity\Seo;
  28. use Slivki\Entity\Street;
  29. use Slivki\Entity\UserAddress;
  30. use Slivki\Entity\UserBalanceActivity;
  31. use Slivki\Entity\Visit;
  32. use Slivki\Enum\OfferCode\PurchaseCountPeriod;
  33. use Slivki\Enum\Order\PaymentType;
  34. use Slivki\Exception\Offer\OfferExtension\Visibility\OfferExtensionNotVisibleException;
  35. use Slivki\Exception\Order\InsufficientBalanceFundsException;
  36. use Slivki\Handler\Order\OnlineOrderHistoryHandler;
  37. use Slivki\Helpers\PhoneNumberHelper;
  38. use Slivki\Helpers\WeightParserHelper;
  39. use Slivki\Repository\Delivery\FoodFilterCounterRepositoryInterface;
  40. use Slivki\Repository\Director\DirectorRepositoryInterface;
  41. use Slivki\Repository\GeoLocation\GeoLocationRepositoryInterface;
  42. use Slivki\Repository\Offer\DeliveryZoneRepositoryInterface;
  43. use Slivki\Repository\Offer\FoodOfferExtensionRepositoryInterface;
  44. use Slivki\Repository\PurchaseCount\PurchaseCountRepositoryInterface;
  45. use Slivki\Repository\SeoRepository;
  46. use Slivki\Repository\StreetRepository;
  47. use Slivki\Repository\User\CreditCardRepositoryInterface;
  48. use Slivki\Services\ImageService;
  49. use Slivki\Services\Mailer;
  50. use Slivki\Services\MapProviders\CoordinatesYandex;
  51. use Slivki\Services\Offer\CustomProductOfferSorter;
  52. use Slivki\Services\Offer\DeliveryZoneSorter;
  53. use Slivki\Services\Offer\OfferCacheService;
  54. use Slivki\Services\Offer\ProductFastDeliveryService;
  55. use Slivki\Services\OfferExtension\FoodByOnlineCategoriesBuilder;
  56. use Slivki\Services\OfferExtension\VisibilityFilterService;
  57. use Slivki\Services\Order\PricePromocodeForOnlineOrder;
  58. use Slivki\Services\PartnerBePaidService;
  59. use Slivki\Services\Payment\PaymentService;
  60. use Slivki\Services\Seo\SeoResourceService;
  61. use Slivki\Services\ShippingSchedulerService;
  62. use Slivki\Services\Subscription\SubscriptionService;
  63. use Slivki\Services\User\UnusedOfferCodeProviderInterface;
  64. use Slivki\Util\CommonUtil;
  65. use Slivki\Util\Iiko\AbstractDelivery;
  66. use Slivki\Util\Iiko\Dominos;
  67. use Slivki\Util\Iiko\IikoUtil;
  68. use Slivki\Util\Iiko\SushiChefArts;
  69. use Slivki\Util\Iiko\SushiHouse;
  70. use Slivki\Util\Iiko\SushiVesla;
  71. use Slivki\Util\Logger;
  72. use Symfony\Component\DependencyInjection\ContainerInterface;
  73. use Symfony\Component\HttpFoundation\JsonResponse;
  74. use Symfony\Component\HttpFoundation\Request;
  75. use Symfony\Component\HttpFoundation\Response;
  76. use Symfony\Component\Routing\Annotation\Route;
  77. use function array_search;
  78. use function array_unshift;
  79. use function array_column;
  80. use function array_map;
  81. use function array_filter;
  82. use function in_array;
  83. use function is_subclass_of;
  84. use function count;
  85. use function array_key_exists;
  86. use function array_merge;
  87. class IikoOrderController extends SiteController
  88. {
  89.     private const KILOGRAM 1000;
  90.     public const NEARLY 'Ближайшее';
  91.     /** @Route("/delivery/select/{offerID}", name = "deliveryOrder") */
  92.     public function indexAction(
  93.         Request $request,
  94.         ContainerInterface $container,
  95.         FoodFilterCounterRepositoryInterface $foodFilterCounterRepository,
  96.         SeoResourceService $seoResourceService,
  97.         SubscriptionService $subscriptionService,
  98.         PurchaseCountRepositoryInterface $purchaseCountRepository,
  99.         OfferCacheService $offerCacheService,
  100.         DirectorRepositoryInterface $directorRepository,
  101.         OfferFastDeliveryDaoInterface $offerFastDeliveryDao,
  102.         $offerID
  103.     ) {
  104.         $response = new Response();
  105.         $entityManager $this->getDoctrine()->getManager();
  106.         /** @var Offer|false $offerCached */
  107.         $offerCached $offerCacheService->getOffer($offerIDtruetrue);
  108.         if (false === $offerCached
  109.             || !$offerCached->hasFreeCodes()
  110.             || !($offerCached->isFoodOnlineOrderAllowedOnSite() || $offerCached->isAvailableOnFood())) {
  111.             if (299624 != $offerID) { //TODO: remove after bepaid approve
  112.                 return $this->redirect($seoResourceService->getOfferSeo($offerID)->getMainAlias());
  113.             }
  114.         }
  115.         $orderUtil AbstractDelivery::instance($offerCached);
  116.         $orderUtil->setContainer($container);
  117.         $isDominos $orderUtil instanceof Dominos;
  118.         $isSushiHouse $orderUtil instanceof SushiHouse;
  119.         $data['isDominos'] = $isDominos;
  120.         $data['showSortingIndexOrder'] = !($isSushiHouse || $isDominos);
  121.         $cityID $entityManager->getRepository(Offer::class)->getCityID($offerID);
  122.         $city $entityManager->find(City::class, $cityID);
  123.         $request->getSession()->set(City::CITY_ID_SESSION_KEY$city->getID());
  124.         $request->getSession()->set(City::CITY_DOMAIN_SESSION_KEY$city->getDomain());
  125.         $data['offer'] = $offerCached;
  126.         Logger::instance('IIKO-DEBUG')->info($offerID);
  127.         $director $directorRepository->getById((int) $offerCached->getDirectorID());
  128.         $data['company'] = $director;
  129.         $data['domain'] = $orderUtil->getDomain();
  130.         if (null !== $offerCached->getOnlineOrderSettings() && $offerCached->getOnlineOrderSettings()->getDomain()) {
  131.             $data['domain'] = $offerCached->getOnlineOrderSettings()->getDomain();
  132.         }
  133.         $data['dishes'] = [];
  134.         $user $this->getUser();
  135.         if (null !== $user) {
  136.             if ($subscriptionService->isSubscriber($user)) {
  137.                 $data['allowedCodesToBuy'] = $subscriptionService->getSubscription($user)->getNumberOfCodes();
  138.             } elseif ($user->isBatchCodesAllowed()) {
  139.                 $data['allowedCodesToBuyBatchCodes'] = $user->getBatchCodesCount();
  140.             }
  141.         }
  142.         $codeCost $this->getOfferRepository()->getCodeCost($offerCached);
  143.         $data['options'] = [];
  144.         $data['robotsMeta'] = 'noindex, follow';
  145.         $data['offerID'] = $offerID;
  146.         $data['director'] = $director;
  147.         $data['minSumForFreeDelivery'] = $orderUtil->getMinSumForFreeDelivery();
  148.         $data['minOrderSum'] = $orderUtil->getMinOrderSum();
  149.         $data['foodOffer'] = true;
  150.         $data['formAction'] = '/delivery/order/checkout';
  151.         $data['showDelivery'] = true;
  152.         $data['categoryName'] = $orderUtil::CATEGORY_NAME;
  153.         $data['footerOfferConditionID'] = $offerID;
  154.         $data['categoryURL'] = $entityManager->getRepository(Seo::class)->getSeoForEntity(SeoRepository::RESOURCE_URL_OFFER_CATEGORY$orderUtil::CATEGORY_ID)->getMainAlias();
  155.         $data['deliveryPrice'] = $orderUtil->getDeliveryPriceSettings();
  156.         $data['pickupEnabled'] = $orderUtil->isPickupEnabled();
  157.         $data['deliveryEnabled'] = $orderUtil->isDeliveryEnabled();
  158.         $data['isBuyCodeDisable'] = $offerCached->isBuyCodeDisable();
  159.         $data['isOnlineOrderAllowed'] = $offerCached->isFoodOnlineOrderAllowedOnSite();
  160.         $data['isAvailableOnFood'] = $offerCached->isAvailableOnFood();
  161.         $data['visitCount'] = $entityManager->getRepository(Visit::class)->getVisitCount($orderUtil::OFFER_IDVisit::TYPE_OFFER30true);
  162.         $data['filterAction'] = $foodFilterCounterRepository->findByOfferId((int) $offerID);
  163.         $purchaseCount $purchaseCountRepository->findByOfferId((int) $offerID);
  164.         $data['purchaseCountMonth'] = null === $purchaseCount $purchaseCount->getPurchaseCountLastMonthWithCorrection();
  165.         $data['sortList'] = CustomProductOfferSorter::SORT_LIST;
  166.         $data['codeCost'] = $codeCost;
  167.         if (!$offerFastDeliveryDao->isOfferHasActiveFastDelivery($offerID)) {
  168.             unset($data['sortList'][CustomProductOfferSorter::FAST_CUSTOM_PRODUCT_SORT]);
  169.         }
  170.         $view CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/delivery/order.html.twig' 'Slivki/delivery/order.html.twig';
  171.         $response->setContent($this->renderView($view$data));
  172.         return $response;
  173.     }
  174.     /** @Route("/delivery/order/checkout", name = "deliveryOrderCheckout") */
  175.     public function checkoutAction(
  176.         Request $request,
  177.         ShippingSchedulerService $shippingSchedulerService,
  178.         ContainerInterface $container,
  179.         ManagerRegistry $registry,
  180.         SeoResourceService $seoResourceService,
  181.         SubscriptionService $subscriptionService,
  182.         DeliveryZoneDaoInterface $deliveryZoneDao,
  183.         DeliveryZoneSorter $deliveryZoneSorter,
  184.         PricePromocodeForOnlineOrder $pricePromocodeForOnlineOrder,
  185.         DeliveryZoneRepositoryInterface $deliveryZoneRepository
  186.     ) {
  187.         ini_set('memory_limit''1g');
  188.         $additionalDominos null;
  189.         $response = new Response();
  190.         $offerID $request->request->getInt('offerID');
  191.         $entityManager $this->getDoctrine()->getManager();
  192.         $requestBasket $request->request->get('basket');
  193.         $pickupDeliveryType = empty($request->request->get('pickupDeliveryType')) ? FoodOfferExtension::DELIVERY_METHOD $request->request->getInt('pickupDeliveryType');
  194.         if (!$requestBasket) {
  195.             return $this->redirectToRoute('deliveryOrder', ['offerID' => $offerID]);
  196.         }
  197.         $request->getSession()->set(OnlineOrderHistory::SORT_SESSION_NAME$request->request->get('dishSortBy'));
  198.         /** @var Offer $offer */
  199.         $offer $entityManager->find(Offer::class, $offerID);
  200.         $slivkiDeliveryOption $entityManager->getRepository(EntityOption::class)->findBy([
  201.             'entityID' => $offerID,
  202.             'name' => EntityOption::OPTION_SLIVKI_DELIVERY
  203.         ]);
  204.         if (!$offer->hasFreeCodes()) {
  205.             return $this->redirect($seoResourceService->getOfferSeo($offerID)->getMainAlias());
  206.         }
  207.         $iikoUtil AbstractDelivery::instance($offer);
  208.         $iikoUtil->setContainer($container);
  209.         $isSushiVesla $iikoUtil instanceof SushiVesla;
  210.         $isDominos $iikoUtil instanceof Dominos;
  211.         if ($isDominos) {
  212.             $dominosSpesialData = [
  213.                 'amountPizza' => 0,
  214.             ];
  215.         }
  216.         $requestBasket json_decode($requestBaskettrue);
  217.         $basket = [];
  218.         foreach ($requestBasket as $basketItem) {
  219.             $key array_key_first($basketItem);
  220.             $variants = [];
  221.             if (is_array($basketItem[$key])) {
  222.                 foreach ($basketItem[$key] as $variantItem) {
  223.                     $variantKey array_key_first($variantItem);
  224.                     $variants[$variantKey] = $variantItem[$variantKey];
  225.                 }
  226.             } else {
  227.                 $variants $basketItem[$key];
  228.             }
  229.             $basket[$key] = $variants;
  230.         }
  231.         $totalDishCount 0;
  232.         foreach ($basket as $dishID => $variants) {
  233.             $extension $entityManager->find(OfferExtension::class, $dishID);
  234.             if (!$extension || $extension instanceof FoodOfferOptionExtension) {
  235.                 continue;
  236.             }
  237.             $dishCount 0;
  238.             if (!is_array($variants)) {
  239.                 $dishCount $variants;
  240.             } else {
  241.                 foreach ($variants as $variantID => $variantCount) {
  242.                     $extensionVariant $entityManager->find(OfferExtensionVariant::class, $variantID);
  243.                     if (!$extensionVariant) {
  244.                         continue;
  245.                     }
  246.                     $dishCount += $variantCount;
  247.                     
  248.                     if ($isDominos) {
  249.                         $dominosSpesialData['amountPizza'] += $variantCount;
  250.                     }
  251.                 }
  252.             }
  253.             $totalDishCount += $dishCount;
  254.         }
  255.         
  256.         if ($isDominos && $dominosSpesialData['amountPizza'] === 0) {
  257.             return new JsonResponse(['status' => 'error''error' => true'message' => 'Скидка на доп. меню действует только при заказе пиццы']);
  258.         }
  259.         if ($totalDishCount == 0) {
  260.             return $this->redirectToRoute('deliveryOrder', ['offerID' => $offerID]);
  261.         }
  262.         $user $this->getUser();
  263.         /** @var OfferOrder $order */
  264.         $order = new FoodOrder();
  265.         $order->setUser($user);
  266.         $order->setStatus(FoodOrder::STATUS_INIT);
  267.         $order->setOffer($offer);
  268.         $totalAmount 0;
  269.         $totalOfferAmount 0;
  270.         $codesCount 0;
  271.         $city $entityManager->find(City::class, $iikoUtil::CITY_ID);
  272.         $request->getSession()->set(City::CITY_ID_SESSION_KEY$city->getID());
  273.         $request->getSession()->set(City::CITY_DOMAIN_SESSION_KEY$city->getDomain());
  274.         $offersDetails = [];
  275.         foreach ($basket as $dishID => $variants) {
  276.             /** @var OfferExtension $extension */
  277.             $extension $entityManager->find(OfferExtension::class, $dishID);
  278.             if (!$extension) {
  279.                 continue;
  280.             }
  281.             if (is_array($variants)) {
  282.                 foreach ($variants as $variantID => $variantCount) {
  283.                     /** @var OfferExtensionVariant $extensionVariant */
  284.                     $extensionVariant $entityManager->find(OfferExtensionVariant::class, $variantID);
  285.                     if (!$extensionVariant) {
  286.                         continue;
  287.                     }
  288.                     $productsPerCode $extension->getProductsPerCode();
  289.                     if ($productsPerCode 0) {
  290.                         $codesCount += $productsPerCode == $variantCount $variantCount/$productsPerCode;
  291.                     }
  292.                     $variantOfferPrice PriceDeliveryType::calcDeliveryPickupPrice(
  293.                         $extension,
  294.                         $pickupDeliveryType,
  295.                         $extensionVariant->getRegularPrice(),
  296.                         $extensionVariant->getOfferPrice(),
  297.                         $additionalDominos
  298.                     );
  299.                     $totalOfferAmount += $variantCount $variantOfferPrice;
  300.                     $totalAmount += $variantCount $extensionVariant->getRegularPrice();
  301.                     $details = new OfferOrderDetails();
  302.                     $details->setOfferExtension($extension);
  303.                     $details->setOfferExtensionVariant($extensionVariant);
  304.                     $details->setItemsCount($variantCount);
  305.                     $order->addOfferOrderDetails($details);
  306.                 }
  307.             } else {
  308.                 $count = (int) $variants;
  309.                 if (=== $count) {
  310.                     continue;
  311.                 }
  312.                 $product $isSushiVesla
  313.                     $iikoUtil->getProductByDB($extension->getPartnerItemID(), $registry)
  314.                     : $iikoUtil->getProduct($extension->getPartnerItemID());
  315.                 if ($product->regularPrice == 0) {
  316.                     $product->regularPrice $extension->getPrice();
  317.                 }
  318.                 $totalAmount += $count $product->regularPrice;
  319.                 $recalculatedOfferPriceValue PriceDeliveryType::calcDeliveryPickupPrice(
  320.                     $extension,
  321.                     $pickupDeliveryType,
  322.                     $product->regularPrice,
  323.                     $extension->getCurrentPrice(null$pickupDeliveryType),
  324.                 );
  325.                 $product->offerPrice $recalculatedOfferPriceValue;
  326.                 $totalOfferAmount += $count $product->offerPrice;
  327.                 if (!$extension instanceof FoodOfferOptionExtension) {
  328.                     $productsPerCode $extension->getProductsPerCode();
  329.                     if ($productsPerCode 0) {
  330.                         $codesCount += $productsPerCode == $count $count/$productsPerCode;
  331.                     }
  332.                 }
  333.                 $details = new OfferOrderDetails();
  334.                 $details->setOfferExtension($extension);
  335.                 $details->setItemsCount($count);
  336.                 $order->addOfferOrderDetails($details);
  337.             }
  338.         }
  339.         $codesCount = \ceil($codesCount);
  340.         $totalAmountWithoutCode $totalOfferAmount;
  341.         $codeCost $pricePromocodeForOnlineOrder->getPrice($order$offer$codesCount$totalAmountWithoutCode);
  342.         $codeCostRegular $codeCost;
  343.         $user $order->getUser();
  344.         $allowedCodesToBuyBalance false;
  345.         if ($subscriptionService->isSubscriber($user) || $user->isBatchCodesAllowed()) {
  346.             $codeCost 0;
  347.         } elseif ($user->isBalanceAllowed($codesCount $codeCost)) {
  348.             $codeCost 0;
  349.             $allowedCodesToBuyBalance true;
  350.         }
  351.         $totalOfferAmount += $codesCount $codeCost;
  352.         $order->setCodesCount($codesCount);
  353.         $order->setCodeCost($codeCostRegular);
  354.         $deliveryPrice $iikoUtil->getMinSumForFreeDelivery() > && $totalAmountWithoutCode $iikoUtil->getMinSumForFreeDelivery() ? $iikoUtil->getDeliveryPriceSettings() : 0;
  355.         // Delivery price will be calculated after choosing the address
  356.         if (null !== $offer->getOfferDeliveryZone() && $offer->getOfferDeliveryZone()->count() > 0) {
  357.             $deliveryPrice 0;
  358.         }
  359.         if ($pickupDeliveryType === FoodOfferExtension::DELIVERY_METHOD_PICKUP) {
  360.             $deliveryPrice 0;
  361.         }
  362.         $order->setAmount($totalOfferAmount $deliveryPrice);
  363.         $order->setDeliveryCost($deliveryPrice);
  364.         if (CommonUtil::isMobileDevice($request)) {
  365.             $order->setDeviceType(SiteController::DEVICE_TYPE_MOBILE);
  366.         } else {
  367.             $order->setDeviceType(SiteController::DEVICE_TYPE_DESKTOP);
  368.         }
  369.         $entityManager->persist($order);
  370.         $entityManager->flush();
  371.         $entityManager->detach($order);
  372.         $deliveryAddresses $user->getAvailableUserAddresses($offerID);
  373.         $defaultDeliveryAddress = empty($deliveryAddresses) ? false $deliveryAddresses[0];
  374.         $deliveryAddressesGift $user->getAvailableUserAddressesGift($offerID);
  375.         if ($order->isOnlineGift()) {
  376.             $defaultDeliveryAddress $deliveryAddressesGift[0] ?? false;
  377.             $deliveryAddresses $deliveryAddressesGift;
  378.         }
  379.         $brandboxEnabled $offer->getBrandboxEnabled();
  380.         $deliveryEnabled $iikoUtil->isDeliveryEnabled();
  381.         $pickupEnabled $iikoUtil->isPickupEnabled();
  382.         $isAjaxScheduleForDelivery false;
  383.         $schedule $shippingSchedulerService->getEmptySchedule($iikoUtil$pickupDeliveryType);
  384.         if (
  385.             ($brandboxEnabled && $pickupDeliveryType === FoodOfferExtension::DELIVERY_METHOD && $deliveryAddresses) ||
  386.             (!$brandboxEnabled && $deliveryEnabled && $deliveryAddresses)
  387.         ) {
  388.             $schedule $shippingSchedulerService->getDeliverySchedule($iikoUtil$pickupDeliveryType);
  389.         }
  390.         $citySelect '';
  391.         $citySelectData $iikoUtil->getCitySelectData($entityManager);
  392.         if ($citySelectData) {
  393.             $citySelect $this->renderView(CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/delivery/city_select.html.twig'
  394.                 'Slivki/delivery/city_select.html.twig', ['deliveryLocations' => $citySelectData]);
  395.         }
  396.         $workHourFrom 0;
  397.         $workHourTo 0;
  398.         $pickupLocations '';
  399.         $defaultLocationID null;
  400.         /** @var GeoLocation $geoLocation */
  401.         foreach ($offer->getGeoLocations() as $geoLocation) {
  402.             if (!$geoLocation->isActive()) {
  403.                 continue;
  404.             }
  405.             if (!$defaultLocationID) {
  406.                 $defaultLocationID $geoLocation->getID();
  407.             }
  408.             $pickupPointScheduleParsed $geoLocation->getPickupPointScheduleParsed();
  409.             if (!$pickupPointScheduleParsed) {
  410.                 continue;
  411.             }
  412.             $pickupLocations .= $this->renderView('Slivki/delivery/pickup_location_item.html.twig', [
  413.                 'location' => $geoLocation,
  414.             ]);
  415.         }
  416.         $nearestTime 'Ближайшее';
  417.         $deliveryTimeFrom $iikoUtil->getDeliveryTimeFrom();
  418.         $deliveryTimeTill $iikoUtil->getDeliveryTimeTill();
  419.         $additionalDominos = !(null === $additionalDominos);
  420.         $this->reCalcOrder(
  421.             $order,
  422.             0,
  423.             $pickupDeliveryType,
  424.             $subscriptionService->isSubscriber($this->getUser()),
  425.             $pricePromocodeForOnlineOrder
  426.         );
  427.         $data = [
  428.             'order' => $order,
  429.             'offer' => $offer,
  430.             'codeCost' => $codeCost,
  431.             'codeCostRegular' => $codeCostRegular,
  432.             'deliveryPrice' => $deliveryPrice,
  433.             'offerURL' => $entityManager->getRepository(Seo::class)->getOfferURL($offer->getID())->getMainAlias(),
  434.             'totalAmount' => $totalAmount $deliveryPrice,
  435.             'director' => $offer->getDirectors()->first(),
  436.             'robotsMeta' => 'noindex, follow',
  437.             'offerID' => $offerID,
  438.             'showCheckAddressButton' => $iikoUtil::SHOW_CHECK_ADDRESS_BUTTON,
  439.             'streetSuggest' => $iikoUtil::STREET_SUGGEST,
  440.             'workHourFrom' => $workHourFrom,
  441.             'workHourTo' => $workHourTo,
  442.             'citySelect' => $citySelect,
  443.             'multipleLocationDelivery' => $iikoUtil::MULTIPLE_LOCATIONS_DELIVERY,
  444.             'formAction' => '/delivery/order/check-payment',
  445.             'categoryName' => $iikoUtil::CATEGORY_NAME,
  446.             'categoryURL' => $entityManager->getRepository(Seo::class)->getSeoForEntity(SeoRepository::RESOURCE_URL_OFFER_CATEGORY$iikoUtil::CATEGORY_ID)->getMainAlias(),
  447.             'pickupLocations' => $pickupLocations,
  448.             'nearestTimeLabel' => $nearestTime,
  449.             'showDelivery' => true,
  450.             'defaultLocationID' => $defaultLocationID,
  451.             'pickupEnabled' => $pickupEnabled,
  452.             'deliveryEnabled' => $deliveryEnabled,
  453.             'allowedPaymentMethods' => $iikoUtil->getAllowedPaymentMethods(),
  454.             'footerOfferConditionID' => $offerID,
  455.             'pickupDiscount' => $iikoUtil->getPickupDiscount(),
  456.             'pickupDeliveryType' => $pickupDeliveryType,
  457.             'deliveryTimeFrom' => $deliveryTimeFrom,
  458.             'deliveryTimeTill' => $deliveryTimeTill,
  459.             'orderPeriodInDays' => $iikoUtil->getOrderPeriodInDays(),
  460.             'offersDetails' => $offersDetails,
  461.             'schedule' => $schedule,
  462.             'deliveryAddresses' => $deliveryAddresses,
  463.             'deliveryAddressesGift' => $deliveryAddressesGift,
  464.             'defaultDeliveryAddress' => $defaultDeliveryAddress,
  465.             'brandboxEnabled' => $brandboxEnabled,
  466.             'additionalDominos' => $additionalDominos,
  467.             'isSushiVesla' => $isSushiVesla,
  468.             'isDominos' => $isDominos,
  469.             'isAjaxScheduleForDelivery' => $isAjaxScheduleForDelivery,
  470.             'isOnlineGift' => $offer->isOnlineOrderGiftEnabled(),
  471.             'allowedCodesToBuyBalance' => $allowedCodesToBuyBalance,
  472.             'deliveryZones' => $deliveryZoneSorter->sortByDefault($deliveryZoneDao->findByOfferId($offerID)),
  473.             'offerForSlivkiDelivery' => $slivkiDeliveryOption,
  474.             'isDeliveryZoneAvailable' => $deliveryZoneRepository->existsForOffer($offer->getID()),
  475.         ];
  476.         $data['iikoOrder'] = true;
  477.         $view CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/delivery/delivery_checkout.html.twig' 'Slivki/delivery/delivery_checkout.html.twig';
  478.         $content $this->renderView($view$data);
  479.         $response->setContent($content);
  480.         $response->headers->addCacheControlDirective('no-cache'true);
  481.         $response->headers->addCacheControlDirective('max-age'0);
  482.         $response->headers->addCacheControlDirective('must-revalidate'true);
  483.         $response->headers->addCacheControlDirective('no-store'true);
  484.         return $response;
  485.     }
  486.     /**
  487.      * @Route("/delivery/order/payment/{orderID}", name="delivery_order_payment")
  488.      */
  489.     public function deliveryOrderPaymentAction(
  490.         Request $request,
  491.         PartnerBePaidService $partnerBePaidService,
  492.         OnlineOrderHistoryHandler $onlineOrderHistoryHandler,
  493.         SubscriptionService $subscriptionService,
  494.         CreditCardRepositoryInterface $creditCardRepository,
  495.         DirectorRepositoryInterface $directorRepository,
  496.         VirtualWalletChecker $virtualWalletChecker,
  497.         PricePromocodeForOnlineOrder $pricePromocodeForOnlineOrder,
  498.         UnusedOfferCodeProviderInterface $unusedOfferCodeProvider,
  499.         $orderID
  500.     ) {
  501.         $entityManager $this->getDoctrine()->getManager();
  502.         $response = new Response();
  503.         /** @var FoodOrder $order */
  504.         $order $entityManager->find(FoodOrder::class, $orderID);
  505.         if (!$order) {
  506.             throw $this->createNotFoundException();
  507.         }
  508.         $user $order->getUser();
  509.         $offer $order->getOffer();
  510.         $offerID $offer->getID();
  511.         $iikoUtil IikoUtil::instance($offer);
  512.         $iikoUtil->setContainer($this->kernel->getContainer());
  513.         $isPickup $order->getDeliveryAddress()->isPickup();
  514.         $detailIdCount = [];
  515.         $totalAmount 0;
  516.         foreach ($order->getOfferOrderDetails() as $details) {
  517.             $extension $details->getOfferExtension();
  518.             if ($iikoUtil instanceof SushiHouse) {
  519.                 if (isset($detailIdCount[$extension->getID()])) {
  520.                     $detailIdCount[$extension->getID()] += $details->getItemsCount();
  521.                 } else {
  522.                     $detailIdCount[$extension->getID()] = $details->getItemsCount();
  523.                 }
  524.             }
  525.             $variant $details->getOfferExtensionVariant();
  526.             $regularPrice $variant $variant->getRegularPrice() : $details->getOfferExtension()->getPrice();
  527.             $totalAmount += $details->getItemsCount() * $regularPrice;
  528.             $sortByFromDelivery $request->getSession()->get(OnlineOrderHistory::SORT_SESSION_NAME);
  529.             if (null !== $sortByFromDelivery) {
  530.                 $onlineOrderHistoryHandler->handle(
  531.                     $order,
  532.                     $extension->getID(),
  533.                     $sortByFromDelivery
  534.                 );
  535.             }
  536.         }
  537.         $request->getSession()->set(OnlineOrderHistory::SORT_SESSION_NAMEnull);
  538.         $pickupDeliveryType $isPickup FoodOfferExtension::DELIVERY_METHOD_PICKUP FoodOfferExtension::DELIVERY_METHOD;
  539.         $deliveryCost 0;
  540.         if ($pickupDeliveryType === FoodOfferExtension::DELIVERY_METHOD || !$isPickup) {
  541.             $totalAmount += $order->getDeliveryCost();
  542.             $deliveryCost $order->getDeliveryCost();
  543.         }
  544.         $codeCost $order->getCodeCost();
  545.         $regularCodeCost $codeCost;
  546.         $allowedCodesToBuyBalance false;
  547.         if ($subscriptionService->isSubscriber($user) || $user->isBatchCodesAllowed()) {
  548.             $codeCost 0;
  549.         } elseif ($user->isBalanceAllowed($codeCost $order->getCodesCount())) {
  550.             $codeCost 0;
  551.             $allowedCodesToBuyBalance true;
  552.         }
  553.         $partnerBePaidService->setOrder($order);
  554.         $paymentToken $partnerBePaidService->getPaymentToken($ordernull$codeCost);
  555.         $view CommonUtil::isMobileDevice($request)
  556.             ? 'Slivki/mobile/delivery/delivery_payment.html.twig'
  557.             'Slivki/delivery/delivery_payment.html.twig';
  558.         $offersDetails = [];
  559.         $director $directorRepository->findById($offer->getDirectorID());
  560.         $fullOrderAmount $order->getAmount();
  561.         if ($allowedCodesToBuyBalance) {
  562.             $fullOrderAmount += $regularCodeCost $order->getCodesCount();
  563.         }
  564.         $this->reCalcOrder(
  565.             $order,
  566.             0,
  567.             $pickupDeliveryType,
  568.             $subscriptionService->isSubscriber($this->getUser()),
  569.             $pricePromocodeForOnlineOrder
  570.         );
  571.         $content =  $this->renderView($view, [
  572.             'order' => $order,
  573.             'offer' => $offer,
  574.             'offerURL' => $entityManager->getRepository(Seo::class)->getOfferURL($offerID)->getMainAlias(),
  575.             'offerID' => $offerID,
  576.             'categoryName' => $iikoUtil::CATEGORY_NAME,
  577.             'deliveryPrice' => $deliveryCost,
  578.             'codeCost' => $codeCost,
  579.             'totalAmount' => $totalAmount,
  580.             'showCheckAddressButton' => false,
  581.             'categoryURL' => $entityManager->getRepository(Seo::class)->getSeoForEntity(SeoRepository::RESOURCE_URL_OFFER_CATEGORY$iikoUtil::CATEGORY_ID)->getMainAlias(),
  582.             'isPickup' => $isPickup,
  583.             'allowedPaymentMethods' => $iikoUtil->getAllowedPaymentMethods()[$isPickup 'pickup' 'delivery'],
  584.             'pickupDiscount' => $isPickup $iikoUtil->getPickupDiscount() : 0,
  585.             'pickupDeliveryType' => $pickupDeliveryType,
  586.             'paymentToken' => $paymentToken['checkout']['token'],
  587.             'offersDetails' => $offersDetails,
  588.             'additionalDominos' => false,
  589.             'isDominos' => $iikoUtil instanceof Dominos,
  590.             'activeCreditCards' => !$offer->isRecurrentDisabled() ? $creditCardRepository->findActiveByUser($user) : [],
  591.             'directorName' => $director instanceof Director $director->getName() : '',
  592.             'allowedCodesToBuyBalance' => $allowedCodesToBuyBalance,
  593.             'isSlivkiPayAllowed' => $virtualWalletChecker->availableSlivkiPay($fullOrderAmount$user),
  594.             'allowedCashbackSumToPay' => $iikoUtil->getAllowedCashbackSumToPay($order$entityManager),
  595.             'allowedFastDeliveryForSushiHouse' => $iikoUtil->enabledFastDelivery($order),
  596.             'unusedCodes' => $unusedOfferCodeProvider->getUnusedOfferCode($order$offer$user),
  597.         ]);
  598.         $response->setContent($content);
  599.         return $response;
  600.     }
  601.     /** @Route("/delivery/order/check-payment", name = "deliveryOrderCheckPayment") */
  602.     public function checkPaymentAction(
  603.         Request $request,
  604.         CoordinatesYandex $coordinatesYandex,
  605.         DeliveryZoneRepositoryInterface $deliveryZoneRepository,
  606.         ShippingSchedulerService $shippingSchedulerService,
  607.         SubscriptionService $subscriptionService,
  608.         PhoneNumberUtil $phoneNumberUtil,
  609.         PhoneNumberHelper $phoneNumberHelper,
  610.         PricePromocodeForOnlineOrder $pricePromocodeForOnlineOrder,
  611.         VisibilityFilterService $visibilityFilterService,
  612.         YandexDeliveryCalculatorInterface $yandexDeliveryCalculator,
  613.         GeoLocationRepositoryInterface $geoLocationRepository
  614.     ) {
  615.         if (!$request->isMethod(Request::METHOD_POST)) {
  616.             throw $this->createNotFoundException();
  617.         }
  618.         $entityManager $this->getDoctrine()->getManager();
  619.         $orderID $request->request->getInt('orderID');
  620.         $pickupDeliveryType $request->request->get('pickupDeliveryType');
  621.         $pickupDeliveryType $pickupDeliveryType ? (int) $pickupDeliveryType null;
  622.         $isOnlineOrderGift $request->request->getBoolean('isOnlineGift');
  623.         $discount 0;
  624.         /** @var FoodOrder $order */
  625.         $order $entityManager->find(FoodOrder::class, $orderID);
  626.         if (!$order || $order->getUser()->getID() != $this->getUser()->getID() || $order->getStatus() != FoodOrder::STATUS_INIT) {
  627.             throw $this->createNotFoundException();
  628.         }
  629.         $order->setComment($request->request->get('comment'));
  630.         $order->setDeliveryTime($request->request->get('deliveryTime'));
  631.         $order->setIsOnlineGift($isOnlineOrderGift);
  632.         $iikoUtil IikoUtil::instance($order->getOffer());
  633.         $iikoUtil->setContainer($this->kernel->getContainer());
  634.         $possibilityOrder $iikoUtil->getPossibilityOrderStatus($order);
  635.         if ($possibilityOrder['status'] === 'error') {
  636.             return new JsonResponse(['status' => 'error''error' => true'message' => $possibilityOrder['message']]);
  637.         }
  638.         $isSushiHouse $iikoUtil instanceof SushiHouse;
  639.         $isSushiVesla $iikoUtil instanceof SushiVesla;
  640.         if (!$isSushiHouse && !$isSushiVesla) {
  641.             $this->reCalcOrder(
  642.                 $order,
  643.                 0,
  644.                 $pickupDeliveryType,
  645.                 $subscriptionService->isSubscriber($this->getUser()),
  646.                 $pricePromocodeForOnlineOrder
  647.             );
  648.         }
  649.         $request->getSession()->set("pickupDiscount"null);
  650.         if ($request->request->has('pickup')) {
  651.             $addressID $request->request->getInt('pickupAddressID');
  652.             $discount $request->request->getInt('pickupDiscount');
  653.             $request->getSession()->set("pickupDiscount"$discount);
  654.             $geoLocation $entityManager->find(GeoLocation::class, $addressID);
  655.             $userAddresses $entityManager->getRepository(UserAddress::class)->findBy(['user' => $this->getUser(), 'geoLocation' => $geoLocation]);
  656.             $address null;
  657.             foreach ($userAddresses as $location) {
  658.                 if ($location->getGeoLocation()->getID() == $addressID) {
  659.                     $address $location;
  660.                     break;
  661.                 }
  662.             }
  663.             if (!$address) {
  664.                 $address = new UserAddress();
  665.                 $address->setUser($this->getUser());
  666.                 $address->setGeoLocation($geoLocation);
  667.                 $address->setOfferID($order->getOffer()->getID());
  668.                 $entityManager->persist($address);
  669.             }
  670.             $address->setPickup(true);
  671.         } else {
  672.             $address $entityManager->find(UserAddress::class, $request->request->getInt('addressID'));
  673.             $geoLocation null;
  674.         }
  675.         if ($address) {
  676.             $name $request->request->get('name''');
  677.             $phone $request->request->get('phone''');
  678.             if (trim($name) == '' || trim($phone) == '') {
  679.                 return new JsonResponse(['error' => true]);
  680.             }
  681.             if (\mb_strlen($phone) > 0) {
  682.                 $phoneNumberObject $phoneNumberUtil->parse($phone);
  683.                 if (!$phoneNumberUtil->isValidNumber($phoneNumberObject)) {
  684.                     return new JsonResponse(['error' => true'message' => 'Введен некорректный номер телефона']);
  685.                 }
  686.             }
  687.             $address->setPhone($phone);
  688.             $address->setName($name);
  689.             $address->setIsOnlineGift($isOnlineOrderGift);
  690.             if ($isOnlineOrderGift) {
  691.                 $address->setNameGift($request->request->get('nameGift'));
  692.                 $address->setPhoneNumberGift(
  693.                     $phoneNumberHelper->convert($request->request->get('phoneNumberGift'), ''),
  694.                 );
  695.             }
  696.             $order->setDeliveryAddress($address);
  697.         } else {
  698.             return new JsonResponse(['error' => true'message' => 'Не выбран адрес']);
  699.         }
  700.         $result $iikoUtil->checkOrder($entityManager$order$subscriptionService);
  701.         if (!$result || $result->resultState 0) {
  702.             $message null;
  703.             if ($result) {
  704.                 switch ($result->resultState) {
  705.                     case 1:
  706.                         if (isset($result->problem)) {
  707.                             $message $result->problem;
  708.                         }
  709.                         if (isset($result->minSumForFreeDelivery)) {
  710.                             $message = \sprintf('Минимальная сумма заказа %s руб.', (string) $result->minSumForFreeDelivery);
  711.                         }
  712.                         break;
  713.                     case 2:
  714.                         $message 'Извините, в данное время заказ невозможен. Пожалуйста, выберите другое время';
  715.                         break;
  716.                     case 3:
  717.                         $message 'Извините, на данный адрес доставка не осуществляется';
  718.                         break;
  719.                     case 4:
  720.                     case 5:
  721.                         $message 'На данный момент заказ одного из товаров невозможен';
  722.                         break;
  723.                     case 9999:
  724.                         $message 'Заказы принимаются с 11:00 по 22:20';
  725.                         break;
  726.                 }
  727.             }
  728.             return new JsonResponse(['error' => true'message' => $message]);
  729.         }
  730.         try {
  731.             $visibilityFilterService->assertAllVisibleOrFail(array_map(
  732.                 static fn (OfferOrderDetails $orderDetail) => $orderDetail->getOfferExtension(),
  733.                 $order->getOfferOrderDetails()->toArray(),
  734.             ));
  735.         } catch (OfferExtensionNotVisibleException $e) {
  736.             return new JsonResponse(['error' => true'message' => $e->getMessage()]);
  737.         }
  738.         if ($request->request->get('deliveryTime') !== self::NEARLY) {
  739.             if ($request->request->get('deliveryTime') === null) {
  740.                 $checkSchedule = [
  741.                     'status' => 'error',
  742.                     'message' => 'Выберите время',
  743.                 ];
  744.             } else {
  745.                 $checkSchedule $iikoUtil->checkSchedule($shippingSchedulerService$geoLocation$entityManager$pickupDeliveryType$request->request->get('deliveryTime'));
  746.             }
  747.             if ($checkSchedule['status'] === 'error') {
  748.                 return new JsonResponse(['status' => $checkSchedule['status'], 'message' => $checkSchedule['message'], 'error' => true], Response::HTTP_OK);
  749.             }
  750.         }
  751.         if (null !== $order->getOffer()->getOfferDeliveryZone() && $order->getOffer()->getOfferDeliveryZone()->count() > 0) {
  752.             if (null === $address->isPickup()) {
  753.                 $points $address->getCoordinatesForDeliveryZone() ?? $coordinatesYandex->getGeoCoordinates(
  754.                     $address->buildFullAddress(),
  755.                     ['offerId' => (int)$order->getOffer()->getID()]
  756.                 );
  757.                 $deliveryZone $deliveryZoneRepository->getPolygonByPoint($order->getOffer(), $points);
  758.                 if (null !== $deliveryZone) {
  759.                     $user $order->getUser();
  760.                     $codeCost $order->getCodeCost();
  761.                     if ($subscriptionService->isSubscriber($user) || $user->isBatchCodesAllowed() || $user->isBalanceAllowed($codeCost $order->getCodesCount())) {
  762.                         $codeCost 0;
  763.                     }
  764.                     $total $order->getAmount() - ($order->getCodesCount() * $codeCost);
  765.                     if ($total $deliveryZone->getMinOrderAmount()) {
  766.                         return new JsonResponse([
  767.                             'error' => true,
  768.                             'message' => \sprintf('До минимальной суммы заказа в этой зоне %s р.', (string) ($deliveryZone->getMinOrderAmount() - $total)),
  769.                         ]);
  770.                     }
  771.                     if ($yandexDeliveryCalculator->isAvailable($order->getOffer())) {
  772.                         $chechPriceResponse $yandexDeliveryCalculator->calculate(
  773.                             $order,
  774.                             $geoLocationRepository->getById($deliveryZone->getGeoLocationId()),
  775.                         );
  776.                         $order->setDeliveryCost($chechPriceResponse->getPrice());
  777.                     } else {
  778.                         $order->setDeliveryCost($deliveryZone->getPaidDeliveryAmount());
  779.                         if ($total >= $deliveryZone->getFreeDeliveryAmount()) {
  780.                             $order->setDeliveryCost(0);
  781.                         }
  782.                     }
  783.                     $order->setDeliveryZoneLocationId($deliveryZone->getGeoLocationId());
  784.                     if (null === $address->getCoordinatesForDeliveryZone()) {
  785.                         $coordinates explode(' '$points);
  786.                         $address->setLatitude($coordinates[1]);
  787.                         $address->setLongitude($coordinates[0]);
  788.                     }
  789.                 } else {
  790.                     return new JsonResponse([
  791.                         'error' => true,
  792.                         'message' => 'Данный адрес не входит в зону доставки. Выберите другой адрес.',
  793.                     ]);
  794.                 }
  795.             } else {
  796.                 $order->setDeliveryZoneLocationId($address->getGeoLocation()->getID());
  797.             }
  798.         }
  799.         $this->reCalcOrder(
  800.             $order,
  801.             $discount,
  802.             $pickupDeliveryType,
  803.             $subscriptionService->isSubscriber($this->getUser()),
  804.             $pricePromocodeForOnlineOrder
  805.         );
  806.         $entityManager->flush();
  807.         return new JsonResponse(['error' => false'redirectURL' => '/delivery/order/payment/' $order->getID() ]);
  808.     }
  809.     /**
  810.      * @Route("/delivery/order/pay/{orderID}", name="deliveryOrderPay")
  811.      */
  812.     public function payAction(
  813.         Request $request,
  814.         PartnerBePaidService $partnerBePaidService,
  815.         PaymentService $paymentService,
  816.         CreditCardRepositoryInterface $creditCardRepository,
  817.         SubscriptionService $subscriptionService,
  818.         ContainerInterface $container,
  819.         PricePromocodeForOnlineOrder $pricePromocodeForOnlineOrder,
  820.         VirtualWalletChecker $virtualWalletChecker,
  821.         $orderID
  822.     ) {
  823.         $paymentMethod $request->request->getInt('paymentMethod');
  824.         $entityManager $this->getDoctrine()->getManager();
  825.         $order $entityManager->find(FoodOrder::class, $orderID);
  826.         if (null === $order) {
  827.             return new JsonResponse(['error' => true]);
  828.         }
  829.         $iikoUtil IikoUtil::instance($order->getOffer());
  830.         $iikoUtil->setContainer($container);
  831.         $order->setPaymentType($paymentMethod);
  832.         $order->setPaymentMethodID(OfferOrder::METHOD_BEPAID);
  833.         $isUsePartnerCashbackBalance $request->request->getBoolean('usePartnerCashbackBalance');
  834.         $order->setUsePartnerCashbackBalance($isUsePartnerCashbackBalance);
  835.         if ($isUsePartnerCashbackBalance) {
  836.             $allowedCashbackSumToPay $iikoUtil->getAllowedCashbackSumToPay($order$entityManager);
  837.             $order->setUsedPartnerCashbackSum($allowedCashbackSumToPay);
  838.         }
  839.         $order->setUseFastDelivery(
  840.             $request->request->getBoolean('useFastDelivery')
  841.         );
  842.         $order->setChangeAmount(
  843.             $request->request->get('changeAmount')
  844.                 ? (float) $request->request->get('changeAmount')
  845.                 : null
  846.         );
  847.         $codeCost $order->getCodeCost();
  848.         $codeCostRegular $codeCost;
  849.         $user $order->getUser();
  850.         $subscriber false;
  851.         if ($subscriptionService->isSubscriber($user)) {
  852.             $subscriber true;
  853.             $codeCost 0;
  854.         }
  855.         $isBatchCodes false;
  856.         if ($user->isBatchCodesAllowed()) {
  857.             $isBatchCodes true;
  858.             $codeCost 0;
  859.         }
  860.         if (in_array($paymentMethod, [PaymentType::CASHPaymentType::TERMINAL], true)) {
  861.             if ($subscriber || $isBatchCodes) {
  862.                 $order->setAmount($codeCost);
  863.                 $paymentService->createCode(
  864.                     $order,
  865.                     $order->getCodesCount(),
  866.                     false,
  867.                     null,
  868.                     false,
  869.                     $isBatchCodes UserBalanceActivity::TYPE_REDUCTION_BATCH_CODES null
  870.                 );
  871.                 return new JsonResponse(['error' => false]);
  872.             }
  873.             $order->setAmount($order->getCodesCount() * $codeCost);
  874.             $entityManager->flush();
  875.             return new JsonResponse([
  876.                 'redirectURL' => $this->redirectToRoute('buyCode', [
  877.                         'offerID' => $order->getOffer()->getID(),
  878.                         'codesCount' =>  $order->getCodesCount(),
  879.                         'orderID' => $order->getID()
  880.                     ]
  881.                 )->getTargetUrl()
  882.             ]);
  883.         }
  884.         $deliveryType $order->getDeliveryAddress()->isPickup() ? FoodOfferExtension::DELIVERY_METHOD_PICKUP FoodOfferExtension::DELIVERY_METHOD;
  885.         $discount $request->getSession()->get("pickupDiscount") ? $request->getSession()->get("pickupDiscount") : 0;
  886.         $this->reCalcOrder(
  887.             $order,
  888.             $discount,
  889.             $deliveryType,
  890.             $subscriptionService->isSubscriber($user),
  891.             $pricePromocodeForOnlineOrder
  892.         );
  893.         if ($paymentMethod === PaymentType::SLIVKI_PAY) {
  894.             $codeCostForSlivkiPay $order->getCodesCount() * (float) $order->getCodeCost();
  895.             try {
  896.                 $orderAmount $order->getAmount();
  897.                 if ($order->getUsedPartnerCashbackSum() > 0) {
  898.                     $orderAmount -= $order->getUsedPartnerCashbackSum();
  899.                 }
  900.                 if ($codeCost === || $user->isBalanceAllowed($codeCost $order->getCodesCount())) {
  901.                     $orderAmount += $codeCostForSlivkiPay;
  902.                 }
  903.                 if (!$virtualWalletChecker->availableSlivkiPay($orderAmount$user)) {
  904.                     return new JsonResponse(
  905.                         [
  906.                             'error' => true,
  907.                             'message' => 'Недостаточно средств на балансе SlivkiPay',
  908.                             'slivkiPay' => true,
  909.                         ]
  910.                     );
  911.                 }
  912.                 $paymentService->payOrder($user$orderAmount);
  913.                 $paymentService->createCode($order$order->getCodesCount(), false);
  914.             } catch (InsufficientBalanceFundsException $exception) {
  915.                 return new JsonResponse(['error' => true]);
  916.             }
  917.             return new JsonResponse(['error' => false]);
  918.         }
  919.         $order->setPaymentType(PaymentType::ONLINE);
  920.         if ($user->isBalanceAllowed($codeCost $order->getCodesCount())) {
  921.             $codeCost 0;
  922.         }
  923.         $iikoUtil->modifyOrder($order$entityManager);
  924.         $entityManager->flush();
  925.         $partnerBePaidService->setOrder($order);
  926.         $card $creditCardRepository->findById($request->request->getInt('creditCardID'));
  927.         if (null === $card || !$card->isOwner($this->getUser()->getID())) {
  928.             $paymentToken $partnerBePaidService->getPaymentToken($ordernull$codeCost);
  929.             if (!$paymentToken) {
  930.                 return new JsonResponse(['error' => true]);
  931.             }
  932.             $partnerBePaidService->createBePaidPaiment($order$paymentToken['checkout']['token']);
  933.             return new JsonResponse([
  934.                 'token' => $paymentToken['checkout']['token'],
  935.             ]);
  936.         }
  937.         $offerSettings $order->getOffer()->getOnlineOrderSettings();
  938.         if (($iikoUtil::SPLIT_PAYMENT || ($offerSettings && $offerSettings->isSplitPayment()))
  939.             && (!$subscriber && !$user->isBatchCodesAllowed() && !$user->isBalanceAllowed($codeCostRegular $order->getCodesCount()))
  940.         ) {
  941.             $amount $order->getAmount() - $order->getCodesCount() * $codeCost;
  942.         } else {
  943.             $amount $order->getAmount();
  944.         }
  945.         $result $partnerBePaidService->checkoutByToken($order$card->getID(), $amount);
  946.         if (!$result) {
  947.             return new JsonResponse(['error' => true]);
  948.         }
  949.         if (is_array($result) && isset($result['token'])) {
  950.             return new JsonResponse(['token' => $result['token']]);
  951.         }
  952.         $partnerBePaidService->createBePaidPaiment($order$result);
  953.         
  954.         return new JsonResponse(['error' => false]);
  955.     }
  956.     /** @Route("/delivery/street/suggest/{offerID}") */
  957.     public function deliveryStreetSuggest(Request $request$offerID): JsonResponse
  958.     {
  959.         /** @var StreetRepository $street */
  960.         $street $this->getDoctrine()->getManager()->getRepository(Street::class);
  961.         $streets $street->getStreets($offerID$request->query->get('q'));
  962.         return new JsonResponse($streets);
  963.     }
  964.     /** @Route("/delivery/feedback/{offerID}") */
  965.     public function feedbackAction(Request $requestMailer $mailer$offerID) {
  966.         $text $request->request->get('name') . ', ' $request->request->get('email') . "\n" $request->request->get('message') . "\n";
  967.         $subj ='';
  968.         if (is_numeric($offerID)) {
  969.             $offerID = (int)$offerID;
  970.             $offer $this->getDoctrine()->getManager()->find(Offer::class, $offerID);
  971.             if ($offer) {
  972.                 $subj 'Жалоба на акцию: ' $offer->getTitle();
  973.             } else {
  974.                 $subj 'Фидбек с доставки суши';
  975.             }
  976.         }
  977.         else if ($offerID == 'subscription-landing') {
  978.             $subj 'Фидбек с лендинга подписки';
  979.         }
  980.         else if ($offerID == 'auth') {
  981.             $subj 'Фидбек с попапа авторизации';
  982.         }
  983.         $message $mailer->createMessage($subj$text);
  984.         $message->setFrom('info@slivki.by''Slivki.by');
  985.         $message->setTo('1@slivki.by')
  986.             ->addTo('info@slivki.by')
  987.             ->addTo('yuri@slivki.com')
  988.             ->addCc('dmitry.kazak@slivki.com');
  989.         $mailer->send($message);
  990.         return new Response();
  991.     }
  992.     private function reCalcOrder(
  993.         FoodOrder $order,
  994.         $discount 0,
  995.         $typePrice null,
  996.         bool $isSubscriber false,
  997.         PricePromocodeForOnlineOrder $pricePromocodeForOnlineOrder
  998.     ) {
  999.         /** @var OfferOrderDetails $details */
  1000.         $orderSum 0;
  1001.         $additionalInfo $order->getAdditionalInfo();
  1002.         $additionalDominos false;
  1003.         if (isset($additionalInfo['dominosCoupon'])) {
  1004.             $additionalDominos true;
  1005.         }
  1006.         $iikoUtil AbstractDelivery::instance($order->getOffer());
  1007.         $iikoUtil->setContainer($this->kernel->getContainer());
  1008.         foreach ($order->getOfferOrderDetails() as $details) {
  1009.             $variant $details->getOfferExtensionVariant();
  1010.             if ($variant) {
  1011.                 $extension $variant->getOfferExtension();
  1012.                 if ($additionalDominos) {
  1013.                     $variantAdditionalDominos $variant;
  1014.                 } else {
  1015.                     $variantAdditionalDominos null;
  1016.                 }
  1017.                 $purchasePrice PriceDeliveryType::calcDeliveryPickupPrice(
  1018.                     $extension,
  1019.                     $typePrice,
  1020.                     $variant->getRegularPrice(),
  1021.                     $variant->getOfferPrice(),
  1022.                     $variantAdditionalDominos
  1023.                 );
  1024.             } else {
  1025.                 $extension $details->getOfferExtension();
  1026.                 $product $iikoUtil->getProduct($extension->getPartnerItemID());
  1027.                 $purchasePrice PriceDeliveryType::calcDeliveryPickupPrice(
  1028.                     $extension,
  1029.                     $typePrice,
  1030.                     $product->regularPrice,
  1031.                     $extension->getCurrentPrice(null$typePrice),
  1032.                 );
  1033.             }
  1034.             $orderSum += $details->getItemsCount() * $purchasePrice;
  1035.             $details->setPurchasePrice($purchasePrice);
  1036.         }
  1037.         $deliveryCost $order->getDeliveryCost();
  1038.         if (
  1039.             ($typePrice !== null && (int) $typePrice === FoodOfferExtension::DELIVERY_METHOD_PICKUP)
  1040.             || (null !== $order->getDeliveryAddress() && $order->getDeliveryAddress()->isPickup())
  1041.         ) {
  1042.             $deliveryCost 0;
  1043.         }
  1044.         $order->setDeliveryCost($deliveryCost);
  1045.         $regularCodeCost $pricePromocodeForOnlineOrder->getPrice(
  1046.             $order,
  1047.             $order->getOffer(),
  1048.             $order->getCodesCount(),
  1049.             $orderSum $deliveryCost
  1050.         );
  1051.         $codeCost 0;
  1052.         if (!$isSubscriber
  1053.             && !$order->getUser()->isBatchCodesAllowed()
  1054.             && !$order->getUser()->isBalanceAllowed($regularCodeCost $order->getCodesCount())
  1055.         ) {
  1056.             $codeCost $regularCodeCost;
  1057.         }
  1058.         $orderSum += $codeCost $order->getCodesCount() + $deliveryCost;
  1059.         if ($discount 0) {
  1060.             $orderSum -= ($orderSum * ($discount 100));
  1061.         }
  1062.         if ($order->getUsedPartnerCashbackSum() > 0) {
  1063.             $orderSum -= $order->getUsedPartnerCashbackSum();
  1064.         }
  1065.         $order->setAmount($orderSum);
  1066.     }
  1067.     /**
  1068.      * @Route("/delivery/check-address", name="delivery_check_address")
  1069.      */
  1070.     public function checkAddressAction(
  1071.         Request $request,
  1072.         SubscriptionService $subscriptionService,
  1073.         VisibilityFilterService $visibilityFilterService
  1074.     ): JsonResponse {
  1075.         $entityManager $this->getDoctrine()->getManager();
  1076.         $orderID $request->request->getInt('orderID');
  1077.         $addressID $request->request->getInt('addressID');
  1078.         $deliveryTime $request->request->get('deliveryTime');
  1079.         $order $entityManager->find(FoodOrder::class, $orderID);
  1080.         $order->setDeliveryTime($deliveryTime);
  1081.         $order->setPaymentType($request->request->getInt('paymentType'1));
  1082.         $address $entityManager->find(UserAddress::class, $addressID);
  1083.         $order->setDeliveryAddress($address);
  1084.         $orderInfo IikoUtil::instance($order->getOffer())->checkOrder($entityManager$order$subscriptionService);
  1085.         if (!$orderInfo) {
  1086.             return new JsonResponse(['error' => true]);
  1087.         }
  1088.         $entityManager->flush();
  1089.         $response $this->getCheckAddressResponse($orderInfo);
  1090.         try {
  1091.             $visibilityFilterService->assertAllVisibleOrFail(array_map(
  1092.                 static fn (OfferOrderDetails $orderDetail) => $orderDetail->getOfferExtension(),
  1093.                 $order->getOfferOrderDetails()->toArray(),
  1094.             ));
  1095.         } catch (OfferExtensionNotVisibleException $e) {
  1096.             return new JsonResponse([
  1097.                 'status' => 'error',
  1098.                 'error' => true,
  1099.                 'deliveryPrice' => $response['deliveryPrice'],
  1100.                 'message' => $e->getMessage(),
  1101.             ]);
  1102.         }
  1103.         return new JsonResponse($response);
  1104.     }
  1105.     /** @Route("/delivery/reload/offer/{offerId}/type/{typePrice}", name="deliveryReloadDish") */
  1106.     public function reloadDish(
  1107.         Request $request,
  1108.         ImageService $imageService,
  1109.         ProductFastDeliveryService $productFastDeliveryService,
  1110.         CustomProductOfferSorter $productSorter,
  1111.         ContainerInterface $container,
  1112.         FoodFilterCounterRepositoryInterface $foodFilterCounterRepository,
  1113.         CustomProductOfferSorter $customProductOfferSorter,
  1114.         OfferOrderPurchaseCountDaoInterface $offerOrderPurchaseCountDao,
  1115.         OfferCacheService $offerCacheService,
  1116.         FoodOfferExtensionRepositoryInterface $foodOfferExtensionRepository,
  1117.         WeightParserHelper $weightParserHelper,
  1118.         ShippingSchedulerService $shippingSchedulerService,
  1119.         FoodByOnlineCategoriesBuilder $foodByOnlineCategoriesBuilder,
  1120.         VisibilityFilterService $visibilityFilterService,
  1121.         $offerId,
  1122.         $typePrice
  1123.     ) {
  1124.         $offerCached $offerCacheService->getOffer($offerIdtruetrue);
  1125.         $data['offer'] = $offerCached;
  1126.         $orderUtil AbstractDelivery::instance($offerCached);
  1127.         $orderUtil->setContainer($container);
  1128.         $data['filterAction'] = $foodFilterCounterRepository->findByOfferId((int) $offerCached->getID());
  1129.         $isSushiVesla $orderUtil instanceof SushiVesla;
  1130.         $isDominos $orderUtil instanceof Dominos;
  1131.         $isSushiHouse $orderUtil instanceof SushiHouse;
  1132.         $isSushiChefArts $orderUtil instanceof SushiChefArts;
  1133.         $data['isDominos'] = $isDominos;
  1134.         $data['showSortingIndexOrder'] = $isSushiVesla || $isDominos false true;
  1135.         $allDishes = [];
  1136.         if ($isSushiVesla) {
  1137.             $allDishes $foodOfferExtensionRepository->findActiveByOfferIdAndShippingType($offerId$typePrice);
  1138.         }
  1139.         $shippingType FoodOfferExtension::LABEL_SHIPPING_TYPE[$typePrice];
  1140.         if ($isSushiVesla) {
  1141.             $dishes $orderUtil->getProductsDBByShippingType(
  1142.                 array_filter($allDishes, static fn (OfferExtension $offerExtension): bool => !is_subclass_of($offerExtensionFoodOfferExtension::class)),
  1143.             );
  1144.         } else {
  1145.             $dishes $orderUtil->getDishes();
  1146.         }
  1147.         $extensions $foodOfferExtensionRepository->findActiveByOfferIdAndShippingType($offerId$typePrice);
  1148.         $extensions array_combine(
  1149.             array_map(static fn (FoodOfferExtension $e) => $e->getPartnerItemID(), $extensions),
  1150.             $extensions,
  1151.         );
  1152.         $dishPurchaseCount $offerOrderPurchaseCountDao->getPurchaseCountsForPeriodByOffer((int) $offerIdPurchaseCountPeriod::LAST_MONTH);
  1153.         $dishPurchaseDayCount $offerOrderPurchaseCountDao->getPurchaseCountsForPeriodByOffer((int) $offerIdPurchaseCountPeriod::LAST_DAY);
  1154.         $data['dishes'] = [];
  1155.         $data['showPricePerKilogram'] = false;
  1156.         foreach ($dishes as $dish) {
  1157.             if (!array_key_exists($dish->id$extensions)) {
  1158.                 continue;
  1159.             }
  1160.             $offerExtension $extensions[$dish->id];
  1161.             $dish->productsPerCode $offerExtension->getProductsPerCode();
  1162.             $dish->offerPrice $offerExtension->getCurrentPrice(null$typePrice);
  1163.             $dish->sauceNeed $offerExtension->isSauceNeed();
  1164.             $dish->rating = (float) $offerCached->getRating();
  1165.             $dish->onlineCategories array_map(
  1166.                 static fn (OfferExtensionOnlineCategory $category): string => $category->getName(),
  1167.                 $offerExtension->getActiveOnlineCategories()->getValues(),
  1168.             );
  1169.             if (isset($dish->regularPrice) && $dish->regularPrice == 0) {
  1170.                 $dish->regularPrice $offerExtension->getPrice();
  1171.             }
  1172.             $dishSizeFull $dish->sizeFull;
  1173.             $dish->sizeFull '';
  1174.             $dish->pricePerKilogram null;
  1175.             $dish->itemCount = (int) $offerExtension->getComponentsCount();
  1176.             $dish->offerPrice = (float) PriceDeliveryType::calcDeliveryPickupPrice(
  1177.                 $offerExtension,
  1178.                 $typePrice,
  1179.                 $dish->regularPrice,
  1180.                 $dish->offerPrice,
  1181.             );
  1182.             if ($extensions[$dish->id]->getWeight()) {
  1183.                 $dish->sizeFull $offerExtension->getWeight() . ' г';
  1184.                 $dish->pricePerKilogram $this->calcPricePerKilogram(
  1185.                     $dish->offerPrice,
  1186.                     (float) $offerExtension->getWeight(),
  1187.                 );
  1188.                 $data['showPricePerKilogram'] = true;
  1189.             }
  1190.             if ($offerExtension->getComponentsCount()) {
  1191.                 if ($dish->sizeFull != '') {
  1192.                     $dish->sizeFull .= ', ';
  1193.                 }
  1194.                 $dish->sizeFull .= $offerExtension->getComponentsCount() . ' шт';
  1195.             }
  1196.             if ($dish->sizeFull === '') {
  1197.                 $dish->sizeFull $dishSizeFull;
  1198.             }
  1199.             if (null === $dish->pricePerKilogram && !empty($dish->sizeFull)) {
  1200.                 $dish->pricePerKilogram $this->calcPricePerKilogram(
  1201.                     $dish->offerPrice,
  1202.                     (float) $weightParserHelper->parse($dish->sizeFull),
  1203.                 );
  1204.                 $data['showPricePerKilogram'] = true;
  1205.             }
  1206.             $dish->originId $dish->id;
  1207.             $dish->position $offerExtension->getPosition() ?: CustomProductOfferSorter::DEFAULT_POSITION;
  1208.             $dish->id $offerExtension->getID();
  1209.             $dish->description str_replace("\n"'<br/>'$dish->description);
  1210.             $dish->imageURL null;
  1211.             if (isset($dish->images[count($dish->images) - 1])) {
  1212.                 if ($dish->images[count($dish->images) - 1] instanceof OfferExtensionMedia) {
  1213.                     $dish->imageURL $imageService->getImageURLCached($dish->images[count($dish->images) - 1], 5400);
  1214.                 } else if ($dish->images[count($dish->images) - 1]) {
  1215.                     $dish->imageURL $dish->images[count($dish->images) - 1]->imageUrl;
  1216.                 }
  1217.             }
  1218.             $key array_search($dish->idarray_column($dishPurchaseCount'id'), true);
  1219.             $dish->purchaseCount = isset($dishPurchaseCount[$key]['cnt']) && $key !== false $dishPurchaseCount[$key]['cnt'] : 0;
  1220.             $keyDay array_search($dish->idarray_column($dishPurchaseDayCount'id'), true);
  1221.             $dish->purchaseDayCount = isset($dishPurchaseDayCount[$keyDay]['cnt']) && $keyDay !== false
  1222.                 $dishPurchaseDayCount[$keyDay]['cnt']
  1223.                 : 0;
  1224.             $deliveryTime $productFastDeliveryService->findProductFastDelivery($offerCached$dish->originId);
  1225.             $dish->fastDeliveryTime CustomProductOfferSorter::DEFAULT_POSITION;
  1226.             if ($deliveryTime) {
  1227.                 $dish->fastDelivery $deliveryTime;
  1228.                 $dish->fastDeliveryTime = (int) $deliveryTime['time'];
  1229.             }
  1230.             if (isset($dish->variants) && count($dish->variants) > 0) {
  1231.                 $offerExtensionVariants array_reduce(
  1232.                     $extensions[$dish->originId]->getVariants()->getValues(),
  1233.                     static function (array $variantsOfferExtensionVariant $variant)
  1234.                     {
  1235.                         $variants[$variant->getPartnerID()] = $variant;
  1236.                         return $variants;
  1237.                     },
  1238.                     [],
  1239.                 );
  1240.                 foreach ($dish->variants as $key => $variant) {
  1241.                     if (!array_key_exists($variant->id$offerExtensionVariants)) {
  1242.                         unset($dish->variants[$key]);
  1243.                         continue;
  1244.                     }
  1245.                     /**
  1246.                      * @var $offerExtensionVariant OfferExtensionVariant
  1247.                      */
  1248.                     $offerExtensionVariant $offerExtensionVariants[$dish->variants[$key]->partnerId];
  1249.                     $dish->variants[$key]->id $offerExtensionVariant->getID();
  1250.                     if (PriceDeliveryType::PERCENT_PRICE === $offerExtension->getPriceDeliveryType()) {
  1251.                         $dish->variants[$key]->offerPrice = (float) PriceDeliveryType::calcDeliveryPickupPrice(
  1252.                             $offerExtension,
  1253.                             $typePrice,
  1254.                             $dish->variants[$key]->regularPrice,
  1255.                             $offerExtension->getCurrentPrice(null$typePrice),
  1256.                         );
  1257.                     }
  1258.                 }
  1259.             }
  1260.             $data['dishes'][] = $dish;
  1261.         }
  1262.         $data['dishes'] = $visibilityFilterService->filterInvisibleExtensions($data['dishes']);
  1263.         $sortType $request->query->get('sort'CustomProductOfferSorter::DEFAULT_CUSTOM_PRODUCT_SORT);
  1264.         $data['dishes'] = $productSorter->sort($data['dishes'], $sortType);
  1265.         $dishGroup $orderUtil->getDishGroups();
  1266.         $foodDishExtensionId $request->query->get('extension');
  1267.         if (null !== $foodDishExtensionId) {
  1268.             $dishKey array_search($foodDishExtensionId, \array_column($data['dishes'], 'id'));
  1269.             $foodCourtExtensionDish $data['dishes'][$dishKey];
  1270.             unset($data['dishes'][$dishKey]);
  1271.             array_unshift($data['dishes'], $foodCourtExtensionDish);
  1272.             if (count($dishGroup)) {
  1273.                 $category $isSushiHouse $foodCourtExtensionDish->parentGroup $foodCourtExtensionDish->groupName;
  1274.                 $keyDishGroup array_search($category$dishGroup);
  1275.                 $group $dishGroup[$keyDishGroup];
  1276.                 unset($dishGroup[$keyDishGroup]);
  1277.                 array_unshift($dishGroup$group);
  1278.             }
  1279.         }
  1280.         $data['topDishIDList'] = [];
  1281.         for ($i 0$i 3$i++) {
  1282.             if (isset($dishPurchaseCount[$i]['id'])) {
  1283.                 $data['topDishIDList'][] = $dishPurchaseCount[$i]['id'];
  1284.             }
  1285.         }
  1286.         if ($orderUtil::DISH_BY_GROUP) {
  1287.             $dishByGroupLabel = [];
  1288.             $dishByGroupContent = [];
  1289.             if ($isSushiHouse || $isSushiChefArts) {
  1290.                 foreach ($data['dishes'] as $dish) {
  1291.                     $dishByGroupContent[$dish->groupName][] = $dish;
  1292.                     if (!in_array($dish->parentGroup$dishByGroupLabel)) {
  1293.                         $dishByGroupLabel[$dish->groupName] = $dish->parentGroup;
  1294.                     }
  1295.                 }
  1296.             }
  1297.             if ($isDominos) {
  1298.                 foreach ($data['dishes'] as $dish) {
  1299.                     $dish->parentGroup $dish->groupName;
  1300.                     $dishByGroupContent[$dish->groupName][] = $dish;
  1301.                     if (!in_array($dish->groupName$dishByGroupLabeltrue)) {
  1302.                         $dishByGroupLabel[$dish->groupName] = $dish->groupName;
  1303.                     }
  1304.                 }
  1305.             }
  1306.             $data['dishByGroup'] = [
  1307.                 'content' => $dishByGroupContent,
  1308.                 'label' => $dishByGroupLabel,
  1309.             ];
  1310.         }
  1311.         $dishGroup $foodByOnlineCategoriesBuilder->create($offerId,$data['dishes']);
  1312.         if (!empty($dishGroup)) {
  1313.             $data['dishByGroup'] = array_key_exists('dishByGroup'$data)
  1314.                 ? [
  1315.                     'content' => array_merge($dishGroup['content'], $data['dishByGroup']['content']),
  1316.                     'label' => array_merge($dishGroup['label'], $data['dishByGroup']['label']),
  1317.                 ]
  1318.                 : $dishGroup;
  1319.         }
  1320.         $options $isSushiVesla
  1321.             $orderUtil->getOptionsDBByShippingType(
  1322.                 $imageService,
  1323.                 \array_filter($allDishes, static fn (OfferExtension $offerExtension): bool => $offerExtension instanceof FoodOfferOptionExtension)
  1324.             )
  1325.             : $this->getOptions($imageService$offerCached$orderUtil0$isDominos $shippingType null);
  1326.         $data['options'] = $customProductOfferSorter->sort(
  1327.             $visibilityFilterService->filterInvisibleExtensions($options),
  1328.             CustomProductOfferSorter::DEFAULT_CUSTOM_PRODUCT_SORT,
  1329.         );
  1330.         $data['sortList'] = CustomProductOfferSorter::SORT_LIST;
  1331.         $data['isAvailableOnFood'] = $offerCached->isAvailableOnFood();
  1332.         $data['isAvailableOrderForToday'] = $shippingSchedulerService->availableOrderForToday($orderUtil$offerCached$typePrice);
  1333.         if ($isDominos) {
  1334.             $view CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/delivery/delivery_teaser_reload_pickup.html.twig' 'Slivki/delivery/delivery_teaser_reload_pickup.html.twig';
  1335.         } else {
  1336.             $view CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/delivery/delivery_teaser_reload.html.twig' 'Slivki/delivery/delivery_teaser_reload.html.twig';
  1337.         }
  1338.         return $this->render($view$data);
  1339.     }
  1340.     private function calcPricePerKilogram(float $offerPriceint $weight): ?float
  1341.     {
  1342.         if (!$weight) {
  1343.             return null;
  1344.         }
  1345.         return \round(self::KILOGRAM $offerPrice $weight2);
  1346.     }
  1347.     /** @Route("/expresspizza-orders") */
  1348.     public function expressPizzaOrdersAction(Request $request) {
  1349.         $offerID 282278;
  1350.         $pass '67380b434f';
  1351.         $objectCode '0017-4-009';
  1352.         if ($pass != $request->query->get('pass')) {
  1353.             return new Response('ERROR: Wrong password!');
  1354.         }
  1355.         $date = \DateTime::createFromFormat('U'$request->query->get('date'));
  1356.         if (!$date) {
  1357.             return new Response('ERROR: Wrong date format!');
  1358.         }
  1359.         $entityManager $this->getDoctrine()->getManager();
  1360.         /** @var Connection $connection */
  1361.         $connection $entityManager->getConnection();
  1362.         $sql "select"
  1363.                 " offer_order.id as order_id,"
  1364.                 " offer_order.paid_at as order_datetime,"
  1365.                 " offer_order.delivery_time as delivery_datetime,"
  1366.                 " user_address.name as client_name,"
  1367.                 " user_address.phone as client_phone,"
  1368.                 " user_address.pickup as pickup,"
  1369.                 " street.name as street_name,"
  1370.                 " user_address.house as house,"
  1371.                 " user_address.block as block,"
  1372.                 " user_address.entrance as entrance,"
  1373.                 " user_address.floor as floor,"
  1374.                 " user_address.doorphone as doorphone,"
  1375.                 " user_address.appartment as appartment,"
  1376.                 " offer_extension.partner_item_id as product_code,"
  1377.                 " offer_extension.name as product_name,"
  1378.                 " offer_order_details.items_count as items_count,"
  1379.                 " offer_extension.dish_delivery_price as delivery_price,"
  1380.                 " offer_extension.pickup_price as pickup_price,"
  1381.                 " offer_order.parameter_int_0 as payment_type,"
  1382.                 " offer_order.comment as comment,"
  1383.                 " coalesce(geo_location.pickup_point_partner_id, '$objectCode') as object_code"
  1384.             " from offer_order_details"
  1385.             " inner join offer_order on offer_order.id = offer_order_details.offer_order_id"
  1386.             " inner join user_address on offer_order.delivery_address_id = user_address.id"
  1387.             " left join street on user_address.street_id = street.id"
  1388.             " left join geo_location on user_address.geo_location_id = geo_location.id"
  1389.             " inner join offer_extension on offer_extension.id = offer_order_details.offer_extension_id"
  1390.             " where offer_order.offer_id = $offerID and offer_order.status > 0 and"
  1391.                 " offer_order.paid_at >= '" $date->format('Y-m-d H:i') . "'"
  1392.             " order by offer_order.id";
  1393.         $orderDetails $connection->executeQuery($sql)->fetchAll(\PDO::FETCH_ASSOC);
  1394.         $result = [];
  1395.         foreach ($orderDetails as $orderDetail) {
  1396.             $orderDateTime = new \DateTime($orderDetail['order_datetime']);
  1397.             $deliveryDateTime = new \DateTime();
  1398.             if ($orderDetail['delivery_datetime'] != 'Ближайшее') {
  1399.                 $deliveryDateTime = new \DateTime($orderDetail['delivery_datetime']);
  1400.             }
  1401.             $comment '';
  1402.             if (trim($orderDetail['entrance'])) {
  1403.                 $comment .= 'П' trim($orderDetail['entrance']) . ' ';
  1404.             }
  1405.             if (trim($orderDetail['floor'])) {
  1406.                 $comment .= 'Э' trim($orderDetail['floor']) . ' ';
  1407.             }
  1408.             if (trim($orderDetail['doorphone'])) {
  1409.                 $comment .= 'Д' trim($orderDetail['doorphone']) . ' ';
  1410.             }
  1411.             $paymentType '';
  1412.             switch ($orderDetail['payment_type']) {
  1413.                 case 1:
  1414.                     $paymentType 'Оплата: онлайн, ';
  1415.                     break;
  1416.                 case 2:
  1417.                     $paymentType 'Оплата: наличные, ';
  1418.                     break;
  1419.                 case 3:
  1420.                     $paymentType 'Оплата: терминал, ';
  1421.                     break;
  1422.                 case PaymentType::SLIVKI_PAY:
  1423.                     $paymentType 'Оплата: SlivkiPay, ';
  1424.                     break;
  1425.             }
  1426.             $comment .= $paymentType;
  1427.             $comment .= trim($orderDetail['comment']);
  1428.             $result[] = join(chr(9), [
  1429.                 $orderDetail['object_code'], // Код объекта
  1430.                 $orderDetail['order_id'], // Номер заказа
  1431.                 $orderDateTime->format('d.m.Y'), // Дата заказа
  1432.                 $orderDateTime->format('H:i'), // Время заказа
  1433.                 $deliveryDateTime->format('H:i'), // Изготовить к какому времени
  1434.                 $orderDetail['client_name'], // Имя клиента – Контакт
  1435.                 str_replace('+375''+375 '$orderDetail['client_phone']), // Контактный телефон.
  1436.                 $orderDetail['pickup'] ? 1// Тип получения: на месте (0) или доставка (1).
  1437.                 trim($orderDetail['street_name']) ?: ' '// Улица доставки
  1438.                 trim($orderDetail['house']) ?: ' '// Номер дома
  1439.                 trim($orderDetail['block']) ?: ' '// Корпус
  1440.                 trim($orderDetail['appartment']) ?: ' '// Квартира
  1441.                 ' '// Код группы
  1442.                 $orderDetail['product_code'], // Код товара
  1443.                 ' '// IDNT Номер выгрузки (оставляйте пустым)
  1444.                 $orderDetail['product_name'], // Название товара
  1445.                 $orderDetail['items_count'], // Количество
  1446.                 $orderDetail['pickup'] ? $orderDetail['pickup_price'] : $orderDetail['delivery_price'], // Цена
  1447.                 str_replace(["\r\n""\n"],' '$comment), // Примечание
  1448.             ]);
  1449.         }
  1450.         $result[] = chr(9) . 'OK';
  1451.         return new Response(join("\r\n"$result));
  1452.     }
  1453.     private function customSortDishByGroup(array $dishByGroupContent, array $sort): array
  1454.     {
  1455.         uasort($dishByGroupContent, function ($dishGroup1$dishGroup2) use ($sort) {
  1456.             if (!count($dishGroup1)) {
  1457.                 return 1;
  1458.             }
  1459.             if (!count($dishGroup2)) {
  1460.                 return -1;
  1461.             }
  1462.             $dishGroup1Key array_search($dishGroup1[0]->parentGroup$sort);
  1463.             $dishGroup2Key array_search($dishGroup2[0]->parentGroup$sort);
  1464.             return $dishGroup1Key $dishGroup2Key ? -1;
  1465.         });
  1466.         return $dishByGroupContent;
  1467.     }
  1468. }