src/Controller/IikoOrderController.php line 111

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