%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/sale/ru/delivery/
Upload File :
Create Path :
Current File : /home/bitrix/www/bitrix/modules/sale/ru/delivery/delivery_russianpost.php

<?
/*********************************************************************************
Delivery services for Russian Post Service (http://www.russianpost.ru/)
It uses on-line calculator. Delivery only from Moscow.
Files:
- russianpost/country.php - list of russianpost country ids
*********************************************************************************/

CModule::IncludeModule("sale");

IncludeModuleLangFile($_SERVER["DOCUMENT_ROOT"].'/bitrix/modules/sale/delivery/delivery_russianpost.php');

define('DELIVERY_RUSSIANPOST_WRITE_LOG', 0); // flag 'write to log'. use CDeliveryRUSSIANPOST::__WriteToLog() for logging.
define('DELIVERY_RUSSIANPOST_CACHE_LIFETIME', 2592000); // cache lifetime - 30 days (60*60*24*30)

define('DELIVERY_RUSSIANPOST_CATEGORY_DEFAULT', 23); // default delivery type

define('DELIVERY_RUSSIANPOST_PRICE_TARIFF', 0.03); // price koefficient - 3%
define('DELIVERY_RUSSIANPOST_PRICE_TARIFF_1', 0.04); // price koefficient - 4%

define('DELIVERY_RUSSIANPOST_SERVER_POST_CATEGORY', 'viewPost');
define('DELIVERY_RUSSIANPOST_SERVER_POST_CATEGORY_NAME', 'viewPostName');
define('DELIVERY_RUSSIANPOST_SERVER_POST_PROFILE', 'typePost');
define('DELIVERY_RUSSIANPOST_SERVER_POST_PROFILE_NAME', 'typePostName');
define('DELIVERY_RUSSIANPOST_SERVER_POST_ZIP', 'postOfficeId');
define('DELIVERY_RUSSIANPOST_SERVER_POST_WEIGHT', 'weight');
define('DELIVERY_RUSSIANPOST_SERVER_POST_PRICE', 'value1');

define('DELIVERY_RUSSIANPOST_SERVER_POST_COUNTRY', 'countryCode');
define('DELIVERY_RUSSIANPOST_SERVER_POST_COUNTRY_NAME', 'countryCodeName');

define('DELIVERY_RUSSIANPOST_SERVER', 'www.russianpost.ru');
define('DELIVERY_RUSSIANPOST_SERVER_PORT', 80);
define('DELIVERY_RUSSIANPOST_SERVER_PAGE', '/autotarif/Autotarif.aspx');
define('DELIVERY_RUSSIANPOST_SERVER_METHOD', 'GET');
define('DELIVERY_RUSSIANPOST_SERVER_METHOD_CAPTHA', 'POST');

define('DELIVERY_RUSSIANPOST_VALUE_CHECK_STRING', '<span id="TarifValue">');
define(
	'DELIVERY_RUSSIANPOST_VALUE_CHECK_REGEXP_RUS',
	'/<sup>\*<\/sup><\/td><td align="Right">*([0-9,]+)<\/td>/i'
);
define(
	'DELIVERY_RUSSIANPOST_VALUE_CHECK_REGEXP',
	'/<span id="TarifValue">*([0-9,]+)<\/span>/i'
);
define('DELIVERY_RUSSIANPOST_VALUE_CAPTHA_STRING', '<input id="key"');
define(
	'DELIVERY_RUSSIANPOST_CAPTHA_REGEXP',
	'/<input id="key" name="key" value="*([0-9,]+)"\/>/i'
);

class CDeliveryRUSSIANPOST
{
	function Init()
	{
		if (\Bitrix\Main\Loader::includeModule('currency') && $arCurrency = CCurrency::GetByID('RUR'))
		{
			$base_currency = 'RUR';
		}
		else
		{
			$base_currency = 'RUB';
		}

		return array(
			/* Basic description */
			"SID" => "russianpost",
			"NAME" => GetMessage('SALE_DH_RUSSIANPOST_NAME'),
			"DESCRIPTION" => GetMessage('SALE_DH_RUSSIANPOST_DESCRIPTION'),
			"DESCRIPTION_INNER" => GetMessage('SALE_DH_RUSSIANPOST_DESCRIPTION_INNER').GetMessage('SALE_DH_RUSSIANPOST_DESCRIPTION_INNER2'),
			"BASE_CURRENCY" => $base_currency,

			"HANDLER" => __FILE__,

			/* Handler methods */
			"DBGETSETTINGS" => array("CDeliveryRUSSIANPOST", "GetSettings"),
			"DBSETSETTINGS" => array("CDeliveryRUSSIANPOST", "SetSettings"),
			"GETCONFIG" => array("CDeliveryRUSSIANPOST", "GetConfig"),

			"COMPABILITY" => array("CDeliveryRUSSIANPOST", "Compability"),
			"CALCULATOR" => array("CDeliveryRUSSIANPOST", "Calculate"),
			"TRACKING_CLASS_NAME" => '\Bitrix\Sale\Delivery\Tracking\RusPost',

			"DEPRECATED" => "Y",
			"GET_ADMIN_MESSAGE" => array("CDeliveryRUSSIANPOST", "getAdminMessage"),
			
			/* List of delivery profiles */
			"PROFILES" => array(
				"ground" => array(
					"TITLE" => GetMessage("SALE_DH_RUSSIANPOST_GROUND_TITLE"),
					"DESCRIPTION" => '', //GetMessage("SALE_DH_RUSSIANPOST_GROUND_DESCRIPTION"),

					"RESTRICTIONS_WEIGHT" => array(0),
					"RESTRICTIONS_SUM" => array(0),
				),

				"avia" => array(
					"TITLE" => GetMessage("SALE_DH_RUSSIANPOST_AVIA_TITLE"),
					"DESCRIPTION" => '', //GetMessage("SALE_DH_RUSSIANPOST_AVIA_DESCRIPTION"),

					"RESTRICTIONS_WEIGHT" => array(0),
					"RESTRICTIONS_SUM" => array(0),
				),
			)
		);
	}

	function GetConfig()
	{
		$arConfig = array(
			"CONFIG_GROUPS" => array(
				"all" => GetMessage('SALE_DH_RUSSIANPOST_CONFIG_TITLE'),
			),

			"CONFIG" => array(
				"category" => array(
					"TYPE" => "DROPDOWN",
					"DEFAULT" => DELIVERY_RUSSIANPOST_CATEGORY_DEFAULT,
					"TITLE" => GetMessage('SALE_DH_RUSSIANPOST_CONFIG_CATEGORY'),
					"GROUP" => "all",
					"VALUES" => array(),
				),
			),
		);

		//$arList = array(42, 43, 44, 23, 52, 12, 13, 30, 41, 50, 33, 26, 53, 36, 16, 51, 54);
		$arList = array(23, 12, 13, 26, 36, 16);

		for ($i = 0, $cnt = count($arList); $i < $cnt; $i++)
		{
			$arConfig["CONFIG"]["category"]["VALUES"][$arList[$i]] = GetMessage('SALE_DH_RUSSIANPOST_CONFIG_CATEGORY_'.$arList[$i]);
		}

		return $arConfig;
	}

	function GetSettings($strSettings)
	{
		return array(
			"category" => intval($strSettings)
		);
	}

	function SetSettings($arSettings)
	{
		if(!isset($arSettings["category"]))
			$arSettings["category"] = DELIVERY_RUSSIANPOST_CATEGORY_DEFAULT;

		return intval($arSettings["category"]);
	}

	function __GetLocation($location, $bGetZIP = false)
	{
		$arLocation = CSaleHelper::getLocationByIdHitCached($location);

		$arLocation["IS_RUSSIAN"] = CDeliveryRUSSIANPOST::__IsRussian($arLocation) ? "Y" : "N";
		if ($bGetZIP)
		{
			$arLocation["ZIP"] = array();

			if ($arLocation["IS_RUSSIAN"] == "Y")
			{
				$rsZIPList = CSaleLocation::GetLocationZIP($location);
				while ($arZIP = $rsZIPList->Fetch())
				{
					$arLocation["ZIP"][] = $arZIP["ZIP"];
				}
			}
		}

		return $arLocation;
	}

	function __GetCountry($arLocation)
	{
		static $arRUSSIANPOSTCountryList;

		if (!is_array($arRUSSIANPOSTCountryList))
		{
			require("russianpost/country.php");
		}

		foreach ($arRUSSIANPOSTCountryList as $country_id => $country_name)
		{
			if (
				ToUpper($arLocation["COUNTRY_NAME_ORIG"]) == $country_name
				|| ToUpper($arLocation["COUNTRY_SHORT_NAME"]) == $country_name
				|| ToUpper($arLocation["COUNTRY_NAME_LANG"]) == $country_name
				|| ToUpper($arLocation["COUNTRY_NAME"]) == $country_name
			)
			{
				return array(
					"ID" => $country_id,
					"NAME" => $country_name,
				);
			}
		}
	}

	function Calculate($profile, $arConfig, $arOrder, $STEP, $TEMP = false)
	{
		if ($STEP >= 3)
		{
			return array(
				"RESULT" => "ERROR",
				"TEXT" => GetMessage('SALE_DH_RUSSIANPOST_ERROR_CONNECT'),
			);
		}

		if ($arOrder["WEIGHT"] <= 0)
			$arOrder["WEIGHT"] = 1;

		$arLocationFrom = CDeliveryRUSSIANPOST::__GetLocation($arOrder["LOCATION_FROM"]);

		if ($arOrder['LOCATION_ZIP'])
		{
			$arLocationTo = CDeliveryRUSSIANPOST::__GetLocation($arOrder["LOCATION_TO"]);
			$arLocationTo['ZIP'] = array(0 => $arOrder['LOCATION_ZIP']);
		}
		else
		{
			$arLocationTo = CDeliveryRUSSIANPOST::__GetLocation($arOrder["LOCATION_TO"], true);
		}

		$zip = COption::GetOptionString('sale', 'location_zip');
		if (strlen($zip) > 0)
			$arLocationFrom["ZIP"] = array(0 => $zip);

		if ($arLocationTo["IS_RUSSIAN"] == 'Y' && count($arLocationTo["ZIP"]) <= 0)
		{
			return array(
				"RESULT" => "ERROR",
				"TEXT" => GetMessage('SALE_DH_RUSSIANPOST_ERROR_NOZIP'),
			);
		}

		$cache_id = "sale|8.0.3|russianpost|".$profile."|".$arConfig["category"]["VALUE"]."|".$arOrder["LOCATION_FROM"]."|".($arLocationTo["IS_RUSSIAN"] == 'Y' ? $arLocationTo["ZIP"][0] : $arOrder["LOCATION_TO"]);

		if (in_array($arConfig["category"]["VALUE"], array(23, 12, 13, 26, 16)))
			$cache_id .= "|".ceil(intval($arOrder["WEIGHT"])/20)."_";
		else
			$cache_id .= "|".ceil(intval($arOrder["WEIGHT"])/500)."_";

		$obCache = new CPHPCache();
		if ($obCache->InitCache(DELIVERY_RUSSIANPOST_CACHE_LIFETIME, $cache_id, "/"))
		{
			$vars = $obCache->GetVars();
			$result = $vars["RESULT"];

			// only these delivery types have insurance tax of 3% or 4% from price
			if (in_array($arConfig["category"]["VALUE"], array(36, 26, 16)))
				$result += $arOrder["PRICE"] * DELIVERY_RUSSIANPOST_PRICE_TARIFF_1;

			return array(
				"RESULT" => "OK",
				"VALUE" => $result
			);
		}

		$arQuery = array();

		$arProfile = array("ground" => 1, "avia" => 2);

		if ($arLocationTo["IS_RUSSIAN"] == "Y")
		{
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_CATEGORY."=".urlencode($arConfig["category"]["VALUE"]);
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_CATEGORY_NAME."=".urlencode(GetMessage("SALE_DH_RUSSIANPOST_CONFIG_CATEGORY_".$arConfig["category"]["VALUE"]));

			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PROFILE."=".urlencode($arProfile[$profile]);
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PROFILE_NAME.'='.urlencode(GetMessage("SALE_DH_RUSSIANPOST_".ToUpper($profile)));
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_COUNTRY."=643";
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_COUNTRY_NAME.'='.urlencode($GLOBALS['APPLICATION']->ConvertCharset('Российская Федерация', LANG_CHARSET, 'utf-8'));

			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_WEIGHT."=".urlencode($arOrder["WEIGHT"]);

			// price does not affect on half of delivery types. others have 3% or 4% insurance tax which is ignored here for caching and used later.
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PRICE."=0";
			// if (!in_array($arConfig["category"]["VALUE"], array(26, 36, 16)))
			// {
				// $arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PRICE."=".urlencode(round($arOrder["PRICE"]));
			// }
			// else
			// {
				// $arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PRICE."=0";
			// }
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_ZIP."=".urlencode($arLocationTo["ZIP"][0]);
		}
		else
		{
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_CATEGORY."=".urlencode($arConfig["category"]["VALUE"]);
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_CATEGORY_NAME."=".urlencode(GetMessage("SALE_DH_RUSSIANPOST_CONFIG_CATEGORY_".$arConfig["category"]["VALUE"]));
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PROFILE."=".urlencode($arProfile[$profile]);
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PROFILE_NAME.'='.urlencode(GetMessage("SALE_DH_RUSSIANPOST_".ToUpper($profile)));
			$arCountry = CDeliveryRUSSIANPOST::__GetCountry($arLocationTo);

			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_COUNTRY."=".urlencode($arCountry["ID"]);
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_COUNTRY_NAME."=".urlencode($GLOBALS['APPLICATION']->ConvertCharset($arCountry["NAME"], LANG_CHARSET, 'utf-8'));

			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_WEIGHT."=".urlencode($arOrder["WEIGHT"]);
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_PRICE."=0";
			$arQuery[] = DELIVERY_RUSSIANPOST_SERVER_POST_ZIP."=0";
		}

		$res = self::sendRequestData($arQuery, DELIVERY_RUSSIANPOST_SERVER_METHOD);

		if (!$res->isSuccess())
		{
			$errors = "";

			foreach($res->getErrorMessages() as $message)
				$errors .= $message."\n";

			CDeliveryRUSSIANPOST::__Write2Log($errors);

			return array(
				"RESULT" => "ERROR",
				"TEXT" => GetMessage('SALE_DH_RUSSIANPOST_ERROR_CONNECT'),
			);
		}

		$data = $res->getData();
		$data = $GLOBALS['APPLICATION']->ConvertCharset($data["DATA"], 'utf-8', LANG_CHARSET);

		CDeliveryRUSSIANPOST::__Write2Log($data);

		if (strstr($data, DELIVERY_RUSSIANPOST_VALUE_CAPTHA_STRING))
		{
			$cResult = preg_match(
					DELIVERY_RUSSIANPOST_CAPTHA_REGEXP,
					$data,
					$matches
			);

			$arCode = array();
			$arCode["key"] = IntVal($matches[1]);

			$res = self::sendRequestData($arCode, DELIVERY_RUSSIANPOST_SERVER_METHOD_CAPTHA);

			if (!$res->isSuccess())
			{
				$errors = "";

				foreach($res->getErrorMessages() as $message)
					$errors .= $message."\n";

				CDeliveryRUSSIANPOST::__Write2Log($errors);

				return array(
					"RESULT" => "ERROR",
					"TEXT" => GetMessage('SALE_DH_RUSSIANPOST_ERROR_CONNECT'),
				);
			}
		}

		if (strstr($data, DELIVERY_RUSSIANPOST_VALUE_CHECK_STRING))
		{
			$bResult = preg_match(
				DELIVERY_RUSSIANPOST_VALUE_CHECK_REGEXP_RUS,
				$data,
				$matches
			);

			// both regexps must be checked! it's not only for russian and non-russian
			if (/*$arLocationTo["IS_RUSSIAN"] == "Y" && */!$bResult)
			{
				$bResult = preg_match(
					DELIVERY_RUSSIANPOST_VALUE_CHECK_REGEXP,
					$data,
					$matches
				);
			}

			if ($bResult)
			{
				$obCache->StartDataCache();

				$result = $matches[1];
				$result = str_replace(array(" ", ","), array("", "."), $result);
				$result = doubleval($result);

				$obCache->EndDataCache(
					array(
						"RESULT" => $result
					)
				);

				// only these delivery types have insurance tax of 3% or 4% from price
				if (in_array($arConfig["category"]["VALUE"], array(26, 16, 36)))
					$result += $arOrder["PRICE"] * DELIVERY_RUSSIANPOST_PRICE_TARIFF_1;

				return array(
					"RESULT" => "OK",
					"VALUE" => $result,
				);
			}
			else
			{
				return array(
					"RESULT" => "ERROR",
					"TEXT" => GetMessage('SALE_DH_RUSSIANPOST_ERROR_RESPONSE'),
				);
			}
		}
		else
			return array(
				"RESULT" => "ERROR",
				"TEXT" => GetMessage('SALE_DH_RUSSIANPOST_ERROR_RESPONSE'),
			);
	}

	function Compability($arOrder, $arConfig)
	{
		$arLocationFrom = CSaleHelper::getLocationByIdHitCached($arOrder["LOCATION_FROM"]);

		if (
			ToUpper($arLocationFrom["CITY_NAME_ORIG"]) == "МОСКВА"
			|| ToUpper($arLocationFrom["CITY_SHORT_NAME"]) == "МОСКВА"
			|| ToUpper($arLocationFrom["CITY_NAME_LANG"]) == "МОСКВА"
			|| ToUpper($arLocationFrom["CITY_NAME_ORIG"]) == "MOSCOW"
			|| ToUpper($arLocationFrom["CITY_SHORT_NAME"]) == "MOSCOW"
			|| ToUpper($arLocationFrom["CITY_NAME_LANG"]) == "MOSCOW"
		)
		{
			$arLocationTo = CSaleHelper::getLocationByIdHitCached($arOrder["LOCATION_TO"]);

			if (!CDeliveryRUSSIANPOST::__IsRussian($arLocationTo) && $arConfig['category']['VALUE'] == 26)
				return array();

			if (isset($arConfig["category"]["VALUE"]) && $arConfig["category"]["VALUE"] == 26 )
				return array("ground");
			else
				return array("ground", "avia");
		}
		else
		{
			return array();
		}
	}

	function __IsRussian($arLocation)
	{
		return
			(ToUpper($arLocation["COUNTRY_NAME_ORIG"]) == "РОССИЯ"
			|| ToUpper($arLocation["COUNTRY_SHORT_NAME"]) == "РОССИЯ"
			|| ToUpper($arLocation["COUNTRY_NAME_LANG"]) == "РОССИЯ"
			|| ToUpper($arLocation["COUNTRY_NAME_ORIG"]) == "RUSSIA"
			|| ToUpper($arLocation["COUNTRY_SHORT_NAME"]) == "RUSSIA"
			|| ToUpper($arLocation["COUNTRY_NAME_LANG"]) == "RUSSIA"
			|| ToUpper($arLocation["COUNTRY_NAME_ORIG"]) == "РОССИЙСКАЯ ФЕДЕРАЦИЯ"
			|| ToUpper($arLocation["COUNTRY_SHORT_NAME"]) == "РОССИЙСКАЯ ФЕДЕРАЦИЯ"
			|| ToUpper($arLocation["COUNTRY_NAME_LANG"]) == "РОССИЙСКАЯ ФЕДЕРАЦИЯ"
			|| ToUpper($arLocation["COUNTRY_NAME_ORIG"]) == "RUSSIAN FEDERATION"
			|| ToUpper($arLocation["COUNTRY_SHORT_NAME"]) == "RUSSIAN FEDERATION"
			|| ToUpper($arLocation["COUNTRY_NAME_LANG"]) == "RUSSIAN FEDERATION"
			|| ($arLocation["COUNTRY_NAME_LANG"] === null && $arLocation["COUNTRY_NAME_ORIG"] === null)
		);
	}

	function __Write2Log($data)
	{
		if (defined('DELIVERY_RUSSIANPOST_WRITE_LOG') && DELIVERY_RUSSIANPOST_WRITE_LOG === 1)
		{
			$fp = fopen(dirname(__FILE__)."/russianpost.log", "a");
			fwrite($fp, "\r\n==========================================\r\n");
			fwrite($fp, $data);
			fclose($fp);
		}
	}

	/**
	 * @param $data
	 * @return \Bitrix\Main\Entity\Result
	 */
	protected static function sendRequestData($data, $method)
	{
		$result = new \Bitrix\Main\Entity\Result();
		$url = "http://".DELIVERY_RUSSIANPOST_SERVER.DELIVERY_RUSSIANPOST_SERVER_PAGE;
		$reqResult = false;

		$httpClient = new \Bitrix\Main\Web\HttpClient(array(
			"version" => "1.1",
			"socketTimeout" => 30,
			"streamTimeout" => 30,
			"redirect" => true,
			"redirectMax" => 5,
		));

		$method = (DELIVERY_RUSSIANPOST_SERVER_METHOD == $method ? \Bitrix\Main\Web\HttpClient::HTTP_GET : \Bitrix\Main\Web\HttpClient::HTTP_POST);

		if($httpClient->query($method, $url, $data))
			$reqResult =$httpClient->getResult();

		$errors = $httpClient->getError();

		if (!$reqResult && !empty($errors))
		{
			foreach($errors as $errorCode => $errMes)
				$result->addError(new \Bitrix\Main\Entity\EntityError($errorCode.": ".$errMes));
		}
		else
		{
			$status = $httpClient->getStatus();

			if ($status != 200)
			{
				$result->addError(new \Bitrix\Main\Entity\EntityError('HTTP error code: %d', $status));
			}
			else
			{
				$result->setData(array("DATA" => $reqResult));
			}
		}

		return $result;
	}

	public function getAdminMessage()
	{
		return array(
			'MESSAGE' => GetMessage(
				'SALE_DH_RUSSIANPOST_MESSAGE',
				array(
					'#A1#' => '<a href="/bitrix/admin/sale_delivery_service_edit.php?lang='.LANGUAGE_ID.'&PARENT_ID=0&CLASS_NAME=%5CSale%5CHandlers%5CDelivery%5CAdditionalHandler&SERVICE_TYPE=RUSPOST">',
					'#A2#' => '</a>'
				)
			),
			"TYPE" => "ERROR",
			"HTML" => true
		);
	}	
}

AddEventHandler("sale", "onSaleDeliveryHandlersBuildList", array('CDeliveryRUSSIANPOST', 'Init'));
?>

Zerion Mini Shell 1.0