Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/grain.iiko/lib/ |
Upload File : |
<?php namespace Grain\Iiko; use \Bitrix\Main\Localization\Loc; use \Bitrix\Main\Application; use \Bitrix\Main\Config\Option; use \Bitrix\Main\Web\Uri; use \Bitrix\Main\Web\Json; use \Bitrix\Main\Loader; use \Grain\Iiko\Rest; use \Grain\Iiko\Size; use \Grain\Iiko\Modifier; use \Grain\Iiko\Restaurants; use \Grain\Iiko\DeliveryTerminalTable; use \Grain\Iiko\CommandStatusTable; Loc::loadMessages(__FILE__); class Order { public static function onSaleOrderBeforeSaved(\Bitrix\Main\Event $event,$values=false) { $order = $event->getParameter("ENTITY"); $oldValues = $event->getParameter("VALUES"); if($order->getId()) return; if( Option::get('grain.iiko','post_orders')!='Y' || !($restaurant=Restaurants::getRestaurantByOrder($order)) ) return; foreach($event->getResults() as $previousResult) if($previousResult->getType()!=\Bitrix\Main\EventResult::SUCCESS) return; $checkForError = Option::get('grain.iiko','post_orders_check_error')=='Y'; $checkForProblem = Option::get('grain.iiko','post_orders_check_problem')=='Y'; $errorMessage = Option::get('grain.iiko','post_orders_check_error_message_'.$order->getSiteId()); $problemMessage = Option::get('grain.iiko','post_orders_check_error_message_'.$order->getSiteId()); $problemGeoMessage = Option::get('grain.iiko','post_orders_check_problem_message_geo_'.$order->getSiteId()); if(!$checkForError && !$checkForProblem) return; $params = self::buildOrderParamsArray($restaurant,$order); $params["queryType"] = "orderCheckCreate"; $event = new \Bitrix\Main\Event("grain.iiko", "OnBuildOrderParamsArray", array( 'RESTAURANT' => $restaurant, 'ORDER' => $order, 'PARAMS' => $params, 'CHECK' => true, )); $event->send(); foreach ($event->getResults() as $eventResult) { if($eventResult->getType() == \Bitrix\Main\EventResult::ERROR) continue; if($eventResult->getParameters()) $params = $eventResult->getParameters(); } $body = Rest::buildIikoOrderBody($params,$restaurant['ID']); $event = new \Bitrix\Main\Event("grain.iiko", "OnBuildIikoOrderBody", array( 'RESTAURANT' => $restaurant, 'ORDER' => $order, 'PARAMS' => $params, 'BODY' => $body, 'CHECK' => true, )); $event->send(); foreach ($event->getResults() as $eventResult) { if($eventResult->getType() == \Bitrix\Main\EventResult::ERROR) continue; if($eventResult->getParameters()) $body = $eventResult->getParameters(); } $result = Rest::orderCheckCreate($body,$restaurant['ID']); if($checkForError && array_key_exists('error',$result)) { $message = !!$errorMessage?str_replace('#ERROR#',$result['error'],$errorMessage):$result['error']; \CEventLog::Add(array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_ORDER_CHECK_ERROR", "MODULE_ID" => "grain.iiko", "ITEM_ID" => time(), "DESCRIPTION" => "\$result = ".print_r($result,true)."\n\$body = ".print_r($body,true), )); } elseif($checkForProblem && is_array($result['result']) && !empty($result['result']['problem'])) { if( strpos($result['result']['problem'], Loc::getMessage('GRAIN_IIKO_ORDER_GEO_NEEDLE1'))!==false || strpos($result['result']['problem'], Loc::getMessage('GRAIN_IIKO_ORDER_GEO_NEEDLE2'))!==false ) $message = !!$problemGeoMessage?str_replace('#ERROR#',$result['result']['problem'],$problemGeoMessage):$result['result']['problem']; else $message = !!$problemMessage?str_replace('#ERROR#',$result['result']['problem'],$problemMessage):$result['result']['problem']; } else return; return new \Bitrix\Main\EventResult( \Bitrix\Main\EventResult::ERROR, \Bitrix\Sale\ResultError::create(new \Bitrix\Main\Error($message, "GRAIN_IIKO_ORDER_CHECK_ERROR")) ); } public static function onSaleOrderSaved(\Bitrix\Main\Event $event) { $order = $event->getParameter("ENTITY"); if( Option::get('grain.iiko','post_orders')!='Y' || !($restaurant=Restaurants::getRestaurantByOrder($order)) || !Loader::includeModule('iblock') ) return; if($event->getParameter("IS_NEW") && Loader::includeModule('grain.iikocard')) { \Grain\IikoCard\Helper::saveStorageDataToOrder($order->getId(),$restaurant['ID']); } $oldValues = $event->getParameter("VALUES"); $isOnlinePayment = self::isOnlinePayment($order); static $blockInfiniteLoop = false; if($blockInfiniteLoop) return; if($isOnlinePayment) { if(!$order->getField('PAYED') || !$oldValues['PAYED'] || !($order->getField('PAYED')==='Y') && ($oldValues['PAYED']==='N')) return; } else { if(!$event->getParameter("IS_NEW")) return; } $blockInfiniteLoop = true; $params = self::buildOrderParamsArray($restaurant,$order); $params["queryType"] = "orderCreate"; $event = new \Bitrix\Main\Event("grain.iiko", "OnBuildOrderParamsArray", array( 'RESTAURANT' => $restaurant, 'ORDER' => $order, 'PARAMS' => $params, 'CHECK' => false, )); $event->send(); foreach ($event->getResults() as $eventResult) { if($eventResult->getType() == \Bitrix\Main\EventResult::ERROR) continue; if($eventResult->getParameters()) $params = $eventResult->getParameters(); } $body = Rest::buildIikoOrderBody($params,$restaurant['ID']); $event = new \Bitrix\Main\Event("grain.iiko", "OnBuildIikoOrderBody", array( 'RESTAURANT' => $restaurant, 'ORDER' => $order, 'PARAMS' => $params, 'BODY' => $body, 'CHECK' => false, )); $event->send(); foreach ($event->getResults() as $eventResult) { if($eventResult->getType() == \Bitrix\Main\EventResult::ERROR) continue; if($eventResult->getParameters()) $body = $eventResult->getParameters(); } if( (defined("GRAIN_IIKO_DO_NOT_POST_ORDERS") && GRAIN_IIKO_DO_NOT_POST_ORDERS) || $_SESSION['grain_iiko_do_not_post_orders'] ) { \CEventLog::Add(array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_ORDER_ERROR", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $params['orderId'], "DESCRIPTION" => Loc::getMessage("GRAIN_IIKO_ORDER_DO_NOT_POST_ORDERS"), )); return; } $result = Rest::orderCreate($body,$restaurant['ID']); \CEventLog::Add(array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => array_key_exists('error',$result)?"GRAIN_IIKO_ORDER_ERROR":"GRAIN_IIKO_ORDER_SUCCESS", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $params['orderId'], "DESCRIPTION" => "\$result = ".print_r($result,true)."\n\$body = ".print_r($body,true), )); if(!array_key_exists('error',$result)) { if(isset($result['result']['orderInfo']['id'])) { //static::setAdditionalInfoField('orderUuid',$result['result']['orderInfo']['id'],$order); $order->setField('XML_ID','grain-iiko-'.$result['result']['orderInfo']['id']); static::setAdditionalInfoField('sendStatus','PrimalSuccess',$order); } else { static::setAdditionalInfoField('sendStatus','NoUuid',$order); } if(isset($result['result']['correlationId']) && isset($result['result']['orderInfo']['id'])) { CommandStatusTable::add(array( 'ENTITY' => 'ORDER', 'ENTITY_ID' => $order->getId(), 'ENTITY_EXTERNAL_ID' => $result['result']['orderInfo']['id'], 'RESTAURANT_ID' => $restaurant['ID'], 'CORRELATION_ID' => $result['result']['correlationId'], )); } $order->save(); } else { static::setAdditionalInfoField('sendStatus','PrimalError',$order); $order->save(); } if($result['result'] && $result['result']['problem'] && $result['result']['problem']['hasProblem']) { \CEventLog::Add(array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_ORDER_PROBLEM", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $params['orderId'], "DESCRIPTION" => $result['result']['problem']['problem'], )); } $blockInfiniteLoop = false; } public static function isOnlinePayment($order) { $onlinePaySystems = explode(",",Option::get('grain.iiko','online_payments')); $isOnlinePayment = false; foreach ($order->getPaymentCollection() as $p) { if ($p->getPaymentSystemId() == \Bitrix\Sale\PaySystem\Manager::getInnerPaySystemId()) continue; $isOnlinePayment = in_array($p->getPaymentSystemId(),$onlinePaySystems); break; } return $isOnlinePayment; } public static function setAdditionalInfoField($fieldName,$fieldValue,$order) { try { $additionalInfo = Json::decode($order->getField('ADDITIONAL_INFO')); } catch (\Bitrix\Main\SystemException $e) { $additionalInfo = array(); } $additionalInfo[$fieldName] = $fieldValue; $order->setField('ADDITIONAL_INFO',Json::encode($additionalInfo)); } public static function buildOrderParamsArray($restaurant,$order) { $isOnlinePayment = self::isOnlinePayment($order); $userId = intval($order->getField('USER_ID')); $iikoCashPaySystemId = Option::get('grain.iiko','iiko_paysystem_cash_'.$restaurant['ID']); $iikoOnlinePaySystemId = Option::get('grain.iiko','iiko_paysystem_online_'.$restaurant['ID']); $iikoDiscountPaySystemId = Option::get('grain.iiko','iiko_paysystem_discount_'.$restaurant['ID']); $storeDiscountAsPayment = !!$iikoDiscountPaySystemId; $iikoFlexibleSumDiscountId = Option::get('grain.iiko','iiko_discount_'.$restaurant['ID']); $propertyCollection = $order->getPropertyCollection(); $propertyValueByCode = array(); foreach($propertyCollection as $propertyValue) $propertyValueByCode[$propertyValue->getField('CODE')] = $propertyValue->getField('VALUE'); $items = array(); $basket = $order->getBasket(); foreach ($basket as $basketItem) { $productId = intval($basketItem->getProductId()); if($productId<=0) continue; $rsElements = \CIBlockElement::GetList( array(), array("=ID"=>$productId), false, array("nTopCount"=>1), array("ID","IBLOCK_ID","XML_ID","NAME","PROPERTY_modifiers","PROPERTY_sizes") ); if(!$ob=$rsElements->GetNextElement()) continue; $element = $ob->GetFields(); $element['PROPERTIES'] = array( 'modifiers'=>$ob->GetProperty('modifiers'), 'sizes'=>$ob->GetProperty('sizes'), ); // $basketItem->getBasePrice() - price without discount // $basketItem->getPrice() - price with discount $item = array ( 'basketId' => $basketItem->getId(), 'id' => $element['XML_ID'], 'name' => $element["NAME"], 'amount' => $basketItem->getQuantity(), 'code' => $productId, 'price' => (Loader::includeModule('grain.iikocard') || $storeDiscountAsPayment || !!$iikoFlexibleSumDiscountId?$basketItem->getBasePrice():$basketItem->getPrice()), 'sum' => (Loader::includeModule('grain.iikocard') || $storeDiscountAsPayment || !!$iikoFlexibleSumDiscountId?$basketItem->getBasePrice():$basketItem->getPrice())*$basketItem->getQuantity(), ); if($modifiers = Modifier::getPreparedForOrder($element,$basketItem)) $item['modifiers'] = $modifiers; if($selectedSize = Size::getSelectedSize($element,$basketItem)) $item['productSize'] = $selectedSize; $items[] = $item; } $params = array( 'orderUuid' => Rest::generateOrderUuid($restaurant,$order), 'orderId' => $order->getId(), 'orderAccountNumber' => $order->getField('ACCOUNT_NUMBER'), 'siteId' => $order->getSiteId(), 'organizationId' => $restaurant['XML_ID'], 'name' => $propertyValueByCode[Option::get('grain.iiko','order_prop_name')], 'email' => $propertyValueByCode[Option::get('grain.iiko','order_prop_email')], 'phone' => $propertyValueByCode[Option::get('grain.iiko','order_prop_phone')], //'date' => $order->getDateInsert()->format("Y-m-d H:i:s"), 'userId' => $userId, 'items' => $items, 'comment' => $order->getField('USER_DESCRIPTION'), ); if( Option::get('grain.iiko','order_prop_time') && !!($orderTimeString=$propertyValueByCode[Option::get('grain.iiko','order_prop_time')]) && !!($orderTime = new \Bitrix\Main\Type\DateTime($orderTimeString)) ) { $params['secondsToCompleteBefore'] = $orderTime->getTimestamp() - time(); $params['date'] = $orderTime; } if(!$params['items']) return; $deliveryId = $order->getField('DELIVERY_ID'); // delivery $additionalInfo = array(); try { $additionalInfo = Json::decode($order->getField('ADDITIONAL_INFO')); } catch (\Bitrix\Main\SystemException $e) { } if(in_array($deliveryId,explode(',',Option::get('grain.iiko','delivery_delivery_'.$order->getSiteId())))) { $params['city'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_city')]; $params['street'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_street')]; $params['house'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_home')]; $params['building'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_housing')]; $params['flat'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_apartment')]; $params['entrance'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_entrance')]; $params['floor'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_floor')]; $params['doorphone'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_doorphone')]; $params['orderServiceType'] = 'DeliveryByCourier'; $params['deliveryPrice'] = $order->getDeliveryPrice(); if(isset($additionalInfo['deliveryServiceProductId'])) $params['deliveryServiceProductId'] = $additionalInfo['deliveryServiceProductId']; } elseif(in_array($deliveryId,explode(',',Option::get('grain.iiko','delivery_pickup_'.$order->getSiteId())))) { $params['orderServiceType'] = 'DeliveryByClient'; } else { $params['orderServiceType'] = 'DeliveryByClient'; } if(isset($additionalInfo['defaultTerminalGroupId'])) $params['terminalGroupId'] = $additionalInfo['defaultTerminalGroupId']; if(isset($propertyValueByCode[Option::get('grain.iiko','order_prop_delivery_terminal_id')])) $params['terminalGroupId'] = $propertyValueByCode[Option::get('grain.iiko','order_prop_delivery_terminal_id')]; if(isset($additionalInfo['terminalGroupId'])) $params['terminalGroupId'] = $additionalInfo['terminalGroupId']; if(!!$params['terminalGroupId'] && Option::get('grain.iiko','all_terminal_groups_'.$restaurant['ID'])=='Y') { $deliveryTerminalResult = DeliveryTerminalTable::getList(array( 'filter' => array( '=DELIVERY_TERMINAL_ID'=>$params['terminalGroupId'], '!ORGANIZATION_ID' => $restaurant['XML_ID'], ), 'select' => array('ORGANIZATION_ID'), 'limit' => 1, )); if($deliveryTerminal=$deliveryTerminalResult->fetch()) { $params['organizationId'] = $deliveryTerminal['ORGANIZATION_ID']; } } // /delivery $orderBasePrice = $order->getBasket()->getBasePrice(); $basketPrice = $order->getBasket()->getPrice(); $orderPrice = $order->getPrice(); $orderDiscountPrice = $orderBasePrice-$basketPrice; if( Loader::includeModule('grain.iikocard') && ($iikoCardPaySystemId=\Grain\IikoCard\Helper::getPaySystemId($restaurant['ID'])) ) { $iikoCardPayment = false; $basePayment = false; foreach($order->getPaymentCollection() as $payment) { if($payment->getPaymentSystemId()==\Bitrix\Sale\PaySystem\Manager::getInnerPaySystemId()) continue; if($payment->getPaymentSystemId()==$iikoCardPaySystemId) $iikoCardPayment = $payment; else $basePayment = $payment; } if(!!$basePayment && !!$iikoCardPayment) { $basketPrice -= $iikoCardPayment->getField('SUM'); $orderPrice -= $iikoCardPayment->getField('SUM'); } } // paysystem $iikoPayments = array(); $iikoPaySystems=array(); $iikoPaySystemsResult = Rest::getPaymentTypes($restaurant['ID']); if(is_array($iikoPaySystemsResult['result']) && is_array($iikoPaySystemsResult['result']['paymentTypes'])) foreach($iikoPaySystemsResult['result']['paymentTypes'] as $iikoPaySystem) $iikoPaySystems[$iikoPaySystem['id']] = $iikoPaySystem; if( (!!$iikoCashPaySystemId || !!$iikoOnlinePaySystemId || !!$iikoDiscountPaySystemId) ) { if(!$isOnlinePayment && !!$iikoCashPaySystemId && is_array($iikoPaySystems[$iikoCashPaySystemId])) { $iikoPayments[] = array( 'paymentTypeKind' => isset($iikoPaySystems[$iikoCashPaySystemId]['paymentTypeKind'])?$iikoPaySystems[$iikoCashPaySystemId]['paymentTypeKind']:'Cash', 'sum' => (Option::get('grain.iiko','iiko_paysystem_cash_order_price')=='Y'?$orderPrice:$basketPrice), 'paymentType' => $iikoPaySystems[$iikoCashPaySystemId], //'additionalData' => , 'isProcessedExternally' => false, 'isPreliminary' => false, 'isExternal' => false, ); } if($isOnlinePayment && !!$iikoOnlinePaySystemId && is_array($iikoPaySystems[$iikoOnlinePaySystemId])) { $iikoPayments[] = array( 'paymentTypeKind' => isset($iikoPaySystems[$iikoOnlinePaySystemId]['paymentTypeKind'])?$iikoPaySystems[$iikoOnlinePaySystemId]['paymentTypeKind']:'External', 'sum' => (Option::get('grain.iiko','iiko_paysystem_online_order_price')=='Y'?$orderPrice:$basketPrice), 'paymentType' => $iikoPaySystems[$iikoOnlinePaySystemId], //'additionalData' => , 'isProcessedExternally' => true, 'isPreliminary' => true, 'isExternal' => true, ); } if($orderDiscountPrice>0 && $storeDiscountAsPayment && !!$iikoDiscountPaySystemId && is_array($iikoPaySystems[$iikoDiscountPaySystemId])) { $iikoPayments[] = array( 'paymentTypeKind' => isset($iikoPaySystems[$iikoDiscountPaySystemId]['paymentTypeKind'])?$iikoPaySystems[$iikoDiscountPaySystemId]['paymentTypeKind']:'External', 'sum' => $orderDiscountPrice, 'paymentType' => $iikoPaySystems[$iikoDiscountPaySystemId], //'additionalData' => , 'isProcessedExternally' => false, 'isPreliminary' => true, 'isExternal' => true, ); } } $iikoCardPaymentMarketingCampaignId = null; if( Loader::includeModule('grain.iikocard') && !!$basePayment && !!$iikoCardPayment ) { $iikoPayments[] = array( 'paymentTypeKind' => isset($iikoPaySystems[\Grain\IikoCard\Helper::getIikoPaymentTypeId($restaurant['ID'])]['paymentTypeKind'])?$iikoPaySystems[\Grain\IikoCard\Helper::getIikoPaymentTypeId($restaurant['ID'])]['paymentTypeKind']:'IikoCard', 'sum' => $iikoCardPayment->getField('SUM'), 'paymentType' => $iikoPaySystems[\Grain\IikoCard\Helper::getIikoPaymentTypeId($restaurant['ID'])], 'paymentAdditionalData' => array( 'credential' => $params['phone'], 'searchScope' => 'Phone', 'type' => 'iikoCard', ), 'isProcessedExternally' => false, 'isPreliminary' => true, 'isExternal' => false, ); $iikoCardPaymentMarketingCampaignId = $iikoCardPayment->getField('PS_INVOICE_ID'); } if($iikoPayments) $params['payments'] = $iikoPayments; // /paysystem // discounts if(!$storeDiscountAsPayment && $orderDiscountPrice>0 && !!$iikoFlexibleSumDiscountId) { if(!is_array($params['discounts'])) $params['discounts'] = array(); $params['discounts'][] = array( 'discountTypeId' => $iikoFlexibleSumDiscountId, 'sum' => $orderDiscountPrice, 'type' => 'RMS', // or 'iikoCard' ); } if(Loader::includeModule('grain.iikocard')) { if($order->getId()) { if(($couponCode=\Grain\IikoCard\OrderLoyaltyTable::getCoupon($order->getId()))!==null) $params['couponCode'] = $couponCode; if(($marketingCampaignId=\Grain\IikoCard\Helper::getMarketingCampaignIdByOrderId($order->getId()))!==null) $params['marketingCampaignId'] = $marketingCampaignId; } else { if(($couponCode=\Grain\IikoCard\CouponStorage::get($restaurant['ID']))!==null) $params['couponCode'] = $couponCode; if(($marketingCampaignId=\Grain\IikoCard\Helper::getMarketingCampaignId($restaurant['ID']))!==null) $params['marketingCampaignId'] = $marketingCampaignId; } /* if($iikoCardPaymentMarketingCampaignId) { if(!is_array($params['marketingCampaignId'])) $params['marketingCampaignId'] = array(); $params['marketingCampaignId'][] = $iikoCardPaymentMarketingCampaignId; } */ } // /discounts return $params; } } ?>