%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/components/bitrix/sale.personal.order.list/ |
Current File : /home/bitrix/www/bitrix/components/bitrix/sale.personal.order.list/class.php |
<?php /** * Bitrix Framework * @package bitrix * @subpackage sale * @copyright 2001-2014 Bitrix */ use Bitrix\Main, Bitrix\Main\Config, Bitrix\Main\Localization, Bitrix\Main\Loader, Bitrix\Main\Data, Bitrix\Sale, Bitrix\Sale\OrderStatus, Bitrix\Sale\Cashbox\CheckManager; if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); class CBitrixPersonalOrderListComponent extends CBitrixComponent { const E_SALE_MODULE_NOT_INSTALLED = 10000; const E_CANNOT_COPY_ORDER_NOT_FOUND = 10001; const E_CANNOT_COPY_CANT_ADD_BASKET = 10002; const E_CATALOG_MODULE_NOT_INSTALLED = 10003; const E_NOT_AUTHORIZED = 10004; /** * Fatal error list. Any fatal error makes useless further execution of a component code. * In most cases, there will be only one error in a list according to the scheme "one shot - one dead body" * * @var string[] Array of fatal errors. */ protected $errorsFatal = array(); /** * Non-fatal error list. Some non-fatal errors may occur during component execution, so certain functions of the component * may became defunct. Still, user should stay informed. * There may be several non-fatal errors in a list. * * @var string[] Array of non-fatal errors. */ protected $errorsNonFatal = array(); /** * Contains some valuable info from $_REQUEST * * @var object request info */ protected $requestData = array(); /** * Gathered options that are required * * @var string[] options */ protected $options = array(); protected $useIblock = true; /** * A value of current date format * * @var string format */ private $dateFormat = ''; /** * Filter used when select orders * * @var mixed[] filter */ protected $filter = array(); /** * Sort field for query * * @var string field */ protected $sortBy = false; /** * Sort direction for query * * @var string order: asc or desc */ protected $sortOrder = false; /** * @var Sale\Registry registry */ protected $registry = null; protected $dbResult = array(); private $dbQueryResult = array(); /**@var Data\Cache $this->currentCache */ protected $currentCache = null; /** * A convert map for method self::formatDate() * * @var string[] keys */ protected $orderDateFields2Convert = array( 'DATE_INSERT', 'DATE_STATUS', 'PAY_VOUCHER_DATE', 'DATE_DEDUCTED', 'DATE_UPDATE', 'PS_RESPONSE_DATE', 'DATE_PAY_BEFORE', 'DATE_BILL', 'DATE_CANCELED' ); /** * A convert map for method self::formatDate() * * @var string[] keys */ protected $basketDateFields2Convert = array( 'DATE_INSERT', 'DATE_UPDATE' ); public function __construct($component = null) { parent::__construct($component); CPageOption::SetOptionString("main", "nav_page_in_session", "N"); $this->dateFormat = Main\Context::getCurrent()->getCulture()->getDateTimeFormat(); Localization\Loc::loadMessages(__FILE__); } /** * Function checks if required modules installed. If not, throws an exception * @throws Main\SystemException * @return void */ protected function checkRequiredModules() { if (!Loader::includeModule('sale')) throw new Main\SystemException(Localization\Loc::getMessage("SPOL_SALE_MODULE_NOT_INSTALL"), self::E_SALE_MODULE_NOT_INSTALLED); if (!Loader::includeModule('iblock')) $this->useIblock = false; } /** * Function checks if user is authorized or not. If not, auth form will be shown. * @return void * @throws Main\SystemException */ protected function checkAuthorized() { global $USER; global $APPLICATION; if (!$USER->IsAuthorized()) { $msg = Localization\Loc::getMessage("SPOL_ACCESS_DENIED"); // for compatibility reasons: by default AuthForm() is shown in class.php, as it used to be. // BUT the better way is to show it in template.php, as it required by MVC paradigm if(!$this->arParams['AUTH_FORM_IN_TEMPLATE']) { $APPLICATION->AuthForm($msg, false, false, 'N', false); } throw new Main\SystemException($msg, self::E_NOT_AUTHORIZED); } } /** * Function checks and prepares all the parameters passed. Everything about $arParam modification is here. * @param mixed[] $arParams List of unchecked parameters * @return mixed[] Checked and valid parameters */ public function onPrepareComponentParams($arParams) { global $APPLICATION; $this->tryParseInt($arParams["CACHE_TIME"], 3600, true); $arParams['CACHE_GROUPS'] = trim($arParams['CACHE_GROUPS']); if ('N' != $arParams['CACHE_GROUPS']) $arParams['CACHE_GROUPS'] = 'Y'; $this->tryParseString($arParams["PATH_TO_DETAIL"], $APPLICATION->GetCurPage()."?"."ID=#ID#"); $this->tryParseString($arParams["PATH_TO_COPY"], $APPLICATION->GetCurPage()."?"."ID=#ID#"); $this->tryParseString($arParams["PATH_TO_CANCEL"], $APPLICATION->GetCurPage()."?"."ID=#ID#"); $this->tryParseString($arParams["PATH_TO_BASKET"], "basket.php"); $this->tryParseString($arParams["PATH_TO_PAYMENT"], "/personal/order/payment/"); if ($arParams["SAVE_IN_SESSION"] != "N") $arParams["SAVE_IN_SESSION"] = "Y"; if (!is_array($arParams['HISTORIC_STATUSES']) || empty($arParams['HISTORIC_STATUSES'])) $arParams['HISTORIC_STATUSES'] = array('F'); $arParams["NAV_TEMPLATE"] = (strlen($arParams["NAV_TEMPLATE"]) ? $arParams["NAV_TEMPLATE"] : ""); $this->tryParseInt($arParams["ORDERS_PER_PAGE"], 20); $this->tryParseString($arParams["ACTIVE_DATE_FORMAT"], "d.m.Y"); $this->tryParseBoolean($arParams['AUTH_FORM_IN_TEMPLATE']); if (empty($arParams['REFRESH_PRICES'])) { $arParams['REFRESH_PRICES'] = "N"; } if (empty($arParams['ALLOW_INNER'])) { $arParams['ALLOW_INNER'] = "N"; } if (empty($arParams['ONLY_INNER_FULL'])) { $arParams['ONLY_INNER_FULL'] = "Y"; } if (!CBXFeatures::IsFeatureEnabled('SaleAccounts')) { $arParams['ALLOW_INNER'] = "N"; } if (empty($arParams['DEFAULT_SORT'])) { $arParams['DEFAULT_SORT'] = 'STATUS'; } return $arParams; } /** * Function reduces input value to integer type, and, if gets null, passes the default value * @param mixed $fld Field value * @param int $default Default value * @param int $allowZero Allows zero-value of the parameter * @return int Parsed value */ public static function tryParseInt(&$fld, $default, $allowZero = null) { $fld = intval($fld); if(!$allowZero && !$fld && isset($default)) $fld = $default; return $fld; } /** * Function processes string value and, if gets null, passes the default value to it * @param mixed $fld Field value * @param string $default Default value * @return string parsed value */ public static function tryParseString(&$fld, $default) { $fld = trim((string)$fld); if(!strlen($fld) && isset($default)) $fld = htmlspecialcharsbx($default); return $fld; } /** * Function forces 'Y'/'N' value to boolean * @param mixed $fld Field value * @return string parsed value */ public static function tryParseBoolean(&$fld) { $fld = $fld == 'Y'; return $fld; } /** * Function sets page title, if required * @return void */ protected function setTitle() { global $APPLICATION; if ($this->arParams["SET_TITLE"] == 'Y') $APPLICATION->SetTitle(Localization\Loc::getMessage("SPOL_DEFAULT_TITLE")); } /** * Function gets all options required for component * @return void */ protected function getOptions() { $this->options['USE_ACCOUNT_NUMBER'] = \Bitrix\Sale\Integration\Numerator\NumeratorOrder::isUsedNumeratorForOrder(); } /** * Function processes and corrects $_REQUEST. Everything about $_REQUEST lies here. * @return void */ protected function processRequest() { $this->requestData["COPY_ORDER"] = ($_REQUEST["COPY_ORDER"] == "Y"); $this->requestData["ID"] = urldecode(urldecode($this->arParams["ID"])); if (strlen($_REQUEST["del_filter"])) { unset($_REQUEST["filter_id"]); unset($_REQUEST["filter_date_from"]); unset($_REQUEST["filter_date_to"]); unset($_REQUEST["filter_status"]); unset($_REQUEST["filter_payed"]); unset($_REQUEST["filter_canceled"]); $_REQUEST["filter_history"] = "Y"; if ($this->arParams["SAVE_IN_SESSION"] == "Y") { unset($_SESSION["spo_filter_id"]); unset($_SESSION["spo_filter_date_from"]); unset($_SESSION["spo_filter_date_to"]); unset($_SESSION["spo_filter_status"]); unset($_SESSION["spo_filter_payed"]); unset($_SESSION["spo_filter_canceled"]); $_SESSION["spo_filter_history"] = "Y"; } } $this->filterRestore(); $this->filterStore(); $orderClassName = $this->registry->getOrderClassName(); $tableFieldNameList = $orderClassName::getAllFields(); if (isset($_REQUEST["by"]) && strval($_REQUEST['by']) != '') { if (!in_array($_REQUEST['by'], $tableFieldNameList)) $_REQUEST["by"] = $this->arParams['DEFAULT_SORT']; } $this->sortBy = (strlen($_REQUEST["by"]) ? $_REQUEST["by"]: $this->arParams['DEFAULT_SORT']); $this->sortOrder = (strlen($_REQUEST["order"]) != "" && $_REQUEST["order"] == "ASC" ? "ASC": "DESC"); $this->prepareFilter(); } /** * Read filter from session (or anywhere else), if required * @return void */ protected function filterRestore() { if ($this->arParams["SAVE_IN_SESSION"] == "Y" && !strlen($_REQUEST["filter"])) { if (intval($_SESSION["spo_filter_id"])) $_REQUEST["filter_id"] = $_SESSION["spo_filter_id"]; if (strlen($_SESSION["spo_filter_date_from"])) $_REQUEST["filter_date_from"] = $_SESSION["spo_filter_date_from"]; if (strlen($_SESSION["spo_filter_date_to"])) $_REQUEST["filter_date_to"] = $_SESSION["spo_filter_date_to"]; if (strlen($_SESSION["spo_filter_status"])) $_REQUEST["filter_status"] = $_SESSION["spo_filter_status"]; if (strlen($_SESSION["spo_filter_payed"])) $_REQUEST["filter_payed"] = $_SESSION["spo_filter_payed"]; if (strlen($_SESSION["spo_filter_canceled"])) $_REQUEST["filter_canceled"] = $_SESSION["spo_filter_canceled"]; if ($_SESSION["spo_filter_history"] == "Y") $_REQUEST["filter_history"] = "Y"; } } /** * Store filter in session (or anywhere else), if required. * @return void */ protected function filterStore() { if ($this->arParams["SAVE_IN_SESSION"] == "Y" && strlen($_REQUEST["filter"])) { $_SESSION["spo_filter_id"] = $_REQUEST["filter_id"]; $_SESSION["spo_filter_date_from"] = $_REQUEST["filter_date_from"]; $_SESSION["spo_filter_date_to"] = $_REQUEST["filter_date_to"]; $_SESSION["spo_filter_status"] = $_REQUEST["filter_status"]; $_SESSION["spo_filter_payed"] = $_REQUEST["filter_payed"]; $_SESSION["spo_filter_history"] = $_REQUEST["filter_history"]; } } /** * Creates filter for CSaleOrder::GetList() based on $_REQUEST and other parameters * @return void */ protected function prepareFilter() { global $USER; global $DB; $arFilter = array(); $arFilter["USER_ID"] = $USER->GetID(); $arFilter["LID"] = SITE_ID; if (strlen($_REQUEST["filter_id"])) { if ($this->options['USE_ACCOUNT_NUMBER']) $arFilter["ACCOUNT_NUMBER"] = $_REQUEST["filter_id"]; else $arFilter["ID"] = intval($_REQUEST["filter_id"]); } if (strlen($_REQUEST["filter_date_from"])) { $arFilter[">=DATE_INSERT"] = trim($_REQUEST["filter_date_from"]); } if (strlen($_REQUEST["filter_date_to"])) { $arFilter["<=DATE_INSERT"] = trim($_REQUEST["filter_date_to"]); if ($arDate = ParseDateTime(trim($_REQUEST["filter_date_to"]), $this->dateFormat)) { if (strlen(trim($_REQUEST["filter_date_to"])) < 11) { $arDate["HH"] = 23; $arDate["MI"] = 59; $arDate["SS"] = 59; } $arFilter["<=DATE_INSERT"] = date($DB->DateFormatToPHP($this->dateFormat), mktime($arDate["HH"], $arDate["MI"], $arDate["SS"], $arDate["MM"], $arDate["DD"], $arDate["YYYY"])); } } if (strlen($_REQUEST["filter_status"])) $arFilter["STATUS_ID"] = trim($_REQUEST["filter_status"]); if (strlen($_REQUEST["filter_payed"])) $arFilter["PAYED"] = trim($_REQUEST["filter_payed"]); if (!isset($_REQUEST['show_all']) || $_REQUEST['show_all'] == 'N') { if (isset($_REQUEST["filter_history"]) && $_REQUEST["filter_history"] == "Y") { if ($_REQUEST["show_canceled"] == "Y") { $arFilter['CANCELED'] = 'Y'; } else { $arFilter[] = array( '@STATUS_ID' => $this->arParams['HISTORIC_STATUSES'] ); } } else { $arFilter[] = array( '!@STATUS_ID' => $this->arParams['HISTORIC_STATUSES'], 'CANCELED' => 'N' ); } } if (strlen($_REQUEST["filter_canceled"])) $arFilter["CANCELED"] = trim($_REQUEST["filter_canceled"]); $this->filter = $arFilter; } /** * Function wraps action list evaluation into try-catch block. * @return void */ private function performActions() { try { $this->performActionList(); } catch (Exception $e) { $this->errorsNonFatal[$e->getCode()] = $e->getMessage(); } } /** * Function perform pre-defined list of actions based on current state of $_REQUEST and parameters. * @return void */ protected function performActionList() { // copy order $this->performActionCopyOrder(); // some other ... } /** * Function checks if order with supplied id is really exists. * @param int|string $id Order id * @return int Order id */ private function getRealId($id) { global $USER; $orderResult = false; $filter = array( 'select' => array("ID"), 'filter' => array("USER_ID" => $USER->GetID(), "LID" => SITE_ID), 'order' => array("ID"=>"DESC") ); if ($this->options['USE_ACCOUNT_NUMBER']) { $filter['filter']['ACCOUNT_NUMBER'] = $id; $orderList = Sale\Order::getList($filter); $orderResult = $orderList->fetch(); } if (!$orderResult) { $filter['filter']['ID'] = $id; $orderList = Sale\Order::getList($filter); $orderResult = $orderList->fetch(); } if (empty($orderResult)) { return false; } return $orderResult['ID']; } /** * Perform the following action: copy order * @throws Main\SystemException * @return void */ protected function performActionCopyOrder() { if (strlen($this->requestData["ID"]) && $this->requestData["COPY_ORDER"]) { if($id = $this->getRealId($this->requestData["ID"])) $this->copyOrder2CustomerBasket($id); else throw new Main\SystemException(Localization\Loc::getMessage('SPOL_CANNOT_COPY_ORDER'), self::E_CANNOT_COPY_ORDER_NOT_FOUND); } } /** * Function obtains all properties of a basket item * @param int $id Basket item Id to search for * @return mixed[] List of basket item properties */ protected function getBasketItemProps($id) { $basketProperties = array(); $filter = array( 'select' => array("ID", "BASKET_ID", "NAME", "VALUE", "CODE", "SORT"), 'filter' => array("BASKET_ID" => $id), 'order' => array("SORT" => "ASC") ); $basketList = Sale\Basket::getList($filter); while ($basket = $basketList->fetch()) { $basketProperties[] = array( "NAME" => $basket["NAME"], "CODE" => $basket["CODE"], "VALUE" => $basket["VALUE"] ); } return $basketProperties; } /** * The default action in case of success copying order * @return void */ protected function doAfterOrderCopyed() { LocalRedirect($this->arParams["PATH_TO_BASKET"]); } /** * Function performs moving entire basket content of a certain order into client`s basket. It implements "copy order" action. * @param int $id Order id * @throws Main\SystemException * @return void */ protected function copyOrder2CustomerBasket($id) { $orderClassName = $this->registry->getOrderClassName(); $basketClassName = $this->registry->getBasketClassName(); if ($id) { /** @var Sale\Basket $basket */ $basket = $basketClassName::loadItemsForFUser(Sale\Fuser::getId(), Main\Context::getCurrent()->getSite()); $filterFields = array( 'SET_PARENT_ID', 'TYPE', 'PRODUCT_ID', 'PRODUCT_PRICE_ID', 'PRICE', 'CURRENCY', 'WEIGHT', 'QUANTITY', 'LID', 'NAME', 'CALLBACK_FUNC', 'NOTES', 'PRODUCT_PROVIDER_CLASS', 'CANCEL_CALLBACK_FUNC', 'ORDER_CALLBACK_FUNC', 'PAY_CALLBACK_FUNC', 'DETAIL_PAGE_URL', 'CATALOG_XML_ID', 'PRODUCT_XML_ID', 'VAT_RATE', 'MEASURE_NAME', 'MEASURE_CODE', 'BASE_PRICE', 'VAT_INCLUDED' ); $filterFields = array_flip($filterFields); /** @var Sale\Order $oldOrder */ $oldOrder = $orderClassName::load($id); $oldBasket = $oldOrder->getBasket(); $refreshStrategy = Sale\Basket\RefreshFactory::create(Sale\Basket\RefreshFactory::TYPE_FULL); $oldBasket->refresh($refreshStrategy); $oldBasketItems = $oldBasket->getOrderableItems(); /** @var Sale\BasketItem $oldBasketItem*/ foreach ($oldBasketItems as $oldBasketItem) { $propertyList = array(); if ($oldPropertyCollection = $oldBasketItem->getPropertyCollection()) { $propertyList = $oldPropertyCollection->getPropertyValues(); } $item = $basket->getExistsItem($oldBasketItem->getField('MODULE'), $oldBasketItem->getField('PRODUCT_ID'), $propertyList); if ($item) { $item->setField('QUANTITY', $item->getQuantity() + $oldBasketItem->getQuantity()); } else { $item = $basket->createItem($oldBasketItem->getField('MODULE'), $oldBasketItem->getField('PRODUCT_ID')); $oldBasketValues = array_intersect_key($oldBasketItem->getFieldValues(), $filterFields); $item->setField('NAME', $oldBasketValues['NAME']); $resultItem = $item->setFields($oldBasketValues); if (!$resultItem->isSuccess()) continue; /** @var Sale\PropertyValueCollection $newPropertyCollection*/ $newPropertyCollection = $item->getPropertyCollection(); /** @var Sale\BasketPropertyItem $oldProperty*/ foreach ($propertyList as $oldPropertyFields) { $propertyItem = $newPropertyCollection->createItem($oldPropertyFields); unset($oldPropertyFields['ID'], $oldPropertyFields['BASKET_ID']); /** @var Sale\BasketPropertyItem $propertyItem*/ $propertyItem->setFields($oldPropertyFields); } } } $result = $basket->save(); if (!$result->isSuccess()) { $errorList = $result->getErrors(); foreach ($errorList as $key => $error) { $this->errorsNonFatal[$error->getCode()."_".$key] = $error->getMessage(); } throw new Main\SystemException(Localization\Loc::getMessage('SPOL_CANNOT_COPY_ORDER'), self::E_CANNOT_COPY_CANT_ADD_BASKET); } $this->doAfterOrderCopyed(); } } /** * Read some data from database, using cache. Under some info we mean status list, delivery system list and so on. * This will be a shared cache between sale.personal.order.list and sale.personal.order.detail, so beware of collisions. * @return void * @throws Exception * @throws Main\SystemException */ protected function obtainDataReferences() { if ($this->startCache(array('spo-shared'))) { try { $cachedData = array(); ///////////////////// ///////////////////// // Person type $cachedData['PERSON_TYPE'] = array(); $personTypeClassName = $this->registry->getPersonTypeClassName(); $cachedData['PERSON_TYPE'] = $personTypeClassName::load(SITE_ID); // Save statuses for Filter form $cachedData['STATUS'] = array(); $orderStatusClassName = $this->registry->getOrderStatusClassName(); $listStatusNames = $orderStatusClassName::getAllStatusesNames(LANGUAGE_ID); foreach($listStatusNames as $key => $data) { $cachedData['STATUS'][$key] = array('ID'=>$key,'NAME'=>$data); } $cachedData['PAYSYS'] = array(); $paySystemsList = Sale\PaySystem\Manager::getList(array()); while ($paySystem = $paySystemsList->fetch()) { $paySystem['NAME'] = htmlspecialcharsbx($paySystem['NAME']); $cachedData['PAYSYS'][$paySystem["ID"]] = $paySystem; } $cachedData['DELIVERY'] = array(); $dbDelivery = \Bitrix\Sale\Delivery\Services\Table::getList(); $deliveryService = array(); while ($delivery = $dbDelivery->fetch()) $deliveryService[$delivery['ID']] = $delivery; foreach ($deliveryService as $delivery) { $cachedData['DELIVERY'][$delivery["ID"]] = $delivery; if ($delivery['PARENT_ID']) { $cachedData['DELIVERY'][$delivery["ID"]]['NAME'] = htmlspecialcharsbx($deliveryService[$delivery['PARENT_ID']]['NAME'].':'.$delivery['NAME']); if (empty($delivery['LOGOTIP'])) $cachedData['DELIVERY'][$delivery["ID"]]['LOGOTIP'] = $deliveryService[$delivery['PARENT_ID']]['LOGOTIP']; } else { $cachedData['DELIVERY'][$delivery["ID"]]['NAME'] = htmlspecialcharsbx($delivery['NAME']); } } ///////////////////// ///////////////////// } catch (Exception $e) { $this->abortCache(); throw $e; } $this->endCache($cachedData); } else $cachedData = $this->getCacheData(); $this->dbResult = array_merge($this->dbResult, $cachedData); } /** * Perform reading main data from database, no cache is used * @return void */ protected function obtainDataOrders() { $listOrders = array(); $orderIdList = array(); $listOrderBasket = array(); $listOrderShipment = array(); $listOrderPayment = array(); $select = array( 'ID', 'LID', 'PERSON_TYPE_ID', 'PAYED', 'DATE_PAYED', 'EMP_PAYED_ID', 'CANCELED', 'DATE_CANCELED', 'EMP_CANCELED_ID', 'REASON_CANCELED', 'MARKED', 'DATE_MARKED', 'EMP_MARKED_ID', 'REASON_MARKED', 'STATUS_ID', 'DATE_STATUS', 'PAY_VOUCHER_NUM', 'PAY_VOUCHER_DATE', 'EMP_STATUS_ID', 'PRICE_DELIVERY', 'ALLOW_DELIVERY', 'DATE_ALLOW_DELIVERY', 'EMP_ALLOW_DELIVERY_ID', 'DEDUCTED', 'DATE_DEDUCTED', 'EMP_DEDUCTED_ID', 'REASON_UNDO_DEDUCTED', 'RESERVED', 'PRICE', 'CURRENCY', 'DISCOUNT_VALUE', 'SUM_PAID', 'USER_ID', 'PAY_SYSTEM_ID', 'DELIVERY_ID', 'DATE_INSERT', 'DATE_UPDATE', 'USER_DESCRIPTION', 'ADDITIONAL_INFO', 'TAX_VALUE', 'STAT_GID', 'RECURRING_ID', 'RECOUNT_FLAG', 'DELIVERY_DOC_NUM', 'DELIVERY_DOC_DATE', 'STORE_ID', 'ORDER_TOPIC', 'RESPONSIBLE_ID', 'DATE_PAY_BEFORE', 'DATE_BILL', 'ACCOUNT_NUMBER', 'TRACKING_NUMBER', 'XML_ID' ); $getListParams = array( 'filter' => $this->filter, 'select' => $select ); if ($this->sortBy == 'STATUS') { $getListParams['runtime'] = array( new \Bitrix\Main\Entity\ReferenceField( 'STATUS', '\Bitrix\Sale\Internals\StatusTable', array( '=this.STATUS_ID' => 'ref.ID', ), array( "join_type" => 'inner' ) ) ); $getListParams['order'] = array("STATUS.SORT" => 'ASC', 'ID' => $this->sortOrder); } else { $getListParams['order'] = array($this->sortBy => $this->sortOrder); } if (class_exists('LandingPubComponent') && method_exists('LandingPubComponent', 'getMainInstance')) { $currentLandingInstance = \LandingPubComponent::getMainInstance(); if ((int)($currentLandingInstance['SITE_ID']) > 0) { $code = \Bitrix\Sale\TradingPlatform\Landing\Landing::getCodeBySiteId((int)$currentLandingInstance['SITE_ID']); $platformId = \Bitrix\Sale\TradingPlatform\Landing\Landing::getInstanceByCode($code)->getId(); if ((int)$platformId > 0) { $getListParams['runtime'][] = new \Bitrix\Main\Entity\ReferenceField( 'TRADING_BINDING', '\Bitrix\Sale\TradingPlatform\OrderTable', array( '=this.ID' => 'ref.ORDER_ID', '=ref.TRADING_PLATFORM_ID' => new \Bitrix\Main\DB\SqlExpression('?i', $platformId) ), array( "join_type" => 'inner' ) ); $getListParams['runtime'][] = new \Bitrix\Main\Entity\ReferenceField( 'TRADING', '\Bitrix\Sale\TradingPlatformTable', array( '=this.TRADING_BINDING.TRADING_PLATFORM_ID' => 'ref.ID', '=ref.CLASS' => new \Bitrix\Main\DB\SqlExpression('?', "\\".\Bitrix\Sale\TradingPlatform\Landing\Landing::class) ), array( "join_type" => 'inner' ) ); } } } $usePageNavigation = true; $totalPages = 0; $totalCount = 0; $orderClassName = $this->registry->getOrderClassName(); \CPageOption::SetOptionString("main", "nav_page_in_session", "N"); $navyParams = \CDBResult::GetNavParams(); if ($navyParams['SHOW_ALL']) { $usePageNavigation = false; } else { $navyParams['PAGEN'] = (int)$navyParams['PAGEN']; $navyParams['SIZEN'] = (int)$navyParams['SIZEN']; if (isset($this->arParams["ORDERS_PER_PAGE"]) && intval($this->arParams["ORDERS_PER_PAGE"]) > 0) { $navyParams['SIZEN'] = $this->arParams["ORDERS_PER_PAGE"]; } $getListParams['limit'] = $navyParams['SIZEN']; $getListParams['offset'] = $navyParams['SIZEN']*($navyParams['PAGEN']-1); /** @var Main\DB\Result $countQuery */ $countQuery = $orderClassName::getList( array( "filter"=>$getListParams['filter'], "runtime"=>$getListParams['runtime'], "select"=>array(new \Bitrix\Main\Entity\ExpressionField('CNT', 'COUNT(1)')) ) ); $totalCount = $countQuery->fetch(); $totalCount = (int)$totalCount['CNT']; unset($countQuery); if ($totalCount > 0) { $totalPages = ceil($totalCount/$navyParams['SIZEN']); if ($navyParams['PAGEN'] > $totalPages) $navyParams['PAGEN'] = $totalPages; $getListParams['limit'] = $navyParams['SIZEN']; $getListParams['offset'] = $navyParams['SIZEN']*($navyParams['PAGEN']-1); } else { $navyParams['PAGEN'] = 1; $getListParams['limit'] = $navyParams['SIZEN']; $getListParams['offset'] = 0; } } $this->dbQueryResult['ORDERS'] = new \CDBResult($orderClassName::getList($getListParams)); if ($usePageNavigation) { $this->dbQueryResult['ORDERS']->NavStart($getListParams['limit'], $navyParams['SHOW_ALL'], $navyParams['PAGEN']); $this->dbQueryResult['ORDERS']->NavRecordCount = $totalCount; $this->dbQueryResult['ORDERS']->NavPageCount = $totalPages; $this->dbQueryResult['ORDERS']->NavPageNomer = $navyParams['PAGEN']; } else { if ((int)($this->arParams["ORDERS_PER_PAGE"])) { $this->dbQueryResult['ORDERS']->NavStart($this->arParams["ORDERS_PER_PAGE"], false); } } if (empty($this->dbQueryResult['ORDERS'])) { return; } while ($arOrder = $this->dbQueryResult['ORDERS']->GetNext()) { if ( is_array($this->arParams['RESTRICT_CHANGE_PAYSYSTEM']) && in_array($arOrder['STATUS_ID'], $this->arParams['RESTRICT_CHANGE_PAYSYSTEM']) ) { $arOrder['LOCK_CHANGE_PAYSYSTEM'] = 'Y'; } $listOrders[$arOrder["ID"]] = $arOrder; $orderIdList[] = $arOrder["ID"]; } $basketClassName = $this->registry->getBasketClassName(); /** @var Main\DB\Result $listBaskets */ $listBaskets = $basketClassName::getList(array( 'select' => array("*"), 'filter' => array("ORDER_ID" => $orderIdList), 'order' => array('NAME' => 'asc') )); while ($basket = $listBaskets->fetch()) { if (CSaleBasketHelper::isSetItem($basket)) continue; $listOrderBasket[$basket['ORDER_ID']][$basket['ID']] = $basket; } $trackingManager = Sale\Delivery\Tracking\Manager::getInstance(); $deliveryStatusClassName = $this->registry->getDeliveryStatusClassName(); $deliveryStatuses = $deliveryStatusClassName::getAllStatusesNames(LANGUAGE_ID); $shipmentClassName = $this->registry->getShipmentClassName(); /** @var Main\DB\Result $listShipments */ $listShipments = $shipmentClassName::getList(array( 'select' => array( 'STATUS_ID', 'DELIVERY_NAME', 'SYSTEM', 'DELIVERY_ID', 'ACCOUNT_NUMBER', 'PRICE_DELIVERY', 'DATE_DEDUCTED', 'CURRENCY', 'DEDUCTED', 'TRACKING_NUMBER', 'ORDER_ID' ), 'filter' => array('ORDER_ID' => $orderIdList) )); while ($shipment = $listShipments->fetch()) { if ($shipment['SYSTEM'] == 'Y') continue; $shipment['DELIVERY_NAME'] = htmlspecialcharsbx($shipment['DELIVERY_NAME']); $shipment["FORMATED_DELIVERY_PRICE"] = SaleFormatCurrency(floatval($shipment["PRICE_DELIVERY"]), $shipment["CURRENCY"]); $shipment["DELIVERY_STATUS_NAME"] = $deliveryStatuses[$shipment["STATUS_ID"]]; if ($shipment["DELIVERY_ID"] > 0 && strlen($shipment["TRACKING_NUMBER"])) { $shipment["TRACKING_URL"] = $trackingManager->getTrackingUrl($shipment["DELIVERY_ID"], $shipment["TRACKING_NUMBER"]); } $listOrderShipment[$shipment['ORDER_ID']][] = $shipment; } $paymentClassName = $this->registry->getPaymentClassName(); /** @var Main\DB\Result $listPayments */ $listPayments = $paymentClassName::getList(array( 'select' => array('ID', 'PAY_SYSTEM_NAME', 'PAY_SYSTEM_ID', 'ACCOUNT_NUMBER', 'ORDER_ID', 'PAID', 'SUM', 'CURRENCY', 'DATE_BILL'), 'filter' => array('ORDER_ID' => $orderIdList) )); $paymentIdList = array(); $paymentList = array(); while ($payment = $listPayments->fetch()) { $payment['PAY_SYSTEM_NAME'] = htmlspecialcharsbx($payment['PAY_SYSTEM_NAME']); $payment["FORMATED_SUM"] = SaleFormatCurrency($payment["SUM"], $payment["CURRENCY"]); $payment['IS_CASH'] = $this->dbResult['PAYSYS'][$payment['PAY_SYSTEM_ID']]['IS_CASH']; $payment['NEW_WINDOW'] = $this->dbResult['PAYSYS'][$payment['PAY_SYSTEM_ID']]['NEW_WINDOW']; $payment["PSA_ACTION_FILE"] = htmlspecialcharsbx($this->arParams["PATH_TO_PAYMENT"]).'?ORDER_ID='.urlencode(urlencode($listOrders[$payment["ORDER_ID"]]['ACCOUNT_NUMBER'])).'&PAYMENT_ID='.$payment['ACCOUNT_NUMBER']; $paymentList[$payment['ID']] = $payment; $paymentIdList[] = $payment['ID']; } $checkList = CheckManager::collectInfo( array( "PAYMENT_ID" => $paymentIdList, "ENTITY_REGISTRY_TYPE" => Sale\Registry::REGISTRY_TYPE_ORDER ) ); if (!empty($checkList)) { foreach ($checkList as $check) { $paymentList[$check['PAYMENT_ID']]['CHECK_DATA'][] = $check; } } foreach ($paymentList as $payment) { $listOrderPayment[$payment['ORDER_ID']][] = $payment; } $orderStatusClassName = $this->registry->getOrderStatusClassName(); $allowStatusList = $orderStatusClassName::getAllowPayStatusList(); foreach ($orderIdList as $orderId) { if (!$listOrderShipment[$orderId]) { $listOrderShipment[$orderId] = array(); } if (!$listOrderPayment[$orderId]) { $listOrderPayment[$orderId] = array(); } if (in_array($listOrders[$orderId]['STATUS_ID'], $allowStatusList)) { $listOrders[$orderId]['IS_ALLOW_PAY'] = 'Y'; } else { $listOrders[$orderId]['IS_ALLOW_PAY'] = 'N'; } $this->dbResult['ORDERS'][] = array( "ORDER" => $listOrders[$orderId], "BASKET_ITEMS" => $listOrderBasket[$orderId], "SHIPMENT" => $listOrderShipment[$orderId], "PAYMENT" => $listOrderPayment[$orderId], ); } } /** * Fetches all required data from database. Everything that connected with data fetch is here. * @return void */ protected function obtainData() { $this->obtainDataReferences(); $this->obtainDataOrders(); } /** * Move data read from database to a specially formatted $arResult * @return void */ protected function formatResult() { global $APPLICATION; $arResult = array(); // references $arResult["INFO"]["STATUS"] = $this->dbResult['STATUS']; $arResult["INFO"]["PAY_SYSTEM"] = $this->dbResult['PAYSYS']; $arResult["INFO"]["DELIVERY"] = $this->dbResult['DELIVERY']; $arResult["INFO"]["DELIVERY_HANDLERS"] = $this->dbResult['DELIVERY_HANDLERS']; $arResult["CURRENT_PAGE"] = $APPLICATION->GetCurPage(); $arResult["NAV_STRING"] = $this->dbQueryResult['ORDERS']->GetPageNavString(Localization\Loc::getMessage("SPOL_PAGES"), $this->arParams["NAV_TEMPLATE"]); // bug walkaround $this->arParams["PATH_TO_CANCEL"] .= (strpos($this->arParams["PATH_TO_CANCEL"], "?") === false ? "?" : "&"); if (empty($this->arParams["PATH_TO_CATALOG"])) { $this->arParams["PATH_TO_CATALOG"] = '/catalog/'; } if(self::isNonemptyArray($this->dbResult['ORDERS'])) { foreach ($this->dbResult['ORDERS'] as $k => $orderInfo) { $arOrder =& $this->dbResult['ORDERS'][$k]['ORDER']; $arOBasket =& $this->dbResult['ORDERS'][$k]['BASKET_ITEMS']; $arOrder["FORMATED_PRICE"] = SaleFormatCurrency($arOrder["PRICE"], $arOrder["CURRENCY"]); $this->formatDate($arOrder, $this->orderDateFields2Convert); if ($this->arParams['DISALLOW_CANCEL'] === 'Y') { $arOrder["CAN_CANCEL"] = 'N'; } else { $arOrder["CAN_CANCEL"] = ($arOrder["CANCELED"] != "Y" && $arOrder["STATUS_ID"] != "F" && $arOrder["PAYED"] != "Y") ? "Y" : "N"; } $arOrder["URL_TO_DETAIL"] = CComponentEngine::makePathFromTemplate($this->arParams["PATH_TO_DETAIL"], array("ID" => urlencode(urlencode($arOrder["ACCOUNT_NUMBER"])))); if (strpos($this->arParams["PATH_TO_COPY"], "COPY_ORDER")) { $arOrder["URL_TO_COPY"] = CComponentEngine::makePathFromTemplate($this->arParams["PATH_TO_COPY"], array("ID" => urlencode(urlencode($arOrder["ACCOUNT_NUMBER"])))); } else { $arOrder["URL_TO_COPY"] = CComponentEngine::makePathFromTemplate($arResult["CURRENT_PAGE"]."?ID=#ID#©_ORDER=Y", array("ID" => urlencode(urlencode($arOrder["ACCOUNT_NUMBER"])))); } $arOrder["URL_TO_CANCEL"] = CComponentEngine::makePathFromTemplate($this->arParams["PATH_TO_CANCEL"], array("ID" => urlencode(urlencode($arOrder["ACCOUNT_NUMBER"]))))."CANCEL=Y"; if(self::isNonemptyArray($arOBasket)) { foreach ($arOBasket as $n => $basketInfo) { $arBasket =& $arOBasket[$n]; $arBasket["NAME~"] = $arBasket["NAME"]; $arBasket["NOTES~"] = $arBasket["NOTES"]; $arBasket["NAME"] = htmlspecialcharsEx($arBasket["NAME"]); $arBasket["NOTES"] = htmlspecialcharsEx($arBasket["NOTES"]); $arBasket["QUANTITY"] = doubleval($arBasket["QUANTITY"]); // backward compatibility $arBasket["MEASURE_TEXT"] = $arBasket["MEASURE_NAME"]; $this->formatDate($arBasket, $this->basketDateFields2Convert); } } } $arResult["ORDERS"] = $this->dbResult['ORDERS']; } else { $arResult["ORDERS"] = array(); } $arResult['SORT_TYPE'] = $this->sortBy; $this->arResult = $arResult; } /** * Move all errors to $arResult, if there were any * @return void */ protected function formatResultErrors() { $errors = array(); if (!empty($this->errorsFatal)) $errors['FATAL'] = $this->errorsFatal; if (!empty($this->errorsNonFatal)) $errors['NONFATAL'] = $this->errorsNonFatal; if (!empty($errors)) $this->arResult['ERRORS'] = $errors; // backward compatiblity $error = each($this->errorsFatal); if (!empty($error['value'])) $this->arResult['ERROR_MESSAGE'] = $error['value']; } /** * Function implements all the life cycle of our component * @return void */ public function executeComponent() { try { $this->setFrameMode(false); $this->checkRequiredModules(); $this->checkAuthorized(); $this->setTitle(); $this->getOptions(); $this->setRegistry(); $this->processRequest(); $this->performActions(); $this->obtainData(); $this->formatResult(); } catch (Exception $e) { $this->errorsFatal[$e->getCode()] = $e->getMessage(); } $this->formatResultErrors(); $this->includeComponentTemplate(); } /** * Return current class registry * * @param mixed[] array that date conversion performs in * @return void */ protected function setRegistry() { $this->registry = Sale\Registry::getInstance(Sale\Order::getRegistryType()); } /** * Convert dates if date template set * @param mixed[] $arr data array to be converted * @param string[] $conversion contains sublist of keys of $arr, that will be converted * @return void */ protected function formatDate(&$arr, $conversion) { if (!$this->useIblock) return; if (strlen($this->arParams['ACTIVE_DATE_FORMAT']) && self::isNonemptyArray($conversion)) foreach ($conversion as $fld) { if (!empty($arr[$fld])) $arr[$fld."_FORMATED"] = CIBlockFormatProperties::DateFormat($this->arParams['ACTIVE_DATE_FORMAT'], MakeTimeStamp($arr[$fld])); } } /** * Function checks if it`s argument is a legal array for foreach() construction * @param mixed $arr data to check * @return boolean */ protected static function isNonemptyArray($arr) { return is_array($arr) && !empty($arr); } //////////////////////// // Cache functions //////////////////////// /** * Function checks if cacheing is enabled in component parameters * @return boolean */ final protected function getCacheNeed() { return intval($this->arParams['CACHE_TIME']) > 0 && $this->arParams['CACHE_TYPE'] != 'N' && Config\Option::get("main", "component_cache_on", "Y") == "Y"; } /** * Function perform start of cache process, if needed * @param mixed[]|string $cacheId An optional addition for cache key * @return boolean True, if cache content needs to be generated, false if cache is valid and can be read */ final protected function startCache($cacheId = array()) { if(!$this->getCacheNeed()) return true; $this->currentCache = Data\Cache::createInstance(); return $this->currentCache->startDataCache(intval($this->arParams['CACHE_TIME']), $this->getCacheKey($cacheId)); } /** * Function perform start of cache process, if needed * @throws Main\SystemException * @param mixed[] $data Data to be stored in the cache * @return void */ final protected function endCache($data = null) { if(!$this->getCacheNeed()) return; if($this->currentCache == 'null') throw new Main\SystemException('Cache were not started'); $this->currentCache->endDataCache($data); $this->currentCache = null; } /** * Function discard cache generation * @throws Main\SystemException * @return void */ final protected function abortCache() { if(!$this->getCacheNeed()) return; if($this->currentCache == 'null') throw new Main\SystemException('Cache were not started'); $this->currentCache->abortDataCache(); $this->currentCache = null; } /** * Function return data stored in cache * @throws Main\SystemException * @return void|mixed[] Data from cache */ final protected function getCacheData() { if(!$this->getCacheNeed()) { return false; } if($this->currentCache == 'null') throw new Main\SystemException('Cache were not started'); return $this->currentCache->getVars(); } /** * Function leaves the ability to modify cache key in future. * @param array $cacheId * @return string Cache key to be used in CPHPCache() */ final protected function getCacheKey($cacheId = array()) { if(!is_array($cacheId)) $cacheId = array((string) $cacheId); $cacheId['SITE_ID'] = SITE_ID; $cacheId['LANGUAGE_ID'] = LANGUAGE_ID; // if there are two or more caches with the same id, but with different cache_time, make them separate $cacheId['CACHE_TIME'] = intval($this->arResult['CACHE_TIME']); if(defined("SITE_TEMPLATE_ID")) $cacheId['SITE_TEMPLATE_ID'] = SITE_TEMPLATE_ID; return implode('|', $cacheId); } }