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\Loader; use \Bitrix\Main\Config\Option; use \Bitrix\Main\Web\Json; use \Grain\Iiko\Rest; use \Grain\Iiko\LocationCityTable; use \Grain\Iiko\LocationStreetTable; use \Grain\Iiko\DeliveryTerminalTable; Loc::loadMessages(__FILE__); class Location { public static function sync($startRestaurantXmlId=null,$startCityXmlId=null) { if( intval($restaurantsIblockId=Option::get('grain.iiko','restaurants_iblock_id'))<=0 || !(Loader::includeModule('grain.iikomulti') || !!($apiLogin = Option::get('grain.iiko','api_login'))) || !Loader::includeModule('iblock') ) return '\\'.__METHOD__.'();'; $restaurants = array(); $resultRestaurant = \Bitrix\Iblock\ElementTable::getList(array( 'filter' => array('IBLOCK_ID'=>$restaurantsIblockId), 'select' => array('NAME','ID','XML_ID'), )); while($restaurant = $resultRestaurant->fetch()) { $restaurants[] = $restaurant; } if(count($restaurants)<=0) return '\\'.__METHOD__.'();'; $currentRestaurantIndex = 0; foreach($restaurants as $index=>$restaurant) { if($restaurant['XML_ID']!=$startRestaurantXmlId) continue; $currentRestaurantIndex = $index; break; } $restaurant = $restaurants[$currentRestaurantIndex]; $nextRestaurant = isset($restaurants[$currentRestaurantIndex+1])?$restaurants[$currentRestaurantIndex+1]:$restaurants[0]; if(!is_array($account=Rest::getAccount($restaurant['ID']))) { \CEventLog::Add(Array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_LOCATION_SYNC", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $restaurant['ID'], "DESCRIPTION" => Loc::getMessage("GRAIN_IIKO_LOCATION_SYNC_ERROR",array( '#ORGANIZATION#' => $restaurant['NAME'], '#ERROR#' => 'No account for organization '.$restaurant['XML_ID'], )), )); return '\\'.__METHOD__.'('.var_export($nextRestaurant['XML_ID'],true).');'; } $timeStart = microtime(true); $log = array( 'city'=>array( 'added' => 0, 'updated' => 0, 'deleted' => 0, ), 'street'=>array( 'added' => 0, 'updated' => 0, 'deleted' => 0, 'cityNames' => array(), ), 'deliveryTerminal'=>array( 'added' => 0, 'updated' => 0, 'deleted' => 0, ), ); static::syncTerminals($restaurant,$log); if($account['API_VERSION']==0) { $return = static::syncCityCompatible($restaurant,$nextRestaurant,$log); } else { $return = static::syncCity($restaurant,$nextRestaurant,$startCityXmlId,$log); } $timeEnd = microtime(true); $time = number_format(($timeEnd-$timeStart),3,".",""); \CEventLog::Add(Array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_LOCATION_SYNC", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $restaurant['ID'], "DESCRIPTION" => Loc::getMessage("GRAIN_IIKO_LOCATION_SYNC_SUCCESS",array( '#ORGANIZATION#' => $restaurant['NAME'], '#CITY_UPDATED#' => $log['city']['updated'], '#CITY_ADDED#' => $log['city']['added'], '#CITY_DELETED#' => $log['city']['deleted'], '#STREET_UPDATED#' => $log['street']['updated'], '#STREET_ADDED#' => $log['street']['added'], '#STREET_DELETED#' => $log['street']['deleted'], '#STREET_CITY_PROCESSED#' => count($log['street']['cityNames'])." (".implode(', ',$log['street']['cityNames']).")", '#DELIVERY_TERMINALS_UPDATED#' => $log['deliveryTerminal']['updated'], '#DELIVERY_TERMINALS_ADDED#' => $log['deliveryTerminal']['added'], '#DELIVERY_TERMINALS_DELETED#' => $log['deliveryTerminal']['deleted'], '#TIME#' => $time, )), )); return $return; } public static function syncCity($restaurant,$nextRestaurant,$startCityXmlId=null,&$log) { $totalQueriesMax = (int)Option::get('grain.iiko','location_total_queries_max'); $totalQueriesMax = $totalQueriesMax>0 && $totalQueriesMax<3?3:$totalQueriesMax; $totalQueriesMax = $totalQueriesMax>0?$totalQueriesMax:10; $queryCount = 1; $result = Rest::getCities($restaurant['ID']); $queryCount++; $return = false; if(!is_array($result['result'])) { \CEventLog::Add(Array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_LOCATION_SYNC", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $restaurant['ID'], "DESCRIPTION" => Loc::getMessage("GRAIN_IIKO_LOCATION_SYNC_ERROR",array( '#ORGANIZATION#' => $restaurant['NAME'], '#ERROR#' => $result['error'], )), )); } else { // select current organization data $localData = array(); $cityResult = LocationCityTable::getList(array( 'filter' => array( 'ORGANIZATION_ID' => $restaurant['XML_ID'], ), 'select' => array('ID','CITY_ID'), )); while($localCity = $cityResult->fetch()) { $localData[$localCity['CITY_ID']] = array( 'ORGANIZATION_ID' => $restaurant['XML_ID'], 'ID' => $localCity['ID'], 'STREETS' => array(), 'DELETE' => true, ); } // /select current organization data foreach($result['result']['cities'][0]['items'] as $city) { $localCityId = 0; // sync city if(array_key_exists($city['id'], $localData)) { //$localCity = $localData[$city['id']]; LocationCityTable::update($localData[$city['id']]['ID'],array( 'NAME'=>$city['name'], 'DELETED'=>$city['isDeleted']?'Y':'N', )); $log['city']['updated']++; $localCityId = $localData[$city['id']]['ID']; $localData[$city['id']]['DELETE'] = false; } else { $cityAddResult = LocationCityTable::add(array( 'NAME'=>$city['name'], 'ORGANIZATION_ID' => $restaurant['XML_ID'], 'CITY_ID' => $city['id'], 'DELETED' => $city['isDeleted']?'Y':'N', )); if ($cityAddResult->isSuccess()) { $localCityId = $cityAddResult->getId(); $log['city']['added']++; } } // /sync city if(!!$startCityXmlId && $city['id']!=$startCityXmlId) { // continue updating cities but not streets continue; } elseif(!!$startCityXmlId && $city['id']==$startCityXmlId) { // start update cities at this point $startCityXmlId=null; } if($queryCount>=$totalQueriesMax) { // continue updating cities but not streets if(!$return) $return = '\\'.__CLASS__.'::sync('.var_export($restaurant['XML_ID'],true).','.var_export($city['id'],true).');'; continue; } if($localCityId<=0) continue; // sync streets $log['street']['cityNames'][] = $city['name']; $streetResult = LocationStreetTable::getList(array( 'filter' => array( 'CITY_ID' => $localCityId, ), 'select' => array('ID','STREET_ID'), )); while($localStreet = $streetResult->fetch()) { $localData[$localCityId]['STREETS'][$localStreet['STREET_ID']] = array( 'ID' => $localStreet['ID'], 'DELETE' => true, ); } $resultStreet = Rest::getStreets($restaurant['ID'],$city['id']); $queryCount++; if(!is_array($resultStreet['result']) || !is_array($resultStreet['result']['streets']) || isset($resultStreet['error'])) { \CEventLog::Add(Array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_LOCATION_SYNC", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $restaurant['ID'], "DESCRIPTION" => Loc::getMessage("GRAIN_IIKO_LOCATION_SYNC_ERROR",array( '#ORGANIZATION#' => $restaurant['NAME'], '#ERROR#' => $resultStreet['error'], )), )); continue; } else { foreach($resultStreet['result']['streets'] as $street) { if($localData[$localCityId] && array_key_exists($street['id'], $localData[$localCityId]['STREETS'])) { $localStreet = $localData[$localCityId]['STREETS'][$street['id']]; LocationStreetTable::update($localStreet['ID'],array( 'NAME'=>$street['name'], 'DELETED'=>$street['isDeleted']?'Y':'N', )); $log['street']['updated']++; $localData[$localCityId]['STREETS'][$street['id']]['DELETE'] = false; } else { $streetAddResult = LocationStreetTable::add(array( 'CITY_ID' => $localCityId, 'NAME'=>$street['name'], 'STREET_ID' => $street['id'], 'DELETED' => $street['isDeleted']?'Y':'N', )); if ($streetAddResult->isSuccess()) { $log['street']['added']++; } } } } // /sync streets } // city and streets delete foreach($localData as $localCity) { foreach($localCity['STREETS'] as $localStreet) { if($localStreet['DELETE'] || $localCity['DELETE']) { LocationStreetTable::delete($localStreet['ID']); $log['street']['deleted']++; } } if($localCity['DELETE']) { LocationCityTable::delete($localCity['ID']); $log['city']['deleted']++; } } // /city and streets delete } return $return?$return:'\\'.__CLASS__.'::sync('.var_export($nextRestaurant['XML_ID'],true).');'; } public static function syncCityCompatible($restaurant,$nextRestaurant,&$log) { $result = Rest::getCities($restaurant['ID']); if(!is_array($result['result'])) { \CEventLog::Add(Array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_LOCATION_SYNC", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $restaurant['ID'], "DESCRIPTION" => Loc::getMessage("GRAIN_IIKO_LOCATION_SYNC_ERROR",array( '#ORGANIZATION#' => $restaurant['NAME'], '#ERROR#' => $result['error'], )), )); } else { /* select current organization data */ $localData = array(); $cityResult = LocationCityTable::getList(array( 'filter' => array( 'ORGANIZATION_ID' => $restaurant['XML_ID'], ), 'select' => array('ID','CITY_ID'), )); while($localCity = $cityResult->fetch()) { $localData[$localCity['CITY_ID']] = array( 'ORGANIZATION_ID' => $restaurant['XML_ID'], 'ID' => $localCity['ID'], 'STREETS' => array(), 'DELETE' => true, ); $streetResult = LocationStreetTable::getList(array( 'filter' => array( 'CITY_ID' => $localCity['ID'], ), 'select' => array('ID','STREET_ID'), )); while($localStreet = $streetResult->fetch()) { $localData[$localCity['CITY_ID']]['STREETS'][$localStreet['STREET_ID']] = array( 'ID' => $localStreet['ID'], 'DELETE' => true, ); } } /* /select current organization data */ foreach($result['result']['cities'][0]['items'] as $city) { $localCityId = 0; $localCity = false; /* sync city */ if(array_key_exists($city['id'], $localData)) { $localCity = $localData[$city['id']]; LocationCityTable::update($localCity['ID'],array( 'NAME'=>$city['name'], 'DELETED'=>$city['isDeleted']?'Y':'N', )); $log['city']['updated']++; $localCityId = $localCity['ID']; $localData[$city['id']]['DELETE'] = false; } else { $cityAddResult = LocationCityTable::add(array( 'NAME'=>$city['name'], 'ORGANIZATION_ID' => $restaurant['XML_ID'], 'CITY_ID' => $city['id'], 'DELETED' => $city['isDeleted']?'Y':'N', )); if ($cityAddResult->isSuccess()) { $localCityId = $cityAddResult->getId(); $log['city']['added']++; } } /* /sync city */ if($localCityId<=0) continue; /* sync streets */ foreach($city['streets'] as $street) { if($localCity && array_key_exists($street['id'], $localCity['STREETS'])) { $localStreet = $localCity['STREETS'][$street['id']]; LocationStreetTable::update($localStreet['ID'],array( 'NAME'=>$street['name'], 'DELETED'=>$street['isDeleted']?'Y':'N', )); $log['street']['updated']++; $localData[$city['id']]['STREETS'][$street['id']]['DELETE'] = false; } else { $streetAddResult = LocationStreetTable::add(array( 'CITY_ID' => $localCityId, 'NAME'=>$street['name'], 'STREET_ID' => $street['id'], 'DELETED' => $street['isDeleted']?'Y':'N', )); if ($streetAddResult->isSuccess()) { $log['street']['added']++; } } } /* /sync streets */ } /* delete city and streets */ foreach($localData as $localCity) { foreach($localCity['STREETS'] as $localStreet) { if($localStreet['DELETE'] || $localCity['DELETE']) { LocationStreetTable::delete($localStreet['ID']); $log['street']['deleted']++; } } if($localCity['DELETE']) { LocationCityTable::delete($localCity['ID']); $log['city']['deleted']++; } } /* /delete city and streets */ } return '\\'.__CLASS__.'::sync('.var_export($nextRestaurant['XML_ID'],true).');'; } public static function syncTerminals($restaurant,&$log) { $result = Rest::getDeliveryTerminals($restaurant['ID']); if(!is_array($result['result']['terminalGroups'][0]['items'])) { \CEventLog::Add(Array( "SEVERITY" => "CUSTOM", "AUDIT_TYPE_ID" => "GRAIN_IIKO_LOCATION_SYNC", "MODULE_ID" => "grain.iiko", "ITEM_ID" => $restaurant['ID'], "DESCRIPTION" => Loc::getMessage("GRAIN_IIKO_LOCATION_TERMINALS_SYNC_ERROR",array( '#ORGANIZATION#' => $restaurant['NAME'], '#ERROR#' => $result['error'], )), )); } else { $localTerminalData = array(); $terminalResult = DeliveryTerminalTable::getList(array( 'filter' => array( 'ORGANIZATION_ID' => $restaurant['XML_ID'], ), 'select' => array('ID','DELIVERY_TERMINAL_ID'), )); while($localTerminal = $terminalResult->fetch()) { $localTerminalData[$localTerminal['DELIVERY_TERMINAL_ID']] = array( 'ORGANIZATION_ID' => $restaurant['XML_ID'], 'ID' => $localTerminal['ID'], 'DELETE' => true, ); } foreach($result['result']['terminalGroups'][0]['items'] as $terminal) { /* sync terminal */ $localTerminal = false; if(array_key_exists($terminal['id'], $localTerminalData)) { $localTerminal = $localTerminalData[$terminal['id']]; DeliveryTerminalTable::update($localTerminal['ID'],array( 'DELIVERY_GROUP_NAME' => is_string($terminal['deliveryGroupName'])?$terminal['deliveryGroupName']:'', // v0 only 'DELIVERY_RESTAURANT_NAME' => is_string($terminal['deliveryRestaurantName'])?$terminal['deliveryRestaurantName']:'', // v0 only 'NAME' => is_string($terminal['name'])?$terminal['name']:'', 'ADDRESS' => is_string($terminal['address'])?$terminal['address']:'', 'OPENING_HOURS' => is_array($terminal['openingHours'])?Json::encode($terminal['openingHours']):'', // v0 only 'EXTERNAL_REVISION' => is_string($terminal['externalRevision'])?$terminal['externalRevision']:'', // v0 only 'TECHNICAL_INFORMATION' => is_string($terminal['technicalInformation'])?$terminal['technicalInformation']:'', // v0 only )); $log['deliveryTerminal']['updated']++; $localTerminalData[$terminal['id']]['DELETE'] = false; } else { $terminalAddResult = DeliveryTerminalTable::add(array( 'ORGANIZATION_ID' => $restaurant['XML_ID'], 'DELIVERY_TERMINAL_ID' => $terminal['id'], 'DELIVERY_GROUP_NAME' => is_string($terminal['deliveryGroupName'])?$terminal['deliveryGroupName']:'', // v0 only 'DELIVERY_RESTAURANT_NAME' => is_string($terminal['deliveryRestaurantName'])?$terminal['deliveryRestaurantName']:'', // v0 only 'NAME' => is_string($terminal['name'])?$terminal['name']:'', 'ADDRESS' => is_string($terminal['address'])?$terminal['address']:'', 'OPENING_HOURS' => is_array($terminal['openingHours'])?Json::encode($terminal['openingHours']):'', // v0 only 'EXTERNAL_REVISION' => is_string($terminal['externalRevision'])?$terminal['externalRevision']:'', // v0 only 'TECHNICAL_INFORMATION' => is_string($terminal['technicalInformation'])?$terminal['technicalInformation']:'', // v0 only )); if ($terminalAddResult->isSuccess()) { $log['deliveryTerminal']['added']++; } } /* /sync terminal */ } /* delete delivery terminals */ foreach($localTerminalData as $localTerminal) { if($localTerminal['DELETE']) { DeliveryTerminalTable::delete($localTerminal['ID']); $log['deliveryTerminal']['deleted']++; } } /* /delete delivery terminals */ } } }