1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
ym_handler.php
См. документацию.
1<?php
2
12
13
14IncludeModuleLangFile(__FILE__);
15
19
21{
22 const JSON = 0;
23 const XML = 1;
24
25 const ERROR_STATUS_400 = "400 Bad Request";
26 const ERROR_STATUS_401 = "401 Unauthorized";
27 const ERROR_STATUS_403 = "403 Forbidden";
28 const ERROR_STATUS_404 = "404 Not Found";
29 const ERROR_STATUS_405 = "405 Method Not Allowed";
30 const ERROR_STATUS_415 = "415 Unsupported Media Type";
31 const ERROR_STATUS_420 = "420 Enhance Your Calm";
32 const ERROR_STATUS_500 = "500 Internal Server Error";
33 const ERROR_STATUS_503 = "503 Service Unavailable";
34
35 const DATE_FORMAT = "d-m-Y";
36 const XML_ID_PREFIX = "ymarket_";
37
38 const TRADING_PLATFORM_CODE = "ymarket";
39
40 protected $communicationFormat = self::JSON;
41 protected $siteId = "";
42 protected $authType = "HEADER"; // or URL
43
45 const LOG_LEVEL_ERROR = 10;
46 const LOG_LEVEL_INFO = 20;
47 const LOG_LEVEL_DEBUG = 30;
48
51
52 protected $logLevel = self::LOG_LEVEL_ERROR;
53
54 protected $oAuthToken = null;
55 protected $oAuthClientId = null;
56 protected $oAuthLogin = null;
57
58 protected $mapDelivery = array();
59 protected $outlets = array();
60 protected $mapPaySystems = array();
61
62 protected $personTypeId = null;
63 protected $campaignId = null;
64 protected $yandexApiUrl = null;
65 protected $yandexToken = null;
66 protected $orderProps = array(
67 "FIO" => "FIO",
68 "EMAIL" => "EMAIL",
69 "PHONE" => "PHONE",
70 "ZIP" => "ZIP",
71 "CITY" => "CITY",
72 "LOCATION" => "LOCATION",
73 "ADDRESS" => "ADDRESS"
74 );
75
76 protected $locationMapper = null;
77 protected $active = true;
78 protected $isAcceptOldPrice = self::NOT_ACCEPT_OLD_PRICE;
79 protected $defaultDeliveryPeriodFrom = 7; //days
82
83 protected static $isYandexRequest = false;
84
89 public function __construct($arParams = array())
90 {
91 $this->siteId = $this->getSiteId($arParams);
92
93 $settings = $this->getSettingsBySiteId($this->siteId);
94
95 if(isset($settings["OAUTH_TOKEN"]))
96 $this->oAuthToken = $settings["OAUTH_TOKEN"];
97
98 if(isset($settings["OAUTH_CLIENT_ID"]))
99 $this->oAuthClientId = $settings["OAUTH_CLIENT_ID"];
100
101 if(isset($settings["OAUTH_LOGIN"]))
102 $this->oAuthLogin = $settings["OAUTH_LOGIN"];
103
104 if(isset($settings["DELIVERIES"]))
105 $this->mapDelivery = $settings["DELIVERIES"];
106
107 if(isset($settings["OUTLETS_IDS"]))
108 $this->outlets = $settings["OUTLETS_IDS"];
109
110 if(isset($settings["PAY_SYSTEMS"]))
111 $this->mapPaySystems = $settings["PAY_SYSTEMS"];
112
113 if(isset($settings["PERSON_TYPE"]))
114 $this->personTypeId = $settings["PERSON_TYPE"];
115
116 if(isset($settings["CAMPAIGN_ID"]))
117 $this->campaignId = $settings["CAMPAIGN_ID"];
118
119 if(isset($settings["YANDEX_URL"]))
120 $this->yandexApiUrl = $settings["YANDEX_URL"];
121
122 if(isset($settings["YANDEX_TOKEN"]))
123 $this->yandexToken = $settings["YANDEX_TOKEN"];
124
125 if(isset($settings["AUTH_TYPE"]))
126 $this->authType = $settings["AUTH_TYPE"];
127
128 if(isset($settings["DATA_FORMAT"]))
129 $this->communicationFormat = $settings["DATA_FORMAT"];
130
131 if(isset($settings["LOG_LEVEL"]))
132 $this->logLevel = $settings["LOG_LEVEL"];
133
134 if(isset($settings["ORDER_PROPS"]) && is_array($settings["ORDER_PROPS"]))
135 $this->orderProps = $settings["ORDER_PROPS"];
136
137 if(isset($settings["IS_ACCEPT_OLD_PRICE"]))
138 $this->isAcceptOldPrice = $settings["IS_ACCEPT_OLD_PRICE"];
139
140 if(isset($settings["PERIOD_FROM"]))
141 $this->defaultDeliveryPeriodFrom = intval($settings["PERIOD_FROM"]);
142
143 if(isset($settings["PERIOD_TO"]))
144 $this->defaultDeliveryPeriodTo = intval($settings["PERIOD_TO"]);
145
146 if(isset($settings["DLV_PS"]))
147 $this->deliveryToPaysystem = $settings["DLV_PS"];
148
149 $this->active = static::isActive();
150 $this->locationMapper = new CSaleYMLocation;
151 }
152
153 public static function isActive()
154 {
155 return YMarket\YandexMarket::getInstance()->isActive();
156 }
157
163 public static function setActivity($activity)
164 {
165 if($activity)
166 static::eventsStart();
167 else
168 static::eventsStop();
169
170 $settings = static::getSettings();
171
172 if($activity && empty($settings) && static::install())
173 {
174 $settings = static::getSettings(false);
175 }
176
177 if(!empty($settings))
178 {
179 if($activity)
181 else
183 }
184 else
185 {
186 $result = false;
187 }
188
189 return $result;
190 }
191
196 protected function checkSiteId($siteId)
197 {
198 $result = false;
199 $rsSites = CSite::GetList('', '', Array(
200 "LID" => $siteId,
201 "ACTIVE"=>"Y"
202 ));
203
204 if($arRes = $rsSites->Fetch())
205 $result = true;
206
207 return $result;
208 }
209
214 protected function getSiteId($arParams)
215 {
216 $result = "";
217
218 if(
219 isset($arParams["SITE_ID"])
220 && $arParams["SITE_ID"] <> ''
221 && $this->checkSiteId($arParams["SITE_ID"])
222 )
223 {
224 $result = $arParams["SITE_ID"];
225 }
226 elseif(defined("SITE_ID"))
227 {
229 }
230 else
231 {
232 $rsSites = CSite::GetList('', '', Array(
233 "ACTIVE"=> "Y",
234 "DEF" => "Y"
235 ));
236
237 if($arRes = $rsSites->Fetch())
238 $result = $arRes["LID"];
239 }
240
241 return $result;
242 }
243
250 public static function getSettings($cached = true)
251 {
252 static $settings = null;
253
254 if($settings === null || !$cached)
255 {
256 $settingsRes = Bitrix\Sale\TradingPlatformTable::getList(array(
257 'filter'=>array('=CODE' => static::TRADING_PLATFORM_CODE)
258 ));
259
260 $settings = $settingsRes->fetch();
261
262 if(!$settings || !is_array($settings))
263 $settings = array();
264 }
265
266 return $settings;
267 }
268
275 public static function getSettingsBySiteId($siteId, $cached = true)
276 {
277 $settings = static::getSettings($cached);
278 return isset($settings["SETTINGS"][$siteId]) ? $settings["SETTINGS"][$siteId] : array();
279 }
280
286 public static function saveSettings($arSettings)
287 {
288 if(!is_array($arSettings))
289 return false;
290
291 $result = true;
292
293 foreach ($arSettings as $siteId => $siteSett)
294 {
295 if(isset($siteSett["OUTLETS_IDS"]) && is_array($siteSett["OUTLETS_IDS"]))
296 {
297 $newOutletsIds = array();
298
299 foreach ($siteSett["OUTLETS_IDS"] as $outletId)
300 if($outletId <> '')
301 $newOutletsIds[] = $outletId;
302
303 $arSettings[$siteId]["OUTLETS_IDS"] = $newOutletsIds;
304 }
305
306 if(isset($arSettings[$siteId]["DELIVERIES"]) && is_array($arSettings[$siteId]["DELIVERIES"]))
307 {
308 foreach($arSettings[$siteId]["DELIVERIES"] as $id => $type)
309 {
310 if($type == '')
311 {
312 unset($arSettings[$siteId]["DELIVERIES"][$id]);
313 unset($arSettings[$siteId]["DLV_PS"][$id]);
314 continue;
315 }
316
317 foreach(self::getExistPaymentMethods() as $methodIdx => $method)
318 if(!isset($arSettings[$siteId]["DLV_PS"][$id][$methodIdx]) || $arSettings[$siteId]["DLV_PS"][$id][$methodIdx] != 'Y')
319 $arSettings[$siteId]["DLV_PS"][$id][$methodIdx] = 'N';
320 }
321 }
322 }
323
324 $settings = static::getSettings(false);
325
326 if(!empty($settings))
327 {
328 if(is_array($settings))
329 $result = Bitrix\Sale\TradingPlatformTable::update(
331 array("SETTINGS" => $arSettings)
332 );
333 }
334 else
335 {
336 $result = false;
337 }
338
339 return $result;
340 }
341
347 public function getTimeInterval($period, $type)
348 {
349 $interval = 'P';
350
351 if($type == 'H' || $type == 'MIN')
352 $interval .= 'T';
353
354 $interval .= strval(intval($period));
355
356 if($type == 'MIN')
357 $type = 'M';
358
359 $interval .= $type;
360
361 return new DateInterval($interval);
362 }
363
369 protected function checkTimeInterval($today, $nextDate)
370 {
371 $interval = $today->diff($nextDate);
372 return (intval($interval->format('%a')) <= 92);
373 }
374
381 protected function getDeliveryDates($from, $to, $type)
382 {
383 $from = intval($from);
384 $to = intval($to);
385 $arResult = array();
386
387 if($from <= $to)
388 {
389 $today = new DateTime('now', new DateTimeZone('Europe/Moscow'));
390 $dateFrom = new DateTime('now', new DateTimeZone('Europe/Moscow'));
391 $dateFrom->add($this->getTimeInterval($from, $type));
392
393 if($this->checkTimeInterval($today, $dateFrom))
394 {
395 $arResult["fromDate"] = $dateFrom->format(self::DATE_FORMAT);
396 $dateTo = $today->add($this->getTimeInterval($to, $type));
397
398 if($this->checkTimeInterval($today, $dateTo))
399 $arResult["toDate"] = $dateTo->format(self::DATE_FORMAT);
400 }
401 }
402
403 return $arResult;
404 }
405
409 protected function getPaymentMethods()
410 {
411 $result = array();
412
413 foreach ($this->mapPaySystems as $psType => $psId)
414 if(isset($psId) && intval($psId) > 0)
415 $result[] = $psType;
416
417 return $result;
418 }
419
424 protected function checkCartStructure($arPostData)
425 {
426 return isset($arPostData["cart"])
427 && isset($arPostData["cart"]["items"])
428 && is_array($arPostData["cart"]["items"])
429 && isset($arPostData["cart"]["currency"])
430 && isset($arPostData["cart"]["delivery"])
431 && is_array($arPostData["cart"]["delivery"]);
432 }
433
441 protected function processCartRequest($arPostData)
442 {
443 if(!$this->checkCartStructure($arPostData))
444 return $this->processError(self::ERROR_STATUS_400, GetMessage("SALE_YMH_ERROR_BAD_STRUCTURE"));
445
446 $result = array(
447 "cart" => array(
448 "items" => array(),
449 "paymentMethods" => array(),
450 "deliveryOptions" => array()
451 )
452 );
453
454 $locationId = 0;
455
456 if($this->orderProps["LOCATION"] <> '')
457 {
458 $locationId = $this->locationMapper->getLocationId($arPostData["cart"]["delivery"]["region"]);
459
460 if(intval($locationId) <= 0)
461 {
462 $this->log(
463 self::LOG_LEVEL_INFO,
464 "YMARKET_LOCATION_MAPPING",
465 $arPostData["cart"]["delivery"]["region"]["name"],
466 GetMessage("SALE_YMH_LOCATION_NOT_FOUND")
467 );
468
469 return $result;
470 }
471 }
472
473 $properties = $this->makeAdditionalOrderProps(
474 $arPostData["cart"]["delivery"]["address"],
475 array(),
476 '',
477 '',
478 $locationId
479 );
480
481 $res = \Bitrix\Sale\TradingPlatform\YMarket\Order::create(array(
482 'CURRENCY' => $arPostData['cart']['currency'],
483 'SITE_ID' => $this->siteId,
484 'PERSON_TYPE_ID' => $this->personTypeId,
485 'PROPERTIES' => $properties,
486 'CART_ITEMS' => $arPostData['cart']['items']
487 ));
488
489 if(!$res->isSuccess())
490 {
491 $this->log(
492 self::LOG_LEVEL_ERROR,
493 "YMARKET_ORDER_CREATE_ERROR",
494 'processCartRequest',
495 implode('; ',$res->getErrorMessages())
496 );
497
498 return $result;
499 }
500
501 $data = $res->getData();
503 $order = $data['ORDER'];
504 $basket = $order->getBasket();
505 $resultItems = array();
506 $items = $arPostData['cart']['items'];
507 $itemKeyToBasketCode = array_flip($data['ITEMS_MAP']);
509 foreach($items as $itemKey => $item)
510 {
511 $price = 0;
512 $count = 0;
513
514 if(!empty($itemKeyToBasketCode[$itemKey]))
515 {
516 $basketCode = $itemKeyToBasketCode[$itemKey];
517 $basketItem = $basket->getItemByBasketCode($basketCode);
518
519 if(!$basketItem)
520 continue;
521
522 $price = round(floatval($basketItem->getPrice()), 2);
523
524 if($price <= 0)
525 continue;
526
527 $count = $basketItem->getQuantity();
528 }
529
530 $resItem = array(
531 'feedId' => $item['feedId'],
532 'offerId' => $item['offerId'],
533 'count' => $count,
534 'delivery' => $count > 0 ? TRUE : FALSE
535 );
536
537 if($count > 0)
538 $resItem['price'] = $price;
539
540 $resultItems[] = $resItem;
541 }
542
543 $shipment = YMarket\Order::createShipment($order);
544 YMarket\Order::createPayment($order);
545 $deliveryObjs = Delivery\Services\Manager::getRestrictedObjectsList(
546 $shipment,
547 Delivery\Restrictions\Manager::MODE_CLIENT
548 );
549
550 $deliveryOptions = array();
551
553 foreach($deliveryObjs as $delivery)
554 {
555 if(empty($this->mapDelivery[$delivery->getId()]))
556 continue;
557
558 $orderClone = $order->createClone();
559 $clonedShipment = null;
560 $orderClone->isStartField();
561
562 foreach ($orderClone->getShipmentCollection() as $shp)
563 {
564 if($shp->isSystem())
565 continue;
566
567 $clonedShipment = $shp;
568 break;
569 }
570
572 $clonedShipment->setDeliveryService($delivery);
573 $deliveryCalcRes = $orderClone->getShipmentCollection()->calculateDelivery();
574
575 if(!$deliveryCalcRes->isSuccess())
576 continue;
577
578 $orderClone->doFinalAction(true);
579 $calcResult = $clonedShipment->calculateDelivery();
580
581 if(!$calcResult->isSuccess())
582 continue;
583
584 $dateFrom = $calcResult->getPeriodFrom();
585 $dateTo = $calcResult->getPeriodTo();
586
587 if($dateFrom === null)
589
590 if($dateTo === null)
592
593 $arDates = $this->getDeliveryDates($dateFrom, $dateTo, $calcResult->getPeriodType());
594
595 if(!empty($arDates))
596 {
597 $deliveryType = $this->mapDelivery[$delivery->getId()];
598
599 $arDeliveryTmp = array(
600 "id" => $delivery->getId(),
601 "type" => $deliveryType,
602 "serviceName" => mb_substr($delivery->getNameWithParent(), 0, 50),
603 "price" => round(floatval($orderClone->getDeliveryPrice()), 2),
604 "dates" => $arDates
605 );
606
607 $dlvToPs = array();
608 $payMethods = self::getExistPaymentMethods();
609
610 if(!empty($this->deliveryToPaysystem[$delivery->getId()]) && is_array($this->deliveryToPaysystem[$delivery->getId()]))
611 foreach($this->deliveryToPaysystem[$delivery->getId()] as $methodIdx => $value)
612 if($value == 'Y' && !empty($payMethods[$methodIdx]))
613 $dlvToPs[] = $payMethods[$methodIdx];
614
615 if(!empty($dlvToPs))
616 $arDeliveryTmp["paymentMethods"] = $dlvToPs;
617
618 if($deliveryType == "PICKUP" && !empty($this->outlets))
619 foreach($this->outlets as $outlet)
620 $arDeliveryTmp["outlets"][] = array("id" => intval($outlet));
621
622 $deliveryOptions[] = $arDeliveryTmp;
623 }
624 }
625
626 if(!empty($resultItems) && !empty($deliveryOptions))
627 {
628 $result['cart']['items'] = $resultItems;
629 $result['cart']['deliveryOptions'] = $deliveryOptions;
630 $result['cart']['paymentMethods'] = $this->getPaymentMethods();
631 }
632
633 return $result;
634 }
635
641 protected function processCustomEvents($eventName, array $params)
642 {
643 $event = new Event('sale', $eventName, $params);
644 $event->send();
645 $resultList = $event->getResults();
646 $result = $params["RESULT"];
647
648 if (is_array($resultList) && !empty($resultList))
649 {
650 foreach ($resultList as &$eventResult)
651 {
652 if ($eventResult->getType() != EventResult::SUCCESS)
653 continue;
654
655 $params = $eventResult->getParameters();
656
657 if(isset($params["RESULT"]))
658 $result = $params["RESULT"];
659 }
660 }
661
662 return $result;
663 }
664
669 protected function checkOrderAcceptStructure($arPostData)
670 {
671 return isset($arPostData["order"])
672 && isset($arPostData["order"]["id"])
673 && isset($arPostData["order"]["currency"])
674 && isset($arPostData["order"]["fake"])
675 && isset($arPostData["order"]["items"]) && is_array($arPostData["order"]["items"])
676 && isset($arPostData["order"]["delivery"]) && is_array($arPostData["order"]["delivery"]);
677 }
678
685 protected function createUser($buyer, $address, $region)
686 {
687 $userRegister = array(
688 "NAME" => $buyer["firstName"],
689 "PERSONAL_MOBILE" => $buyer["phone"]
690 );
691
692 if(isset($buyer["lastName"]))
693 $userRegister["LAST_NAME"] = $buyer["lastName"];
694
695 if(isset($buyer["middleName"]))
696 $userRegister["SECOND_NAME"] = $buyer["middleName"];
697
698 $arPersonal = array();
699
700 if($buyer["phone"] <> '')
701 $arPersonal = array("PERSONAL_MOBILE" => $buyer["phone"]);
702
703 $arErrors = array();
705 $buyer["email"],
706 $userRegister,
707 $this->siteId,
708 $arErrors,
709 $arPersonal);
710
711 $this->log(
712 empty($arErrors) ? self::LOG_LEVEL_INFO : self::LOG_LEVEL_ERROR,
713 "YMARKET_USER_CREATE",
714 $userId ? $userId : print_r($buyer, true),
715 empty($arErrors) ? GetMessage("SALE_YMH_USER_PROFILE_CREATED") : print_r($arErrors, true)
716 );
717
718 return $userId;
719 }
720
729 protected function makeAdditionalOrderProps($address, $buyer, $psId, $deliveryId, $locationId)
730 {
731 $psId = intval($psId);
732 $arResult = array();
733
734 $arPropFilter = array(
735 "PERSON_TYPE_ID" => $this->personTypeId,
736 "ACTIVE" => "Y"
737 );
738
739 if ($psId != 0)
740 {
741 $arPropFilter["RELATED"]["PAYSYSTEM_ID"] = $psId;
742 $arPropFilter["RELATED"]["TYPE"] = "WITH_NOT_RELATED";
743 }
744
745 if ($deliveryId <> '')
746 {
747 $arPropFilter["RELATED"]["DELIVERY_ID"] = $deliveryId;
748 $arPropFilter["RELATED"]["TYPE"] = "WITH_NOT_RELATED";
749 }
750
751 $dbOrderProps = CSaleOrderProps::GetList(
752 array(),
753 $arPropFilter,
754 false,
755 false,
756 array("ID", "CODE")
757 );
758
759 while ($arOrderProps = $dbOrderProps->Fetch())
760 {
761 if($this->orderProps["FIO"] <> '' && $arOrderProps["CODE"] == $this->orderProps["FIO"] && !empty($buyer))
762 {
763 $fio = $buyer["firstName"];
764
765 if(isset($buyer["middleName"]))
766 $fio .= ' '.$buyer["middleName"];
767
768 if(isset($buyer["lastName"]))
769 $fio .= ' '.$buyer["lastName"];
770
771 $arResult[$arOrderProps["ID"]] = $fio;
772 }
773 elseif($this->orderProps["EMAIL"] <> '' && $arOrderProps["CODE"] == $this->orderProps["EMAIL"] && isset($buyer["email"]))
774 $arResult[$arOrderProps["ID"]] = $buyer["email"];
775 elseif($this->orderProps["PHONE"] <> '' && $arOrderProps["CODE"] == $this->orderProps["PHONE"] && isset($buyer["phone"]))
776 $arResult[$arOrderProps["ID"]] = $buyer["phone"];
777 elseif($this->orderProps["ZIP"] <> '' && $arOrderProps["CODE"] == $this->orderProps["ZIP"] && isset($address["postcode"]))
778 $arResult[$arOrderProps["ID"]] = $address["postcode"];
779 elseif($this->orderProps["CITY"] <> '' && $arOrderProps["CODE"] == $this->orderProps["CITY"])
780 $arResult[$arOrderProps["ID"]] = $address["city"];
781 elseif($this->orderProps["LOCATION"] <> '' && $arOrderProps["CODE"] == $this->orderProps["LOCATION"])
782 {
783 if($locationId > 0)
784 {
785 $dbRes = \Bitrix\Sale\Location\LocationTable::getById($locationId);
786
787 if($loc = $dbRes->fetch())
788 $arResult[$arOrderProps["ID"]] = $loc['CODE'];
789 }
790 }
791 elseif($this->orderProps["ADDRESS"] <> '' && $arOrderProps["CODE"] == $this->orderProps["ADDRESS"])
792 $arResult[$arOrderProps["ID"]] = $this->createAddressString($address);
793 }
794
795 return $arResult;
796 }
797
798 protected function createAddressString($address)
799 {
800 $strAddr = "";
801
802 if(isset($address["postcode"]))
803 $strAddr .= $address["postcode"].", ";
804
805 $strAddr .= $address["country"].", ".$address["city"].", ";
806
807 if(isset($address["street"]))
808 $strAddr .= GetMessage("SALE_YMH_ADDRESS_STREET")." ".$address["street"].", ";
809
810 if(isset($address["subway"]))
811 $strAddr .= GetMessage("SALE_YMH_ADDRESS_SUBWAY")." ".$address["subway"].", ";
812
813 $strAddr .= GetMessage("SALE_YMH_ADDRESS_HOUSE")." ".$address["house"];
814
815 if(isset($address["block"]))
816 $strAddr .= ", ".GetMessage("SALE_YMH_ADDRESS_BLOCK")." ".$address["block"];
817
818 if(isset($address["entrance"]))
819 $strAddr .= ", ".GetMessage("SALE_YMH_ADDRESS_ENTRANCE")." ".$address["entrance"];
820
821 if(isset($address["entryphone"]))
822 $strAddr .= ", ".GetMessage("SALE_YMH_ADDRESS_ENTRYPHONE")." ".$address["entryphone"];
823
824 if(isset($address["floor"]))
825 $strAddr .= ", ".GetMessage("SALE_YMH_ADDRESS_FLOOR")." ".$address["floor"];
826
827 if(isset($address["apartment"]))
828 $strAddr .= ", ".GetMessage("SALE_YMH_ADDRESS_APARTMENT")." ".$address["apartment"];
829
830 if(isset($address["recipient"]))
831 $strAddr .= ", ".GetMessage("SALE_YMH_ADDRESS_RECIPIENT")." ".$address["recipient"];
832
833 if(isset($address["phone"]))
834 $strAddr .= ", ".GetMessage("SALE_YMH_ADDRESS_PHONE")." ".$address["phone"];
835
836 return $strAddr;
837 }
838
848 protected function processOrderAcceptRequest($arPostData)
849 {
850 if(!$this->checkOrderAcceptStructure($arPostData))
851 return $this->processError(self::ERROR_STATUS_400, GetMessage("SALE_YMH_ERROR_BAD_STRUCTURE"));
852
853 $deliveryId = $arPostData["order"]["delivery"]["id"];
854 $paySystemId = $this->mapPaySystems[$arPostData["order"]["paymentMethod"]];
855
856 $result = array(
857 'order' => array(
858 'accepted' => false,
859 'reason' => 'OUT_OF_DATE'
860 )
861 );
862
863 if(!Loader::includeModule('iblock'))
864 return $result;
865
866 if(!Loader::includeModule('catalog'))
867 return $result;
868
869 $dbRes = \Bitrix\Sale\TradingPlatform\OrderTable::getList(array(
870 "filter" => array(
871 "TRADING_PLATFORM_ID" => YMarket\YandexMarket::getInstance()->getId(),
872 "EXTERNAL_ORDER_ID" => $arPostData["order"]["id"]
873 )
874 ));
875
876 $orderId = 0;
877
878 if($orderCorrespondence = $dbRes->fetch())
879 $orderId = $orderCorrespondence["ORDER_ID"];
880
881 if($orderId <= 0)
882 {
883 $locationId = 0;
884
885 if($this->orderProps["LOCATION"] <> '')
886 {
887 $locationId = $this->locationMapper->getLocationId($arPostData["order"]["delivery"]["region"]);
888
889 if(intval($locationId) <= 0)
890 {
891 $this->log(
892 self::LOG_LEVEL_INFO,
893 "YMARKET_LOCATION_MAPPING",
894 $arPostData["order"]["delivery"]["region"]["name"],
895 GetMessage("SALE_YMH_LOCATION_NOT_FOUND")
896 );
897
898 return $result;
899 }
900 }
901
902 $properties = $this->makeAdditionalOrderProps(
903 $arPostData["order"]["delivery"]["address"],
904 array(),
905 $paySystemId,
906 $deliveryId,
907 $locationId
908 );
909
910 $res = \Bitrix\Sale\TradingPlatform\YMarket\Order::create(array(
911 'CURRENCY' => $arPostData['order']['currency'],
912 'SITE_ID' => $this->siteId,
913 'PERSON_TYPE_ID' => $this->personTypeId,
914 'PROPERTIES' => $properties,
915 'CART_ITEMS' => $arPostData['order']['items'],
916 'IS_ACCEPT_OLD_PRICE' => $this->isAcceptOldPrice
917 ));
918
919 if(!$res->isSuccess())
920 {
921 $this->log(
922 self::LOG_LEVEL_ERROR,
923 "YMARKET_ORDER_CREATE_ERROR",
924 'processOrderAcceptRequest',
925 implode('; ',$res->getErrorMessages())
926 );
927
928 return $result;
929 }
930
931 $data = $res->getData();
933 $order = $data['ORDER'];
934
935 if(!$this->checkBasketPrice($arPostData['order']['items'], $order))
936 {
937 if($this->isAcceptOldPrice == \CSaleYMHandler::ACCEPT_OLD_PRICE)
938 {
939 $this->setBasketOldPrice($arPostData['order']['items'], $order);
940 $order->setField(
941 "COMMENTS",
942 GetMessage('SALE_YMARKET_ORDER_PRICE_CHANGED')
943 );
944 }
945 else
946 {
947 return $result;
948 }
949 }
950
951 YMarket\Order::createShipment($order, $deliveryId, $arPostData["order"]["delivery"]["price"]);
952 YMarket\Order::createPayment($order, $paySystemId);
953 $order->setField("PRICE", $order->getPrice());
954 $order->setField("XML_ID", self::XML_ID_PREFIX.$arPostData["order"]["id"]);
955
956 /* PRODUCT_XML_ID CATALOG_XML_ID */
957 $xmls = array();
958 $productIds = array();
959
960 foreach ($arPostData["order"]["items"] as $item)
961 $productIds[] = $item['offerId'];
962
963 $dbRes = \Bitrix\Iblock\ElementTable::getList(array(
964 'filter' => array(
965 '=ID' => $productIds
966 ),
967 'select' => array(
968 'ID', 'XML_ID',
969 'IBLOCK_EXTERNAL_ID' => 'IBLOCK.XML_ID',
970 )
971 ));
972
973 $parentsIds = array();
974
975 while($iblockElement = $dbRes->fetch())
976 {
977 $xmls[$iblockElement['ID']] = array();
978
979 if($iblockElement["XML_ID"] <> '')
980 $xmls[$iblockElement['ID']]["PRODUCT_XML_ID"] = $iblockElement["XML_ID"];
981
982 if($iblockElement["IBLOCK_EXTERNAL_ID"] <> '')
983 $xmls[$iblockElement['ID']]["CATALOG_XML_ID"] = $iblockElement["IBLOCK_EXTERNAL_ID"];
984
985 if(mb_strpos($iblockElement["XML_ID"], '#') === false && $parent = \CCatalogSku::GetProductInfo($iblockElement['ID']))
986 $parentsIds[$iblockElement['ID']] = $parent['ID'];
987 }
988
989 if(!empty($parentsIds))
990 {
991 $dbRes = \Bitrix\Iblock\ElementTable::getList(array(
992 'filter' => array('=ID' => array_unique($parentsIds)),
993 'select' => array('ID', 'XML_ID')
994 ));
995
996 while($parent = $dbRes->fetch())
997 {
998 if($parent['XML_ID'] == '')
999 continue;
1000
1001 foreach($parentsIds as $childId => $parentId)
1002 if($parentId == $parent['ID'])
1003 $xmls[$childId]["PRODUCT_XML_ID"] = $parent['XML_ID'].'#'.$xmls[$childId]["PRODUCT_XML_ID"];
1004 }
1005 }
1006 /* */
1007
1008 $basket = $order->getBasket();
1010 foreach($basket->getBasketItems() as $basketItem)
1011 {
1012 $productId = $basketItem->getProductId();
1013
1014 if(!empty($xmls[$productId]['PRODUCT_XML_ID']))
1015 $basketItem->setField("PRODUCT_XML_ID", $xmls[$productId]['PRODUCT_XML_ID']);
1016
1017 if(!empty($xmls[$productId]['CATALOG_XML_ID']))
1018 $basketItem->setField("CATALOG_XML_ID", $xmls[$productId]['CATALOG_XML_ID']);
1019 }
1020
1021 if(!empty($arPostData["order"]["notes"]))
1022 $order->setField('USER_DESCRIPTION', $arPostData["order"]["notes"]);
1023
1024 //Let's mark order that we don't have info about buyer yet.
1025 $r = new \Bitrix\Sale\Result();
1026 $r->addWarning(new \Bitrix\Main\Error(GetMessage('SALE_YMH_MARK_BUYER_WAITING'), 'YMARKET_BUYER_INFO_WAITING'));
1027 \Bitrix\Sale\EntityMarker::addMarker($order, $order, $r);
1028 $order->setField('MARKED', 'Y');
1029
1030 $res = $order->save();
1031
1032 if(!$res->isSuccess())
1033 {
1034 $this->log(
1035 self::LOG_LEVEL_ERROR,
1036 "YMARKET_PLATFORM_ORDER_ADD_ERROR",
1037 $arPostData["order"]["id"],
1038 implode('; ', $res->getErrorMessages())
1039 );
1040
1041 return $result;
1042 }
1043
1044 if (\Bitrix\Sale\Integration\Numerator\NumeratorOrder::isUsedNumeratorForOrder())
1045 {
1046 $orderId = $order->getField('ACCOUNT_NUMBER');
1047 }
1048 else
1049 {
1050 $orderId = $order->getId();
1051 }
1052
1053 $res = \Bitrix\Sale\TradingPlatform\OrderTable::add(array(
1054 "ORDER_ID" => $res->getId(),
1055 "TRADING_PLATFORM_ID" => YMarket\YandexMarket::getInstance()->getId(),
1056 "EXTERNAL_ORDER_ID" => $arPostData["order"]["id"]
1057 ));
1058
1059 if(!$res->isSuccess())
1060 {
1061 $this->log(
1062 self::LOG_LEVEL_ERROR,
1063 "YMARKET_PLATFORM_ORDER_ADD_ERROR",
1064 $arPostData["order"]["id"],
1065 implode('; ', $res->getErrorMessages())
1066 );
1067
1068 return $result;
1069 }
1070 }
1071
1072 $result["order"]["accepted"] = TRUE;
1073 $result["order"]["id"] = '"'.$orderId.'"';
1074 unset($result["order"]["reason"]);
1075
1076 $this->log(
1077 self::LOG_LEVEL_INFO,
1078 "YMARKET_ORDER_CREATE",
1079 $arPostData["order"]["id"],
1080 GetMessage("SALE_YMH_ORDER_CREATED")." ".$orderId
1081 );
1082
1083 return $result;
1084 }
1085
1086 protected function checkBasketPrice(array $items, \Bitrix\Sale\Order $order)
1087 {
1088 $yandexBasketPrice = 0;
1089
1090 foreach($items as $item)
1091 if(isset($item['price']))
1092 $yandexBasketPrice += $item['price']*$item['count'];
1093
1094 return round($order->getBasket()->getPrice(), 2) == round($yandexBasketPrice, 2);
1095 }
1096
1097 protected function setBasketOldPrice(array $items, \Bitrix\Sale\Order $order)
1098 {
1099 $basket = $order->getBasket();
1100
1102 foreach($basket->getBasketItems() as $basketItem)
1103 {
1104 foreach($items as $key => $item)
1105 {
1106 if($item['offerId'] != $basketItem->getProductId())
1107 continue;
1108
1109 $basketItem->setField("CUSTOM_PRICE", 'Y');
1110 $basketItem->setField("PRICE", $item['price']);
1111 unset($items[$key]);
1112 }
1113 }
1114 }
1115
1120 protected function checkOrderStatusRequest($arPostData)
1121 {
1122 return
1123 (isset($arPostData["order"])
1124 && isset($arPostData["order"]["id"])
1125 && isset($arPostData["order"]["currency"])
1126 && isset($arPostData["order"]["creationDate"])
1127 && isset($arPostData["order"]["itemsTotal"])
1128 && isset($arPostData["order"]["total"])
1129 && isset($arPostData["order"]["status"])
1130 && isset($arPostData["order"]["fake"])
1131 && isset($arPostData["order"]["buyer"])
1132 && isset($arPostData["order"]["items"]) && is_array($arPostData["order"]["items"])
1133 && isset($arPostData["order"]["delivery"]) && is_array($arPostData["order"]["delivery"])) || true;
1134 }
1135
1145 protected function processOrderStatusRequest($arPostData)
1146 {
1147 $arResult = array();
1148 if($this->checkOrderStatusRequest($arPostData))
1149 {
1150 $registry = \Bitrix\Sale\Registry::getInstance(\Bitrix\Sale\Registry::REGISTRY_TYPE_ORDER);
1151
1153 $orderClass = $registry->getOrderClassName();
1154
1155 $dbOrder = $orderClass::getList(array(
1156 'filter' => array("XML_ID" => self::XML_ID_PREFIX.$arPostData["order"]["id"]),
1157 'select' => array('ID', 'LID', 'XML_ID')
1158 ));
1159
1160 if($arOrder = $dbOrder->fetch())
1161 {
1162 $order = $orderClass::load($arOrder['ID']);
1163 $reason = "";
1164
1165 switch ($arPostData["order"]["status"])
1166 {
1167 case 'PROCESSING':
1168 $locationId = $this->locationMapper->getLocationId($arPostData["order"]["delivery"]["region"]);
1169
1170 if($locationId === false)
1171 {
1172 $this->log(
1173 self::LOG_LEVEL_INFO,
1174 "YMARKET_LOCATION_MAPPING",
1175 $arPostData["order"]["delivery"]["region"]["name"],
1176 GetMessage("SALE_YMH_LOCATION_NOT_FOUND")
1177 );
1178 }
1179
1180 if(isset($arPostData["order"]["paymentMethod"]) && $arPostData["order"]["paymentMethod"] == "YANDEX")
1181 {
1182 $paymentCollection = $order->getPaymentCollection();
1183
1185 if($paymentCollection->count() > 0)
1186 {
1187 foreach ($paymentCollection as $payment)
1188 {
1189 $res = $payment->setPaid("Y");
1190
1191 if(!$res->isSuccess())
1192 {
1193 $this->log(
1194 self::LOG_LEVEL_INFO,
1195 "YMARKET_INCOMING_ORDER_STATUS",
1196 'Set order paid',
1197 implode('; ',$res->getErrorMessages())
1198 );
1199 }
1200 }
1201 }
1202 }
1203
1204 $arOrderPropsValues = $this->makeAdditionalOrderProps(
1205 $arPostData["order"]["delivery"]["address"],
1206 $arPostData["order"]["buyer"],
1207 isset($this->mapPaySystems[$arPostData["order"]["paymentMethod"]]) ? $this->mapPaySystems[$arPostData["order"]["paymentMethod"]] : "",
1208 $arPostData["order"]["delivery"]["id"],
1209 $locationId
1210 );
1211
1212 if(!empty($arOrderPropsValues))
1213 {
1214 $propCollection = $order->getPropertyCollection();
1215 $res = $propCollection->setValuesFromPost(array('PROPERTIES' => $arOrderPropsValues), array());
1216
1217 if(!$res->isSuccess())
1218 {
1219 $this->log(
1220 self::LOG_LEVEL_INFO,
1221 "YMARKET_INCOMING_ORDER_STATUS",
1222 'Set order properties',
1223 implode('; ',$res->getErrorMessages())
1224 );
1225 }
1226 }
1227
1228 if($order->getUserId() == \CSaleUser::GetAnonymousUserID())
1229 {
1230 $userId = $this->createUser($arPostData["order"]["buyer"], null, null);
1231
1232 if(intval($userId) > 0)
1233 {
1234 $order->setFieldNoDemand("USER_ID", $userId);
1235
1236 EntityMarker::deleteByFilter(array(
1237 '=ORDER_ID' => $order->getId(),
1238 '=ENTITY_TYPE' => EntityMarker::ENTITY_TYPE_ORDER,
1239 '=ENTITY_ID' => $order->getId(),
1240 '=CODE' => 'YMARKET_BUYER_INFO_WAITING'
1241 ));
1242
1243 $order->setField('MARKED', 'N');
1244 }
1245 }
1246
1247 if(!empty($arPostData["order"]["notes"]) && $order->getField('USER_DESCRIPTION') != $arPostData["order"]["notes"])
1248 $order->setField('USER_DESCRIPTION', $order->getField('USER_DESCRIPTION')."\n".$arPostData["order"]["notes"]);
1249
1250 $res = $order->save();
1251
1252 if(!$res->isSuccess())
1253 {
1254 $this->log(
1255 self::LOG_LEVEL_INFO,
1256 "YMARKET_INCOMING_ORDER_STATUS",
1257 'Save order',
1258 implode('; ',$res->getErrorMessages())
1259 );
1260 }
1261
1262 $this->sendEmailNewOrder($arOrder["ID"], $arPostData["order"]["buyer"]);
1263
1264 if(!empty($arErrors))
1265 {
1266 $this->log(
1267 self::LOG_LEVEL_ERROR,
1268 "YMARKET_INCOMING_ORDER_STATUS",
1269 $arPostData["order"]["id"],
1270 print_r($arErrors, true)
1271 );
1272 }
1273 else
1274 {
1275 $this->log(
1276 self::LOG_LEVEL_INFO,
1277 "YMARKET_INCOMING_ORDER_STATUS",
1278 $arPostData["order"]["id"],
1279 GetMessage("SALE_YMH_INCOMING_ORDER_STATUS_PROCESSING").": ".$arOrder["ID"]
1280 );
1281 }
1282
1283 break;
1284
1285 case 'UNPAID':
1286 case 'DELIVERY':
1287 case 'PICKUP':
1288 case 'DELIVERED ':
1289 case 'RESERVED ':
1290 break;
1291
1292 case 'CANCELLED':
1293 if(isset($arPostData["order"]["substatus"]))
1294 $reason = $arPostData["order"]["substatus"];
1295 break;
1296
1297 default:
1298 $arResult = $this->processError(self::ERROR_STATUS_400, GetMessage("SALE_YMH_ERROR_UNKNOWN_STATUS"));
1299 break;
1300 }
1301
1302 $this->mapYandexStatusToOrder($arOrder, $arPostData["order"]["status"], $reason);
1303 }
1304 }
1305 else
1306 {
1307 $arResult = $this->processError(self::ERROR_STATUS_400, GetMessage("SALE_YMH_ERROR_BAD_STRUCTURE"));
1308 }
1309
1310 return $arResult;
1311 }
1312
1317 protected function extractPostData($postData)
1318 {
1319 global $APPLICATION;
1320 $arResult = array();
1321
1322 if($this->communicationFormat == self::JSON)
1323 {
1324 $arResult = json_decode($postData, true);
1325 }
1326
1327 return $arResult;
1328 }
1329
1334 protected function prepareResult($arData)
1335 {
1336 global $APPLICATION;
1337 $result = array();
1338
1339 if($this->communicationFormat == self::JSON)
1340 {
1341 header('Content-Type: application/json');
1342 $result = json_encode($arData);
1343 }
1344
1345 return $result;
1346 }
1347
1353 public function checkAuth()
1354 {
1355 $incomingToken = "";
1356
1357 if($this->authType == "HEADER")
1358 {
1359 if(isset($_SERVER["REMOTE_USER"]) && $_SERVER["REMOTE_USER"] <> '')
1360 $incomingToken = $_SERVER["REMOTE_USER"];
1361 elseif(isset($_SERVER["REDIRECT_REMOTE_USER"]) && $_SERVER["REDIRECT_REMOTE_USER"] <> '')
1362 $incomingToken = $_SERVER["REDIRECT_REMOTE_USER"];
1363 elseif(isset($_SERVER["HTTP_AUTHORIZATION"]) && $_SERVER["HTTP_AUTHORIZATION"] <> '')
1364 $incomingToken = $_SERVER["HTTP_AUTHORIZATION"];
1365 }
1366 elseif($this->authType == "URL")
1367 {
1368 if(isset($_REQUEST["auth-token"]) && $_REQUEST["auth-token"] <> '')
1369 $incomingToken = $_REQUEST["auth-token"];
1370 }
1371
1372 if($incomingToken == "" && intval($_SERVER["argc"]) > 0)
1373 {
1374 foreach ($_SERVER["argv"] as $arg)
1375 {
1376 $e = explode("=", $arg);
1377
1378 if(count($e) == 2 && $e[0] == "auth-token")
1379 $incomingToken = $e[1];
1380 }
1381 }
1382
1383 return $incomingToken <> '' && $incomingToken == $this->yandexToken;
1384 }
1385
1392 public function processRequest($reqObject, $method, $postData)
1393 {
1394 $arResult = array();
1395 $arPostData = $this->extractPostData($postData);
1396
1397 $this->log(
1398 self::LOG_LEVEL_DEBUG,
1399 "YMARKET_INCOMING_REQUEST",
1400 $reqObject.":".$method,
1401 print_r($arPostData, true)
1402 );
1403
1404 if(!$this->isActive())
1405 {
1406 $arResult = $this->processError(self::ERROR_STATUS_503, GetMessage("SALE_YMH_ERROR_OFF"));
1407 }
1408 elseif(!$this->checkAuth())
1409 {
1410 $arResult = $this->processError(self::ERROR_STATUS_403, GetMessage("SALE_YMH_ERROR_FORBIDDEN"));
1411 }
1412 else
1413 {
1414 self::$isYandexRequest = true;
1416
1417 switch ($reqObject)
1418 {
1419 case 'cart':
1420 $arResult = $this->processCartRequest($arPostData);
1421 break;
1422
1423 case 'order':
1424
1425 if($method == "accept")
1426 $arResult = $this->processOrderAcceptRequest($arPostData);
1427 elseif($method == "status")
1428 $arResult = $this->processOrderStatusRequest($arPostData);
1429 break;
1430
1431 default:
1432 $arResult = $this->processError(self::ERROR_STATUS_400, GetMessage("SALE_YMH_ERROR_UNKNOWN_REQ_OBJ"));
1433 break;
1434 }
1435 }
1436
1437 $this->log(
1438 self::LOG_LEVEL_DEBUG,
1439 "YMARKET_INCOMING_REQUEST_RESULT",
1440 $reqObject.":".$method,
1441 print_r($arResult, true)
1442 );
1443
1445 'OnSaleYandexMarketRequest_'.$reqObject.$method,
1446 array(
1447 "POST_DATA" => $arPostData,
1448 "RESULT" => $arResult
1449 ));
1450
1451 $arPreparedResult = $this->prepareResult($arResult);
1452 return $arPreparedResult;
1453 }
1454
1455
1461 protected function processError($status = "", $message = "")
1462 {
1463 if($status != "")
1465
1466 if($message && $this->logLevel >= self::LOG_LEVEL_ERROR)
1467 $this->log(
1468 self::LOG_LEVEL_ERROR,
1469 "YMARKET_REQUEST_ERROR",
1470 "",
1471 $message);
1472
1473 return array("error" => $message);
1474 }
1475
1482 public function sendStatus($orderId, $status, $substatus = false)
1483 {
1484 global $APPLICATION;
1485
1486 if(
1487 $this->yandexApiUrl == ''
1488 || $this->campaignId == ''
1489 || intval($orderId) <= 0
1490 || $status == ''
1491 || $this->oAuthToken == ''
1492 || $this->oAuthClientId == ''
1493 || $this->oAuthLogin == ''
1494 )
1495 return false;
1496
1497 $format = $this->communicationFormat == self::JSON ? 'json' : 'xml';
1498 $url = $this->yandexApiUrl."campaigns/".$this->campaignId."/orders/".$orderId."/status.".$format;
1499
1500 $http = new \Bitrix\Main\Web\HttpClient(array(
1501 "version" => "1.1",
1502 "socketTimeout" => 30,
1503 "streamTimeout" => 30,
1504 "redirect" => true,
1505 "redirectMax" => 5,
1506 ));
1507
1508 $arQuery = array(
1509 "order" => array(
1510 "status" => $status,
1511 )
1512 );
1513
1514 if($substatus)
1515 $arQuery["order"]["substatus"] = $substatus;
1516
1517 $postData = '';
1518 if($this->communicationFormat == self::JSON)
1519 $postData = json_encode($arQuery);
1520
1521 $http->setHeader("Content-Type", "application/".$format);
1522 $http->setHeader("Authorization", 'OAuth oauth_token="'.$this->oAuthToken.
1523 '", oauth_client_id="'.$this->oAuthClientId.
1524 '", oauth_login="'.$this->oAuthLogin.'"', false);
1525
1526
1527 $result = $http->query("PUT", $url, $postData);
1528 $errors = $http->getError();
1529
1530 if (!$result && !empty($errors))
1531 {
1532 $bResult = false;
1533 $message = "HTTP ERROR: ";
1534
1535 foreach($errors as $errorCode => $errMes)
1536 $message .= $errorCode.": ".$errMes;
1537 }
1538 else
1539 {
1540 $headerStatus = $http->getStatus();
1541
1542 if ($headerStatus == 200)
1543 {
1544 $message = GetMessage("SALE_YMH_STATUS").": ".$status;
1545
1546 if($substatus)
1547 $message .= ' ['.$substatus.']';
1548
1549 $bResult = true;
1550 }
1551 else
1552 {
1553 $res = $http->getResult();
1554 $message = "HTTP error code: ".$headerStatus."(".$res.")";
1555
1556 if($headerStatus == 403)
1557 $this->notifyAdmin("SEND_STATUS_ERROR_403");
1558
1559 if($headerStatus == 500)
1560 {
1561 $intervalSeconds = 3600;
1562 $timeToStart = ConvertTimeStamp(strtotime(date('Y-m-d H:i:s', time() + $intervalSeconds)), 'FULL');
1563 \CAgent::AddAgent(
1564 '\CSaleYMHandler::sendStatusAgent("'.$orderId.'","'.$status.'", "'.$substatus.'", "'.$this->siteId.'");',
1565 'sale',
1566 "N",
1567 $intervalSeconds,
1568 $timeToStart,
1569 "Y",
1570 $timeToStart
1571 );
1572 }
1573
1574 $bResult = false;
1575 }
1576 }
1577
1578 $this->log(
1579 $bResult ? self::LOG_LEVEL_INFO : self::LOG_LEVEL_ERROR,
1580 "YMARKET_STATUS_CHANGE",
1581 $orderId,
1582 $message
1583 );
1584
1585 if(!$bResult)
1586 {
1587 if($order = $this->loadOrderByYandexOrderId($orderId))
1588 {
1589 $r = new \Bitrix\Sale\Result();
1590 $r->addWarning(new \Bitrix\Main\Error($message, 'YMARKET_STATUS_CHANGE_ERROR'));
1591 \Bitrix\Sale\EntityMarker::addMarker($order, $order, $r);
1592 $order->setField('MARKED', 'Y');
1593 $order->save();
1594 }
1595 }
1596
1597 return $bResult;
1598 }
1599
1607 public static function sendStatusAgent($yandexOrderId, $yandexStatus, $substatus, $siteId)
1608 {
1610 array("SITE_ID"=> $siteId)
1611 );
1612
1613 $YMHandler->sendStatus($yandexOrderId, $yandexStatus, $substatus);
1614
1615 return '';
1616 }
1617
1623 public static function getOrderInfo($orderId)
1624 {
1625 if(intval($orderId) <= 0)
1626 return array();
1627
1628 $res = \Bitrix\Sale\Internals\OrderTable::getList(array(
1629 'filter' => array(
1630 '=ID' => $orderId,
1631 '=SOURCE.TRADING_PLATFORM_ID' => YMarket\YandexMarket::getInstance()->getId()
1632 ),
1633 'select' => array("LID", "XML_ID", "YANDEX_ID" => "SOURCE.EXTERNAL_ORDER_ID"),
1634 'runtime' => array(
1635 'SOURCE' => array(
1636 'data_type' => '\Bitrix\Sale\TradingPlatform\OrderTable',
1637 'reference' => array(
1638 'ref.ORDER_ID' => 'this.ID',
1639 ),
1640 'join_type' => 'left'
1641 )
1642 )
1643 ));
1644
1645 if($arOrder = $res->fetch())
1646 return $arOrder;
1647
1648 return array();
1649 }
1650
1655 public static function isOrderFromYandex($orderId)
1656 {
1657 $arOrder = self::getOrderInfo($orderId);
1658 return !empty($arOrder["YANDEX_ID"]);
1659 }
1660
1664 public static function onSaleStatusOrderChange(Bitrix\Main\Event $params)
1665 {
1667 $order = $params->getParameter("ENTITY");
1668 $value = $params->getParameter("VALUE");
1669 $oldValue = $params->getParameter("OLD_VALUE");
1670
1671 if (!static::isOrderEntity($order))
1672 {
1673 return;
1674 }
1675
1676 if($value == $oldValue)
1677 return;
1678
1679 if($order->getId() <= 0)
1680 return;
1681
1682 self::onSaleStatusOrder($order->getId(), $value);
1683 }
1684
1688 public static function onSaleOrderCanceled(Bitrix\Main\Event $params)
1689 {
1690 global $USER;
1691
1693 $order = $params->getParameter("ENTITY");
1694
1695 if (!static::isOrderEntity($order))
1696 {
1697 return;
1698 }
1699
1700 if($order->getId() <= 0)
1701 return;
1702
1703 if(!$order->isCanceled())
1704 return;
1705
1706 $arSubstatuses = self::getOrderSubstatuses();
1707 $description = $order->getField('REASON_CANCELED');
1708
1709 if($description == '' || !$USER->IsAdmin() || empty($arSubstatuses[$description]))
1710 $description = "USER_CHANGED_MIND";
1711
1712 self::onSaleStatusOrder($order->getId(), "CANCELED", $description);
1713 }
1714
1718 public static function onSaleShipmentDelivery(Bitrix\Main\Event $params)
1719 {
1721 $shipment = $params->getParameter("ENTITY");
1722
1723 if (!static::isOrderEntity($shipment))
1724 {
1725 return;
1726 }
1727
1728 if($shipment->getId() <= 0)
1729 return;
1730
1732 $collection = $shipment->getCollection();
1733
1734 if(!$collection->isAllowDelivery())
1735 return;
1736
1737 self::onSaleStatusOrder($shipment->getField('ORDER_ID'), "ALLOW_DELIVERY");
1738 }
1739
1743 public static function onSaleOrderPaid(Bitrix\Main\Event $params)
1744 {
1746 $order = $params->getParameter("ENTITY");
1747
1748 if (!static::isOrderEntity($order))
1749 {
1750 return;
1751 }
1752
1753 if($order->getId() <= 0)
1754 return;
1755
1756 if(!$order->isPaid())
1757 return;
1758
1759 self::onSaleStatusOrder($order->getId(), "PAYED");
1760 }
1761
1765 public static function onShipmentDeducted(Bitrix\Main\Event $params)
1766 {
1768 $shipment = $params->getParameter("ENTITY");
1769
1770 if (!static::isOrderEntity($shipment))
1771 {
1772 return;
1773 }
1774
1775 if($shipment->getId() <= 0)
1776 return;
1777
1779 $collection = $shipment->getCollection();
1780
1781 if(!$collection->isShipped())
1782 return;
1783
1784 self::onSaleStatusOrder($shipment->getField('ORDER_ID'), "DEDUCTED");
1785 }
1786
1795 public static function onSaleStatusOrder($orderId, $status, $substatus = false)
1796 {
1797 if(self::$isYandexRequest)
1798 return false;
1799
1800 if(intval($orderId) <= 0)
1801 return false;
1802
1803 $result = false;
1804 $arOrder = self::getOrderInfo($orderId);
1805
1806 if(!empty($arOrder) && isset($arOrder["YANDEX_ID"]) && !self::$isYandexRequest)
1807 {
1809 array("SITE_ID"=> $arOrder["LID"])
1810 );
1811
1812 $settings = $YMHandler->getSettingsBySiteId($arOrder["LID"]);
1813
1814 if(!isset($settings["STATUS_OUT"][$status]) || $settings["STATUS_OUT"][$status] == '')
1815 return false;
1816
1817 $yandexStatus = $settings["STATUS_OUT"][$status];
1818 $YMHandler->sendStatus($arOrder["YANDEX_ID"], $yandexStatus, $substatus);
1819 $result = true;
1820 }
1821
1822 return $result;
1823 }
1824
1825 public static function getOrderSubstatuses()
1826 {
1827 return array(
1828 "USER_UNREACHABLE" => GetMessage("SALE_YMH_SUBSTATUS_USER_UNREACHABLE"),
1829 "USER_CHANGED_MIND" => GetMessage("SALE_YMH_SUBSTATUS_USER_CHANGED_MIND"),
1830 "USER_REFUSED_DELIVERY"=> GetMessage("SALE_YMH_SUBSTATUS_USER_REFUSED_DELIVERY"),
1831 "USER_REFUSED_PRODUCT" => GetMessage("SALE_YMH_SUBSTATUS_USER_REFUSED_PRODUCT"),
1832 "SHOP_FAILED" => GetMessage("SALE_YMH_SUBSTATUS_SHOP_FAILED"),
1833 "REPLACING_ORDER" => GetMessage("SALE_YMH_SUBSTATUS_REPLACING_ORDER"),
1834 "PROCESSING_EXPIRED" => GetMessage("SALE_YMH_SUBSTATUS_PROCESSING_EXPIRED"),
1835 "RESERVATION_EXPIRED" => GetMessage("SALE_YMH_SUBSTATUS_RESERVATION_EXPIRED"),
1836 "USER_NOT_PAID" => GetMessage("SALE_YMH_SUBSTATUS_USER_NOT_PAID"),
1837 "USER_REFUSED_QUALITY" => GetMessage("SALE_YMH_SUBSTATUS_USER_REFUSED_QUALITY"),
1838 );
1839 }
1840
1841 public static function getCancelReasonsAsSelect($name, $val=false, $id=false)
1842 {
1844 $result = '<select width="100%" name="'.$name.'"';
1845
1846 if($id !== false)
1847 $result .= ' id="'.$id.'"';
1848
1849 $result .='>';
1850 foreach ($arStatuses as $statusId => $statusName)
1851 {
1852 $result .='<option value="'.$statusId.'"';
1853
1854 if($val == $statusId)
1855 $result .= ' selected';
1856
1857 $result .= '>'.$statusName.'</option>';
1858 }
1859
1860 $result .='</select>';
1861
1862 return $result;
1863 }
1864
1865 public static function getCancelReasonsAsRadio($name, $id=false, $val=false)
1866 {
1867 $result = "";
1869 $start = 0;
1870
1871 if($id === false)
1872 $id = "cancelreasonid_".rand();
1873
1874 foreach ($arStatuses as $statusId => $statusName)
1875 {
1876 $tmpId = $id.'_'.($start++);
1877 $result .=
1878 '<label for="'.$tmpId.'">'.
1879 '<input id="'.$tmpId.'" type="radio" name="'.$name.'_rb" value="'.$statusId.'">'.
1880 '<span id="'.$tmpId.'_lbl">'.$statusName.'</span>'.
1881 '</label><br>'.
1882 '<script>'.
1883 'BX("'.$tmpId.'").onchange=function(){if(this.checked == true) { BX("'.$id.'").innerHTML = BX("'.$tmpId.'_lbl").innerHTML; }};'.
1884 '</script>';
1885 }
1886 return $result;
1887 }
1888
1889 public static function OnEventLogGetAuditTypes()
1890 {
1891 return array(
1892 "YMARKET_STATUS_CHANGE" => "[YMARKET_STATUS_CHANGE] ".GetMessage("SALE_YMH_LOG_TYPE_STATUS_CHANGE"),
1893 "YMARKET_INCOMING_ORDER_STATUS" => "[YMARKET_INCOMING_ORDER_STATUS] ".GetMessage("SALE_YMH_LOG_TYPE_INCOMING_ORDER_STATUS"),
1894 "YMARKET_USER_CREATE" => "[YMARKET_USER_CREATE] ".GetMessage("SALE_YMH_LOG_TYPE_USER_CREATE"),
1895 "YMARKET_ORDER_CREATE" => "[YMARKET_ORDER_CREATE] ".GetMessage("SALE_YMH_LOG_TYPE_ORDER_CREATE"),
1896 "YMARKET_REQUEST_ERROR" => "[YMARKET_REQUEST_ERROR] ".GetMessage("SALE_YMH_LOG_TYPE_REQUEST_ERROR"),
1897 "YMARKET_INCOMING_REQUEST" => "[YMARKET_INCOMING_REQUEST] ".GetMessage("SALE_YMH_LOG_TYPE_INCOMING_REQUEST"),
1898 "YMARKET_INCOMING_REQUEST_RESULT" => "[YMARKET_INCOMING_REQUEST_RESULT] ".GetMessage("SALE_YMH_LOG_TYPE_INCOMING_REQUEST_RESULT"),
1899 "YMARKET_LOCATION_MAPPING" => "[YMARKET_LOCATION_MAPPING] ".GetMessage("SALE_YMH_LOG_TYPE_YMARKET_LOCATION_MAPPING"),
1900 "YMARKET_ORDER_STATUS_CHANGE" => "[YMARKET_ORDER_STATUS_CHANGE] ".GetMessage("SALE_YMH_LOG_TYPE_ORDER_STATUS_CHANGE"),
1901 "YMARKET_ORDER_CREATE_ERROR" => "[YMARKET_ORDER_CREATE_ERROR] ".GetMessage("SALE_YMH_LOG_TYPE_ORDER_CREATE_ERROR"),
1902
1903 );
1904 }
1905
1913 protected function log($level, $type, $itemId, $description)
1914 {
1915 if($this->logLevel < $level)
1916 return false;
1917
1919 "SEVERITY" => $level >= CSaleYMHandler::LOG_LEVEL_ERROR ? "WARNING" : "NOTICE",
1920 "AUDIT_TYPE_ID" => $type,
1921 "MODULE_ID" => "sale",
1922 "ITEM_ID" => $itemId,
1923 "DESCRIPTION" => $description,
1924 ));
1925
1926 return true;
1927 }
1928
1935 protected function mapYandexStatusToOrder($order, $yandexStatus, $cancelReason="")
1936 {
1937 global $APPLICATION;
1938
1939 if(!is_array($order) || !isset($order["ID"]) || $yandexStatus == '')
1940 return false;
1941
1942 $settings = $this->getSettingsBySiteId($order["LID"]);
1943
1944 if(!isset($settings["STATUS_IN"][$yandexStatus]) || $settings["STATUS_IN"][$yandexStatus] == '')
1945 return false;
1946
1947 $result = false;
1948 $bitrixStatus = $settings["STATUS_IN"][$yandexStatus];
1949
1950 switch($bitrixStatus)
1951 {
1952 /* flags */
1953 case "CANCELED":
1954
1955 $errorMessageTmp = "";
1956 $result = \CSaleOrder::CancelOrder($order["ID"], "Y", $cancelReason);
1957
1958 if (!$result)
1959 {
1960 if ($ex = $APPLICATION->GetException())
1961 {
1962 if ($ex->GetID() != "ALREADY_FLAG")
1963 $errorMessageTmp .= $ex->GetString();
1964 }
1965 else
1966 $errorMessageTmp .= GetMessage("ERROR_CANCEL_ORDER").". ";
1967 }
1968
1969 if($errorMessageTmp != "")
1970 {
1971 $this->log(
1972 self::LOG_LEVEL_ERROR,
1973 "YMARKET_INCOMING_ORDER_STATUS",
1974 $order["XML_ID"],
1975 $errorMessageTmp
1976 );
1977 }
1978 else
1979 {
1980 $this->log(
1981 self::LOG_LEVEL_INFO,
1982 "YMARKET_INCOMING_ORDER_STATUS",
1983 $order["XML_ID"],
1984 GetMessage("SALE_YMH_INCOMING_ORDER_STATUS_CANCELED").": ".$order["ID"]
1985 );
1986 }
1987
1988 break;
1989
1990 case "ALLOW_DELIVERY":
1991 $result = CSaleOrder::DeliverOrder($order["ID"], "Y");
1992 break;
1993
1994 case "PAYED":
1995 $result = CSaleOrder::PayOrder($order["ID"], "Y");
1996 break;
1997
1998 case "DEDUCTED":
2000 break;
2001
2002 /* statuses */
2003 default:
2004 if(CSaleStatus::GetByID($bitrixStatus))
2005 {
2006 $result = CSaleOrder::StatusOrder($order["ID"], $bitrixStatus);
2007 }
2008 break;
2009 }
2010
2011 $this->log(
2012 $result ? self::LOG_LEVEL_INFO : self::LOG_LEVEL_ERROR,
2013 "YMARKET_ORDER_STATUS_CHANGE",
2014 $order["ID"],
2015 ($result ? GetMessage("SALE_YMH_LOG_TYPE_ORDER_STATUS_CHANGE_OK") : GetMessage("SALE_YMH_LOG_TYPE_ORDER_STATUS_CHANGE_ERROR"))." (".$bitrixStatus.")"
2016 );
2017
2018 return $result;
2019 }
2020
2025 public static function eventsStart()
2026 {
2028 $eventManager->registerEventHandler('sale', 'OnSaleStatusOrderChange', 'sale', 'CSaleYMHandler', 'onSaleStatusOrderChange');
2029 $eventManager->registerEventHandler('sale', 'OnSaleOrderCanceled', 'sale', 'CSaleYMHandler', 'onSaleOrderCanceled');
2030 $eventManager->registerEventHandler('sale', 'OnSaleShipmentDelivery', 'sale', 'CSaleYMHandler', 'onSaleShipmentDelivery');
2031 $eventManager->registerEventHandler('sale', 'OnSaleOrderPaid', 'sale', 'CSaleYMHandler', 'onSaleOrderPaid');
2032 $eventManager->registerEventHandler('sale', 'OnShipmentDeducted', 'sale', 'CSaleYMHandler', 'onShipmentDeducted');
2033
2034 return true;
2035 }
2036
2041 public static function eventsStop()
2042 {
2044 $eventManager->unRegisterEventHandler('sale', 'OnSaleStatusOrderChange', 'sale', 'CSaleYMHandler', 'onSaleStatusOrderChange');
2045 $eventManager->unRegisterEventHandler('sale', 'OnSaleOrderCanceled', 'sale', 'CSaleYMHandler', 'onSaleOrderCanceled');
2046 $eventManager->unRegisterEventHandler('sale', 'OnSaleShipmentDelivery', 'sale', 'CSaleYMHandler', 'onSaleShipmentDelivery');
2047 $eventManager->unRegisterEventHandler('sale', 'OnSaleOrderPaid', 'sale', 'CSaleYMHandler', 'onSaleOrderPaid');
2048 $eventManager->unRegisterEventHandler('sale', 'OnShipmentDeducted', 'sale', 'CSaleYMHandler', 'onShipmentDeducted');
2049
2050 return true;
2051 }
2052
2057 public static function install()
2058 {
2059 $settings = static::getSettings();
2060
2061 if(empty($settings))
2062 {
2063 $res = Bitrix\Sale\TradingPlatformTable::add(array(
2064 "CODE" => static::TRADING_PLATFORM_CODE,
2065 "ACTIVE" => "N",
2066 "NAME" => GetMessage("SALE_YMH_NAME"),
2067 "DESCRIPTION" => GetMessage("SALE_YMH_DESCRIPTION"),
2068 "SETTINGS" => "",
2069 ));
2070
2071 $dbSites = \CSite::GetList('', '', array("ACTIVE" => "Y"));
2072
2073 while ($site = $dbSites->Fetch())
2074 {
2076 array(
2077 "CONDITION" => "#^/bitrix/services/ymarket/#",
2078 "RULE" => "",
2079 "ID" => "",
2080 "PATH" => "/bitrix/services/ymarket/index.php",
2081 "SITE_ID" => $site["ID"]
2082 )
2083 );
2084 }
2085
2086 return $res->isSuccess();
2087 }
2088
2089 return true;
2090 }
2091
2096 public static function unInstall($deleteRecord = true)
2097 {
2098 static::eventsStop();
2099
2100 $settings = static::getSettings();
2101
2102 if(!empty($settings))
2103 {
2104 if($deleteRecord)
2105 Bitrix\Sale\TradingPlatformTable::delete(static::TRADING_PLATFORM_CODE);
2106 else
2107 static::setActivity(false);
2108 }
2109
2111 array(
2112 "CONDITION" => "#^/bitrix/services/ymarket/#",
2113 "PATH" => "/bitrix/services/ymarket/index.php"
2114 )
2115 );
2116 }
2117
2122 protected function sendEmailNewOrder($newOrderId, $buyer)
2123 {
2124 global $DB;
2125
2126 $strOrderList = "";
2127 $baseLangCurrency = Bitrix\Sale\Internals\SiteCurrencyTable::getSiteCurrency($this->siteId);
2128 $orderNew = CSaleOrder::GetByID($newOrderId);
2129 $orderNew["BASKET_ITEMS"] = array();
2130
2131 $userEmail = $buyer["email"];
2132 $fio = $buyer["last-name"].(isset($buyer["first-name"]) ? $buyer["first-name"] : "");
2133
2134 $dbBasketTmp = CSaleBasket::GetList(
2135 array("SET_PARENT_ID" => "DESC", "TYPE" => "DESC", "NAME" => "ASC"),
2136 array("ORDER_ID" => $newOrderId),
2137 false,
2138 false,
2139 array(
2140 "ID", "PRICE", "QUANTITY", "NAME"
2141 )
2142 );
2143
2144 while ($arBasketTmp = $dbBasketTmp->GetNext())
2145 {
2146 $orderNew["BASKET_ITEMS"][] = $arBasketTmp;
2147 }
2148
2149 $orderNew["BASKET_ITEMS"] = getMeasures($orderNew["BASKET_ITEMS"]);
2150
2151 foreach ($orderNew["BASKET_ITEMS"] as $val)
2152 {
2154 continue;
2155
2156 $measure = (isset($val["MEASURE_TEXT"])) ? $val["MEASURE_TEXT"] : GetMessage("SALE_YMH_SHT");
2157 $strOrderList .= $val["NAME"]." - ".$val["QUANTITY"]." ".$measure." x ".SaleFormatCurrency($val["PRICE"], $baseLangCurrency);
2158 $strOrderList .= "</br>";
2159 }
2160
2161 //send mail
2162 $arFields = array(
2163 "ORDER_ID" => $orderNew["ACCOUNT_NUMBER"],
2164 "ORDER_DATE" => Date($DB->DateFormatToPHP(CLang::GetDateFormat("SHORT", $this->siteId))),
2165 "ORDER_USER" => $fio,
2166 "PRICE" => SaleFormatCurrency($orderNew["PRICE"], $baseLangCurrency),
2167 "BCC" => COption::GetOptionString("sale", "order_email", "order@".$_SERVER['SERVER_NAME']),
2168 "EMAIL" => array("PAYER_NAME" => $fio, "USER_EMAIL" => $userEmail),
2169 "ORDER_LIST" => $strOrderList,
2170 "SALE_EMAIL" => COption::GetOptionString("sale", "order_email", "order@".$_SERVER['SERVER_NAME']),
2171 "DELIVERY_PRICE" => $orderNew["DELIVERY_PRICE"],
2172 );
2173
2174 $eventName = "SALE_NEW_ORDER";
2175
2176 $bSend = true;
2177 foreach(GetModuleEvents("sale", "OnOrderNewSendEmail", true) as $arEvent)
2178 if (ExecuteModuleEventEx($arEvent, array($newOrderId, &$eventName, &$arFields))===false)
2179 $bSend = false;
2180
2181 if($bSend)
2182 {
2183 $event = new CEvent;
2184 $event->Send($eventName, $this->siteId, $arFields, "N");
2185 }
2186
2187 CSaleMobileOrderPush::send("ORDER_CREATED", array("ORDER" => $orderNew));
2188 }
2189
2195 protected function notifyAdmin($code)
2196 {
2197 $tag = "YANDEX_MARKET_".$code;
2198 $problemsCount = intval(Option::get("sale", $tag, 0, $this->siteId));
2199
2200 if($problemsCount < 3)
2201 {
2202 Option::set("sale", $tag, $problemsCount+1, $this->siteId);
2203 return false;
2204 }
2205
2206 $dbRes = CAdminNotify::GetList(array(), array("TAG" => $tag));
2207
2208 if($res = $dbRes->Fetch())
2209 return false;
2210
2212 "MESSAGE" => GetMessage("SALE_YMH_ADMIN_NOTIFY_".$code, array("##LANGUAGE_ID##" => LANGUAGE_ID)),
2213 "TAG" => "YANDEX_MARKET_".$code,
2214 "MODULE_ID" => "SALE",
2215 "ENABLE_CLOSE" => "Y"
2216 )
2217 );
2218
2219 Option::set("sale", $tag, 0, $this->siteId);
2220
2221 return true;
2222 }
2223
2227 public static function getExistPaymentMethods()
2228 {
2229 return array('YANDEX', 'CASH_ON_DELIVERY', 'CARD_ON_DELIVERY');
2230 }
2231
2233 public static function onSaleCancelOrder($orderId, $value, $description)
2234 {
2235 if($value != "Y" || self::$isYandexRequest)
2236 return false;
2237
2238 global $USER;
2239
2240 $arSubstatuses = self::getOrderSubstatuses();
2241
2242 if($description == '' || !$USER->IsAdmin() || empty($arSubstatuses[$description]))
2243 $description = "USER_CHANGED_MIND";
2244
2245 return self::onSaleStatusOrder($orderId, "CANCELED", $description);
2246 }
2247
2249 public static function onSaleDeliveryOrder($orderId, $value)
2250 {
2251 if($value != "Y" || self::$isYandexRequest)
2252 return false;
2253
2254 return self::onSaleStatusOrder($orderId, "ALLOW_DELIVERY");
2255 }
2256
2258 public static function onSalePayOrder($orderId, $value)
2259 {
2260 if($value != "Y" || self::$isYandexRequest)
2261 return false;
2262
2263 return self::onSaleStatusOrder($orderId, "PAYED");
2264 }
2265
2267 public static function onSaleDeductOrder($orderId, $value)
2268 {
2269 if($value != "Y" || self::$isYandexRequest)
2270 return false;
2271
2272 return self::onSaleStatusOrder($orderId, "DEDUCTED");
2273 }
2274
2276 protected function getDeliveryOptions($delivery, $price, $weight = 0)
2277 {
2278 $arResult = array();
2279
2280 $locationId = $this->locationMapper->getLocationId($delivery['region']);
2281
2282 if($locationId > 0)
2283 {
2284 foreach ($this->mapDelivery as $deliveryId => $deliveryType)
2285 {
2286 if($deliveryType == "")
2287 continue;
2288
2289 $filter = array(
2290 "ID" => $deliveryId,
2291 "LID" => $this->siteId,
2292 "ACTIVE" => "Y",
2293 "LOCATION" => $locationId,
2294 "+<=ORDER_PRICE_FROM" => $price,
2295 "+>=ORDER_PRICE_TO" => $price
2296 );
2297
2298 if(intval($weight) > 0)
2299 {
2300 $filter["+<=WEIGHT_FROM"] = $weight;
2301 $filter["+>=WEIGHT_TO"] = $weight;
2302 }
2303
2304 $dbDelivery = CSaleDelivery::GetList(
2305 array("SORT"=>"ASC", "NAME"=>"ASC"),
2306 $filter
2307 );
2308
2309 if($arDelivery = $dbDelivery->Fetch())
2310 {
2311 $arDates = $this->getDeliveryDates(
2312 $arDelivery["PERIOD_FROM"],
2313 $arDelivery["PERIOD_TO"],
2314 $arDelivery["PERIOD_TYPE"]
2315 );
2316
2317 if(!empty($arDates))
2318 {
2319 $arDeliveryTmp = array(
2320 "id" => $arDelivery["ID"],
2321 "type" =>$deliveryType,
2322 "serviceName" => mb_substr($arDelivery["NAME"], 0, 50),
2323 "price" => round(floatval($arDelivery["PRICE"]), 2),
2324 "dates" => $arDates
2325 );
2326
2327 if($deliveryType == "PICKUP" && !empty($this->outlets))
2328 foreach($this->outlets as $outlet)
2329 $arDeliveryTmp["outlets"][] = array("id" => intval($outlet));
2330
2331 $arResult[] = $arDeliveryTmp;
2332 }
2333 }
2334 }
2335 }
2336
2337 return $arResult;
2338 }
2339
2341 protected function getLocationByCityName($cityName)
2342 {
2343 return $this->locationMapper->getLocationByCityName($cityName);
2344 }
2345
2350 public static function settingsConverter()
2351 {
2352 $settings = static::getSettings();
2353
2354 if(!empty($settings) && !empty($settings["SETTINGS"]))
2355 {
2356 return false;
2357 }
2358
2360 {
2361 return false;
2362 }
2363
2364 $settings = array();
2365
2366 $rsSites = CSite::GetList();
2367
2368 while ($arSite = $rsSites->Fetch())
2369 {
2370 $serSiteSett = COption::GetOptionString("sale", "yandex_market_purchase_settings", "", $arSite["ID"], true);
2371 $siteSett = unserialize($serSiteSett, ['allowed_classes' => false]);
2372
2373 if(is_array($siteSett) && !empty($siteSett))
2374 $settings[$arSite["ID"]] = $siteSett;
2375 }
2376
2377 if(empty($settings))
2378 {
2379 $serSiteSett = COption::GetOptionString("sale", "yandex_market_purchase_settings", "");
2380 $siteSett = unserialize($serSiteSett, ['allowed_classes' => false]);
2381
2382 if(is_array($siteSett) && !empty($siteSett))
2383 $settings[CSite::GetDefSite()] = $siteSett;
2384 }
2385
2386 if(empty($settings))
2387 {
2388 return false;
2389 }
2390
2392 {
2393 return false;
2394 }
2395
2397 {
2398 return false;
2399 }
2400
2402 {
2403 return false;
2404 }
2405
2406 return true;
2407 }
2408
2414 public static function takeOutOrdersToCorrespondentTable()
2415 {
2416 $platformId = YMarket\YandexMarket::getInstance()->getId();
2417
2418 if(intval($platformId) <= 0)
2419 return "";
2420
2422 $helper = $conn->getSqlHelper();
2423
2424 $correspondence = $conn->query(
2425 'SELECT ID
2426 FROM '.$helper->quote(\Bitrix\Sale\TradingPlatform\OrderTable::getTableName()).'
2427 WHERE '.$helper->quote('TRADING_PLATFORM_ID').'='.$platformId
2428 );
2429
2430 //check if we already tried to convert
2431 if ($correspondence->fetch())
2432 return "";
2433
2434 if($conn->getType() == "mssql")
2435 $lenOpName = "LEN";
2436 else
2437 $lenOpName = "LENGTH";
2438
2439 if($conn->getType() == "oracle")
2440 $right = 'SUBSTR(XML_ID, -('.$lenOpName.'(XML_ID)-'.mb_strlen(self::XML_ID_PREFIX).'))';
2441 else
2442 $right = 'RIGHT(XML_ID, '.$lenOpName.'(XML_ID)-'.mb_strlen(self::XML_ID_PREFIX).')';
2443
2444 //take out correspondence to
2445 $sql = 'INSERT INTO '.\Bitrix\Sale\TradingPlatform\OrderTable::getTableName().' (ORDER_ID, EXTERNAL_ORDER_ID, TRADING_PLATFORM_ID)
2446 SELECT ID, '.$right.', '.$platformId.'
2448 WHERE XML_ID LIKE '."'".self::XML_ID_PREFIX."%'";
2449
2450 try
2451 {
2452 $conn->queryExecute($sql);
2453 }
2454 catch(\Bitrix\Main\DB\SqlQueryException $e)
2455 {
2457 "SEVERITY" => "ERROR",
2458 "AUDIT_TYPE_ID" => "YMARKET_XML_ID_CONVERT_INSERT_ERROR",
2459 "MODULE_ID" => "sale",
2460 "ITEM_ID" => "YMARKET",
2461 "DESCRIPTION" => __FILE__.': '.$e->getMessage(),
2462 ));
2463 }
2464
2465 return "";
2466 }
2467
2469 public static function convertDeliveryAndPSIds()
2470 {
2471 if(\Bitrix\Main\Config\Option::get("sale", 'YANDEX_MARKET_DELIVERY_PS_IDS_CONVERTED', 'N') == 'Y')
2472 return '';
2473
2475
2476 if(!empty($settings['SETTINGS']) && is_array($settings['SETTINGS']))
2477 {
2478 $message = '';
2479
2480 foreach($settings['SETTINGS'] as $siteId => $siteSettings)
2481 {
2482 if(!empty($siteSettings['DELIVERIES']) && is_array($siteSettings['DELIVERIES']))
2483 {
2484 $newDeliveries = array();
2485 $message .= 'Deliveries ids converted: ';
2486
2487 foreach($siteSettings['DELIVERIES'] as $oldId => $type)
2488 {
2490 $message .= $oldId.'->'.$newId.', ';
2491
2492 if(intval($newId) > 0)
2493 $newDeliveries[$newId] = $type;
2494 }
2495
2496 $settings['SETTINGS'][$siteId]['DELIVERIES'] = $newDeliveries;
2497 }
2498 }
2499
2500 if(!empty($message))
2501 {
2503 "SEVERITY" => "INFO",
2504 "AUDIT_TYPE_ID" => "YANDEX_MARKET_DELIVERY_PS_IDS_CONVERTED",
2505 "MODULE_ID" => "sale",
2506 "ITEM_ID" => "YMARKET",
2507 "DESCRIPTION" => $message,
2508 ));
2509
2510 $res = Bitrix\Sale\TradingPlatformTable::update(
2512 array("SETTINGS" => $settings['SETTINGS'])
2513 );
2514
2515 if($res->isSuccess())
2516 \Bitrix\Main\Config\Option::set("sale", 'YANDEX_MARKET_DELIVERY_PS_IDS_CONVERTED', 'Y');
2517 }
2518 }
2519
2520 return '';
2521 }
2522
2527 public function loadOrderByYandexOrderId($yandexOrderId)
2528 {
2529 if ($yandexOrderId == '')
2530 return null;
2531
2532 $registry = \Bitrix\Sale\Registry::getInstance(\Bitrix\Sale\Registry::REGISTRY_TYPE_ORDER);
2533
2535 $orderClass = $registry->getOrderClassName();
2536
2537 $filter = array(
2538 'filter' => array(
2539 '=SOURCE.EXTERNAL_ORDER_ID' => $yandexOrderId,
2540 '=SOURCE.TRADING_PLATFORM_ID' => YMarket\YandexMarket::getInstance()->getId()
2541 ),
2542 'select' => array('*'),
2543 'runtime' => array(
2544 'SOURCE' => array(
2545 'data_type' => '\Bitrix\Sale\TradingPlatform\OrderTable',
2546 'reference' => array(
2547 'ref.ORDER_ID' => 'this.ID',
2548 ),
2549 'join_type' => 'left'
2550 )
2551 )
2552 );
2553
2554 $list = $orderClass::loadByFilter($filter);
2555
2556 if (!empty($list) && is_array($list))
2557 return reset($list);
2558
2559 return null;
2560 }
2561
2566 public static function isYandexRequest()
2567 {
2568 return self::$isYandexRequest;
2569 }
2570
2575 protected static function isOrderEntity(Sale\Internals\Entity $entity)
2576 {
2577 if ($entity instanceof Sale\Order
2578 || $entity instanceof Sale\Shipment
2579 || $entity instanceof Sale\Payment
2580 )
2581 {
2582 return $entity::getRegistryType() === Sale\Registry::REGISTRY_TYPE_ORDER;
2583 }
2584
2585 return false;
2586 }
2587}
$arParams
Определения access_dialog.php:21
$count
Определения admin_tab.php:4
$type
Определения options.php:106
$dbSites
Определения options.php:14
global $APPLICATION
Определения include.php:80
$arResult
Определения generate_coupon.php:16
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getConnection($name="")
Определения application.php:638
static get($moduleId, $name, $default="", $siteId=false)
Определения option.php:30
static set($moduleId, $name, $value="", $siteId="")
Определения option.php:261
Определения error.php:15
Определения event.php:5
static getInstance()
Определения eventmanager.php:31
Определения loader.php:13
Определения date.php:9
static getIdByCode($code)
Определения manager.php:1018
static init($mode=self::MODE_CLIENT, $params=[], $clearStorage=false)
Определения discountcouponsmanagerbase.php:476
static getTableName()
Определения order.php:38
static getSiteCurrency($siteId)
Определения sitecurrency.php:96
Определения payment.php:19
static getInstance($type)
Определения registry.php:183
const REGISTRY_TYPE_ORDER
Определения registry.php:16
static getTableName()
Определения order.php:44
static Add($arFields)
Определения admin_notify.php:22
static GetList($arSort=[], $arFilter=[])
Определения admin_notify.php:207
static GetList($arOrder=array("SORT"=> "ASC", "NAME"=> "ASC"), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array(' *'))
Определения delivery.php:989
static CancelOrder($ID, $val, $description="")
Определения order.php:2303
static StatusOrder($ID, $val)
Определения order.php:2449
static DeductOrder($ID, $val, $description="", $bAutoDeduction=true, $arStoreBarcodeOrderFormData=array(), $recurringID=0)
Определения order.php:2101
static DoAutoRegisterUser($autoEmail, $payerName, $siteId, &$arErrors, $arOtherFields=null)
Определения basket.php:3614
static GetAnonymousUserID()
Определения basket.php:3562
Определения event.php:13
static Add($arFields)
Определения event_log.php:44
static SetStatus($status)
Определения http.php:476
static isSetItem($arItem)
Определения basket_helper.php:26
static GetList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
Определения basket.php:33
static send($eventId, $arParams)
Определения mobile_order.php:1088
static GetList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
Определения order_props.php:410
static GetByID($statusId, $languageId=LANGUAGE_ID, $type=null)
Определения status.php:23
Определения ym_handler.php:21
const LOG_LEVEL_INFO
Определения ym_handler.php:46
$mapDelivery
Определения ym_handler.php:58
static getSettings($cached=true)
Определения ym_handler.php:250
static saveSettings($arSettings)
Определения ym_handler.php:286
$oAuthToken
Определения ym_handler.php:54
checkAuth()
Определения ym_handler.php:1353
$defaultDeliveryPeriodTo
Определения ym_handler.php:80
static getOrderSubstatuses()
Определения ym_handler.php:1825
static isYandexRequest()
Определения ym_handler.php:2566
$yandexApiUrl
Определения ym_handler.php:64
checkOrderAcceptStructure($arPostData)
Определения ym_handler.php:669
$personTypeId
Определения ym_handler.php:62
$isAcceptOldPrice
Определения ym_handler.php:78
$locationMapper
Определения ym_handler.php:76
static unInstall($deleteRecord=true)
Определения ym_handler.php:2096
getTimeInterval($period, $type)
Определения ym_handler.php:347
checkSiteId($siteId)
Определения ym_handler.php:196
mapYandexStatusToOrder($order, $yandexStatus, $cancelReason="")
Определения ym_handler.php:1935
static onSaleDeductOrder($orderId, $value)
Определения ym_handler.php:2267
static onSaleCancelOrder($orderId, $value, $description)
Определения ym_handler.php:2233
const XML_ID_PREFIX
Определения ym_handler.php:36
const LOG_LEVEL_DISABLE
Определения ym_handler.php:44
$mapPaySystems
Определения ym_handler.php:60
const ACCEPT_OLD_PRICE
Определения ym_handler.php:50
const NOT_ACCEPT_OLD_PRICE
Определения ym_handler.php:49
static takeOutOrdersToCorrespondentTable()
Определения ym_handler.php:2414
createUser($buyer, $address, $region)
Определения ym_handler.php:685
const ERROR_STATUS_401
Определения ym_handler.php:26
static getSettingsBySiteId($siteId, $cached=true)
Определения ym_handler.php:275
const LOG_LEVEL_DEBUG
Определения ym_handler.php:47
processError($status="", $message="")
Определения ym_handler.php:1461
processRequest($reqObject, $method, $postData)
Определения ym_handler.php:1392
checkBasketPrice(array $items, \Bitrix\Sale\Order $order)
Определения ym_handler.php:1086
static setActivity($activity)
Определения ym_handler.php:163
prepareResult($arData)
Определения ym_handler.php:1334
static getCancelReasonsAsRadio($name, $id=false, $val=false)
Определения ym_handler.php:1865
static OnEventLogGetAuditTypes()
Определения ym_handler.php:1889
const XML
Определения ym_handler.php:23
$logLevel
Определения ym_handler.php:52
const ERROR_STATUS_420
Определения ym_handler.php:31
const ERROR_STATUS_405
Определения ym_handler.php:29
makeAdditionalOrderProps($address, $buyer, $psId, $deliveryId, $locationId)
Определения ym_handler.php:729
static settingsConverter()
Определения ym_handler.php:2350
const LOG_LEVEL_ERROR
Определения ym_handler.php:45
static install()
Определения ym_handler.php:2057
static onSalePayOrder($orderId, $value)
Определения ym_handler.php:2258
static onSaleStatusOrder($orderId, $status, $substatus=false)
Определения ym_handler.php:1795
$deliveryToPaysystem
Определения ym_handler.php:81
const ERROR_STATUS_403
Определения ym_handler.php:27
$orderProps
Определения ym_handler.php:66
sendStatus($orderId, $status, $substatus=false)
Определения ym_handler.php:1482
sendEmailNewOrder($newOrderId, $buyer)
Определения ym_handler.php:2122
static $isYandexRequest
Определения ym_handler.php:83
processCustomEvents($eventName, array $params)
Определения ym_handler.php:641
getDeliveryOptions($delivery, $price, $weight=0)
Определения ym_handler.php:2276
const DATE_FORMAT
Определения ym_handler.php:35
const ERROR_STATUS_500
Определения ym_handler.php:32
extractPostData($postData)
Определения ym_handler.php:1317
notifyAdmin($code)
Определения ym_handler.php:2195
const TRADING_PLATFORM_CODE
Определения ym_handler.php:38
$defaultDeliveryPeriodFrom
Определения ym_handler.php:79
const ERROR_STATUS_400
Определения ym_handler.php:25
checkOrderStatusRequest($arPostData)
Определения ym_handler.php:1120
const ERROR_STATUS_415
Определения ym_handler.php:30
$authType
Определения ym_handler.php:42
$active
Определения ym_handler.php:77
static isOrderFromYandex($orderId)
Определения ym_handler.php:1655
$siteId
Определения ym_handler.php:41
__construct($arParams=array())
Определения ym_handler.php:89
const ERROR_STATUS_503
Определения ym_handler.php:33
getPaymentMethods()
Определения ym_handler.php:409
$oAuthLogin
Определения ym_handler.php:56
getDeliveryDates($from, $to, $type)
Определения ym_handler.php:381
static eventsStart()
Определения ym_handler.php:2025
checkTimeInterval($today, $nextDate)
Определения ym_handler.php:369
$outlets
Определения ym_handler.php:59
static convertDeliveryAndPSIds()
Определения ym_handler.php:2469
static getCancelReasonsAsSelect($name, $val=false, $id=false)
Определения ym_handler.php:1841
$communicationFormat
Определения ym_handler.php:40
static sendStatusAgent($yandexOrderId, $yandexStatus, $substatus, $siteId)
Определения ym_handler.php:1607
static isActive()
Определения ym_handler.php:153
getSiteId($arParams)
Определения ym_handler.php:214
static isOrderEntity(Sale\Internals\Entity $entity)
Определения ym_handler.php:2575
log($level, $type, $itemId, $description)
Определения ym_handler.php:1913
$campaignId
Определения ym_handler.php:63
const JSON
Определения ym_handler.php:22
static getExistPaymentMethods()
Определения ym_handler.php:2227
createAddressString($address)
Определения ym_handler.php:798
static getOrderInfo($orderId)
Определения ym_handler.php:1623
checkCartStructure($arPostData)
Определения ym_handler.php:424
$yandexToken
Определения ym_handler.php:65
static eventsStop()
Определения ym_handler.php:2041
static onSaleDeliveryOrder($orderId, $value)
Определения ym_handler.php:2249
$oAuthClientId
Определения ym_handler.php:55
const ERROR_STATUS_404
Определения ym_handler.php:28
getLocationByCityName($cityName)
Определения ym_handler.php:2341
Определения ym_location.php:13
static Add($arFields)
Определения urlrewriter.php:38
static Delete($arFilter)
Определения urlrewriter.php:67
$right
Определения options.php:8
$arFields
Определения dblapprove.php:5
$data['IS_AVAILABLE']
Определения .description.php:13
$orderId
Определения payment.php:5
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$rsSites
Определения options.php:477
$res
Определения filter_act.php:7
$_REQUEST["admin_mnu_menu_id"]
Определения get_menu.php:8
$result
Определения get_property_values.php:14
$start
Определения get_search.php:9
$entity
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
Определения .description.php:24
$region
Определения .description.php:13
$activity
Определения options.php:214
$errors
Определения iblock_catalog_edit.php:74
$filter
Определения iblock_catalog_list.php:54
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
global $DB
Определения cron_frame.php:29
global $USER
Определения csv_new_run.php:40
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$status
Определения session.php:10
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
$name
Определения menu_edit.php:35
Определения arrayresult.php:2
Определения ufield.php:9
Определения buffer.php:3
trait Error
Определения error.php:11
$payment
Определения payment.php:14
$order
Определения payment.php:8
$paymentCollection
Определения payment.php:11
$message
Определения payment.php:8
$settings
Определения product_settings.php:43
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$items
Определения template.php:224
SaleFormatCurrency($fSum, $strCurrency, $OnlyValue=false, $withoutFormat=false)
Определения include.php:142
getMeasures($arBasketItems)
Определения include.php:360
$arStatuses
Определения options.php:1642
$val
Определения options.php:1793
$method
Определения index.php:27
if($_SERVER $YMHandler['REQUEST_METHOD']=='POST' &&count($_POST)<=0)
Определения index.php:36
$postData
Определения index.php:29
$eventManager
Определения include.php:412
$arRes
Определения options.php:104
const SITE_ID
Определения sonet_set_content_view.php:12
$url
Определения iframe.php:7
$dbRes
Определения yandex_detail.php:168
$site
Определения yandex_run.php:614