├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── include.php ├── install ├── components │ └── opensource │ │ └── order │ │ ├── .description.php │ │ ├── .parameters.php │ │ ├── ajax.php │ │ ├── class.php │ │ ├── lang │ │ └── ru │ │ │ ├── .description.php │ │ │ ├── .parameters.php │ │ │ └── class.php │ │ └── templates │ │ ├── .default │ │ ├── done.php │ │ ├── form.php │ │ ├── lang │ │ │ └── ru │ │ │ │ └── template.php │ │ ├── result_modifier.php │ │ ├── script.js │ │ ├── selectize │ │ │ ├── images │ │ │ │ └── spinner.gif │ │ │ ├── selectize.default.css │ │ │ ├── selectize.dropdown.css │ │ │ └── selectize.js │ │ ├── style.css │ │ └── template.php │ │ ├── example_person_type │ │ ├── done.php │ │ ├── form.php │ │ ├── lang │ │ │ └── ru │ │ │ │ └── template.php │ │ ├── result_modifier.php │ │ ├── script.js │ │ ├── selectize │ │ │ ├── images │ │ │ │ └── spinner.gif │ │ │ ├── selectize.default.css │ │ │ ├── selectize.dropdown.css │ │ │ └── selectize.js │ │ ├── style.css │ │ └── template.php │ │ └── example_refresh_delivery │ │ ├── done.php │ │ ├── form.php │ │ ├── lang │ │ └── ru │ │ │ └── template.php │ │ ├── result_modifier.php │ │ ├── script.js │ │ ├── selectize │ │ ├── images │ │ │ └── spinner.gif │ │ ├── selectize.default.css │ │ ├── selectize.dropdown.css │ │ └── selectize.js │ │ ├── style.css │ │ └── template.php ├── index.php └── version.php ├── lang └── ru │ └── install │ └── index.php └── lib ├── errorcollection.php ├── locationhelper.php └── orderhelper.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Alexandr Shubin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Opensource Bitrix Order 2 | 3 | Более подробную информацию по функционалу, а так же просто рассуждения на тему читайте по ссылке: 4 | https://verstaem.com/bitrix/opensource-order/ 5 | 6 | Здесь, в README.md краткая выжимка из статьи касательно функционала, но без объяснения причин. 7 | 8 | ## Как установить? 9 | 10 | Установка доступна тремя разными способами: 11 | 12 | 1\. Установка через композер 13 | 14 | Чтобы пакет скачался в нужную папку в файле composer.json укажите путь до папки bitrix. Обратите внимание на блок extra: 15 | ```json 16 | { 17 | "name": "your/project", 18 | "authors": [ 19 | { 20 | "name": "Alexander Shubin", 21 | "email": "alorian@yandex.ru" 22 | } 23 | ], 24 | "require": {}, 25 | "extra": { 26 | "bitrix-dir": "./" 27 | } 28 | } 29 | ``` 30 | Путь до папки bitrix нужно прописывать относительно файла composer.json. Например если файл composer.json лежит в /local/libs, 31 | то нужно прописать "bitrix-dir": "../../bitrix". По дефолту установщик считает, что файл composer.json лежит в document_root. 32 | Если не указать корректный bitrix-dir, то будет создана папка bitrix/modules/opensource.order/ рядом с composer.json. 33 | 34 | После того как прописали правильный bitrix-dir выполните: 35 | ```bash 36 | $ composer require alorian/bxorder 37 | ``` 38 | 39 | После выполнения команды откройте список модулей маркетплейс в админке /bitrix/admin/partner_modules.php?lang=ru, если 40 | bitrix-dir был указан корректно, то вы увидите строку с модулем opensource.order. Нажмите "Установить" в выпадающем меню. 41 | 42 | 2\. Установка из маркетплейс 43 | 44 | Перейдите по ссылке https://marketplace.1c-bitrix.ru/solutions/opensource.order/ и установите решение как обычно. 45 | Если страница не открывается, то возможно решение еще на модерации. 46 | 47 | 3\. Ручная установка 48 | 49 | Скачайте архив https://github.com/alorian/bxorder/archive/master.zip и самостоятельно распакуйте его содержимое 50 | в папку модулей битрикса -- /bitrix/modules, либо /local/modules. 51 | 52 | В папке модулей у вас должна быть папка opensource.order, а не bxorder-master, папку bxorder-master которая лежит 53 | в архиве необходимо переименовать. Таким образом полный путь до файла include.php у вас должен 54 | быть /bitrix/modules/opensource.order/include.php, либо /local/modules/opensource.order/include.php 55 | 56 | После распаковки архива откройте список модулей маркетплейс в админке /bitrix/admin/partner_modules.php?lang=ru, 57 | найдите строку с модулем opensource.order и нажмите "Установить" в выпадающем меню 58 | 59 | --- 60 | 61 | После установки любым из указанных способов разместите компонент opensource:order на нужной странице. 62 | 63 | ## Как использовать? 64 | 65 | Что вам нужно сделать как программисту для интеграции верстки? В самом простом случае вам всего лишь нужно сформировать 66 | форму (html тэг form) в шаблоне компонента, которая при отправке передаст на сервер пять переменных: 67 | 68 | 1\. person_type_id. Переменная которая содержит тип плательщика. 69 | 70 | 2\. properties[]. Массив переменных со свойствами заказа. Например, если у свойства символьный код — FIO, то атрибут 71 | name у инпута ставьте properties[FIO]. Если переменная множественная то ставьте name=properties[FIO][] 72 | 73 | 3\. delivery_id. В самом простом случае это просто input типа radio, у которого атрибут name=delivery_id 74 | 75 | 4\. pay_system_id. Так же как и с доставкой, просто radio инпут, только атрибут name=pay_system_id 76 | 77 | 5\. save. Если переменная save=y, то компонент сохранит заказ. Во всех остальных случаях компонент просто обновит 78 | данные в объекте заказа и отдаст шаблон. 79 | 80 | Да, всё настолько просто. Формируете форму с этими пятью переменными и вы великолепны. Это далеко не всё что можно 81 | сделать с помощью опенсорсного компонента. Но даже в самых сложных шаблонах суть останется прежней. 82 | Оформление заказа это не магия, просто обычная форма в браузере, просто чуть больше полей чем в обратной связи. 83 | 84 | ## Что передается из компонента в шаблон? 85 | 86 | Компонент формирует объект заказа и объект с коллекцией ошибок. Массив $arResult не используется. 87 | 88 | Чтобы получить доступ к объекту заказа и коллекции ошибок в файле result_modifier.php шаблона вставьте в начало следующий 89 | код: 90 | ```php 91 | __component; 96 | $order = $component->order; 97 | $errorCollection = $component->errorCollection; 98 | ``` 99 | 100 | В шаблоне компонента желательно использовать предварительно сформированный в result_modifier массив $arResult (см. демо шаблоны). 101 | Но если вы по каким либо причинам хотите получить прямой доступ к объекту заказа, то можете сделать это так: 102 | ```php 103 | order->getPrice(); 110 | var_dump($component->errorCollection); 111 | ``` 112 | 113 | ## Куда отправлять аякс запросы? 114 | 115 | В компоненте есть три готовых аякс метода, все они лежат в файле [ajax.php](https://github.com/alorian/bxorder/blob/master/install/components/order/ajax.php). 116 | Все они работают с помощью ["нового механизма аякс"](https://verstaem.com/ajax/new-bitrix-ajax/) 117 | 118 | 1. searchLocation. Возвращает найденные местоположения по любой строке вида "москва", "санкт" и т.д. 119 | 2. calculateDeliveries. Возвращает массив со стоимостью доставок 120 | 3. saveOrder. Сохранение массива аяксом. Для работы нужно сериализовать все поля формы и отправить. 121 | 122 | ## Как дорабатывать компонент под проект? 123 | 124 | Во первых, вы всегда можете отправить pull request. Если там будет код, который пригодится многим, то pull request будет 125 | влит в основную ветку. Таким образом вы будете пользоваться оригинальным компонентом, без каких либо доработок. 126 | 127 | Во вторых, вы можете использовать систему событий битрикс. Наиболее полезным я думаю будет событие [OnSaleOrderBeforeSaved](https://dev.1c-bitrix.ru/api_d7/bitrix/sale/events/order_saved.php). 128 | 129 | В третьих, вы можете использовать [возможность наследования компонентов](https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=2028). 130 | В наследованном компоненте пишете любой нужный под проект функционал, и при этом не теряете совместимость с оригинальным компонентом. 131 | Шаблон компонента у вас в любом случае будет свой. 132 | 133 | ## Куда отправлять ошибки и предложения? 134 | 135 | Компонент более менее протестирован. Но возможно вы найдете какие-либо баги, в этом случае создайте [issue](https://github.com/alorian/bxorder/issues) в этом репозитории. 136 | Предложения по доработке тоже можно писать туда. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alorian/bxorder", 3 | "description": "Opensource bitrix order component", 4 | "keywords": [ 5 | "bitrix", 6 | "components", 7 | "module" 8 | ], 9 | "homepage": "https://github.com/Alorian/bxorder", 10 | "type": "bitrix-module", 11 | "license": "MIT", 12 | "support": { 13 | "telegram": "https://t.me/bxmeetup", 14 | "email": "verstaem.com@gmail.com", 15 | "skype": "alorian_22", 16 | "issues": "https://github.com/Alorian/bxorder/issues", 17 | "source": "https://github.com/Alorian/bxorder" 18 | }, 19 | "authors": [ 20 | { 21 | "name": "Alexander Shubin", 22 | "homepage": "https://verstaem.com", 23 | "email": "admin@verstaem.com" 24 | } 25 | ], 26 | "extra": { 27 | "installer-name": "opensource.order" 28 | }, 29 | "require": { 30 | "php": "^7.0", 31 | "composer/installers": "~1" 32 | } 33 | } -------------------------------------------------------------------------------- /include.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alorian/bxorder/427a5037dfd956fdabada1bb672c25867dab1abf/include.php -------------------------------------------------------------------------------- /install/components/opensource/order/.description.php: -------------------------------------------------------------------------------- 1 | Loc::getMessage('OPEN_SOURCE_ORDER_COMPONENT_NAME'), 11 | 'DESCRIPTION' => Loc::getMessage('OPEN_SOURCE_ORDER_COMPONENT_DESCRIPTION'), 12 | 'ICON' => '/images/news_detail.gif', 13 | 'SORT' => 10, 14 | 'CACHE_PATH' => 'Y', 15 | 'PATH' => [ 16 | 'ID' => 'e-store', 17 | ], 18 | ]; -------------------------------------------------------------------------------- /install/components/opensource/order/.parameters.php: -------------------------------------------------------------------------------- 1 | 'ASC']); 14 | while ($arPersonType = $rsPersonTypes->Fetch()) { 15 | $arPersonTypesList[$arPersonType['ID']] = '[' . $arPersonType['ID'] . '] ' . $arPersonType['NAME']; 16 | } 17 | 18 | 19 | $arDeliveriesList = [ 20 | 0 => Loc::getMessage('OPEN_SOURCE_DEFAULT_VALUE_EMPTY') 21 | ]; 22 | $arActiveDeliveries = Bitrix\Sale\Delivery\Services\Manager::getActiveList(); 23 | foreach ($arActiveDeliveries as $arDelivery) { 24 | $arDeliveriesList[$arDelivery['ID']] = '[' . $arDelivery['ID'] . '] ' . $arDelivery['NAME']; 25 | } 26 | 27 | 28 | $arPaySystemsList = [ 29 | 0 => Loc::getMessage('OPEN_SOURCE_DEFAULT_VALUE_EMPTY') 30 | ]; 31 | $rsPaySystems = Bitrix\Sale\PaySystem\Manager::getList(); 32 | while ($arPaySystem = $rsPaySystems->fetch()) { 33 | $arPaySystemsList[$arPaySystem['ID']] = '[' . $arPaySystem['ID'] . '] ' . $arPaySystem['NAME']; 34 | } 35 | 36 | $arComponentParameters = [ 37 | 'GROUPS' => [ 38 | ], 39 | 'PARAMETERS' => [ 40 | 'DEFAULT_PERSON_TYPE_ID' => [ 41 | 'NAME' => Loc::getMessage('OPEN_SOURCE_DEFAULT_PERSON_TYPE_ID'), 42 | 'TYPE' => 'LIST', 43 | 'MULTIPLE' => 'N', 44 | 'DEFAULT' => '/personal/cart/', 45 | 'PARENT' => 'BASE', 46 | 'VALUES' => $arPersonTypesList 47 | ], 48 | 'DEFAULT_DELIVERY_ID' => [ 49 | 'NAME' => Loc::getMessage('OPEN_SOURCE_ORDER_DEFAULT_DELIVERY_ID'), 50 | 'TYPE' => 'LIST', 51 | 'MULTIPLE' => 'N', 52 | 'DEFAULT' => '/personal/cart/', 53 | 'PARENT' => 'BASE', 54 | 'VALUES' => $arDeliveriesList 55 | ], 56 | 'DEFAULT_PAY_SYSTEM_ID' => [ 57 | 'NAME' => Loc::getMessage('OPEN_SOURCE_ORDER_DEFAULT_PAY_SYSTEM_ID'), 58 | 'TYPE' => 'LIST', 59 | 'MULTIPLE' => 'N', 60 | 'DEFAULT' => '/personal/cart/', 61 | 'PARENT' => 'BASE', 62 | 'VALUES' => $arPaySystemsList 63 | ], 64 | 'PATH_TO_BASKET' => [ 65 | 'NAME' => Loc::getMessage('OPEN_SOURCE_ORDER_PATH_TO_BASKET'), 66 | 'TYPE' => 'STRING', 67 | 'MULTIPLE' => 'N', 68 | 'DEFAULT' => '/personal/cart/', 69 | 'PARENT' => 'ADDITIONAL_SETTINGS', 70 | ] 71 | ] 72 | ]; -------------------------------------------------------------------------------- /install/components/opensource/order/ajax.php: -------------------------------------------------------------------------------- 1 | [ 37 | 'prefilters' => [] 38 | ], 39 | 'calculateDeliveries' => [ 40 | 'prefilters' => [] 41 | ], 42 | 'saveOrder' => [ 43 | 'prefilters' => [] 44 | ] 45 | ]; 46 | } 47 | 48 | /** 49 | * @param string $q 50 | * @param int $limit 51 | * @param string $typeCode 52 | * @param array $excludeParts 53 | * @param string $sortOrder 54 | * @return array 55 | * @throws Exception 56 | */ 57 | public function searchLocationAction( 58 | string $q, 59 | int $limit = 5, 60 | string $typeCode = '', 61 | array $excludeParts = [], 62 | string $sortOrder = 'desc' 63 | ): array { 64 | $foundLocations = []; 65 | 66 | if ($q !== '') { 67 | if ($limit > 50 || $limit < 1) { 68 | $limit = 50; 69 | } 70 | 71 | //getting location type 72 | $typeId = null; 73 | if(!empty($typeCode)) { 74 | $arType = TypeTable::getList([ 75 | 'select' => [ 76 | 'ID', 77 | 'CODE' 78 | ], 79 | 'filter' => [ 80 | '=CODE' => $typeCode 81 | ] 82 | ]) 83 | ->fetch(); 84 | 85 | if (!empty($arType)) { 86 | $typeId = $arType['ID']; 87 | } 88 | } 89 | 90 | $result = Finder::find([ 91 | 'select' => [ 92 | 'ID', 93 | 'CODE', 94 | ], 95 | 'filter' => [ 96 | 'PHRASE' => $q, 97 | 'TYPE_ID' => $typeId 98 | ], 99 | 'limit' => $limit 100 | ]); 101 | 102 | while ($arLocation = $result->fetch()) { 103 | $foundLocations[] = LocationHelper::getDisplayByCode($arLocation['CODE'], $excludeParts, $sortOrder); 104 | } 105 | } 106 | 107 | return $foundLocations; 108 | } 109 | 110 | /** 111 | * @param int $person_type_id 112 | * @param array $properties 113 | * @param array $delivery_ids 114 | * @return array 115 | * 116 | * @throws Exception 117 | */ 118 | public function calculateDeliveriesAction( 119 | int $person_type_id, 120 | array $properties, 121 | array $delivery_ids = [] 122 | ): array { 123 | CBitrixComponent::includeComponentClass('opensource:order'); 124 | 125 | $componentClass = new OpenSourceOrderComponent(); 126 | $componentClass->createVirtualOrder($person_type_id); 127 | $componentClass->setOrderProperties($properties); 128 | $shipment = $componentClass->createOrderShipment(); 129 | 130 | $availableDeliveries = Delivery\Services\Manager::getRestrictedObjectsList($shipment); 131 | 132 | //calc only needed if argument given 133 | if (!empty($delivery_ids)) { 134 | $availableDeliveries = array_intersect( 135 | $availableDeliveries, 136 | array_flip($delivery_ids) 137 | ); 138 | } 139 | 140 | $calculatedDeliveries = []; 141 | foreach (OrderHelper::calcDeliveries($shipment, $availableDeliveries) as $deliveryId => $calculationResult) { 142 | $obDelivery = $availableDeliveries[$deliveryId]; 143 | 144 | $arDelivery = [ 145 | 'id' => $obDelivery->getId(), 146 | 'success' => $calculationResult->isSuccess(), 147 | 'name' => $obDelivery->getName(), 148 | 'logo_path' => $obDelivery->getLogotipPath(), 149 | 'period' => $calculationResult->getPeriodDescription(), 150 | 'base_price' => $calculationResult->getPrice(), 151 | 'base_price_display' => SaleFormatCurrency( 152 | $calculationResult->getPrice(), 153 | $componentClass->order->getCurrency() 154 | ), 155 | ]; 156 | 157 | $data = $calculationResult->getData(); 158 | if (!empty($data['DISCOUNT_DATA'])) { 159 | $arDelivery['price'] = $data['DISCOUNT_DATA']['PRICE']; 160 | $arDelivery['price_display'] = SaleFormatCurrency( 161 | $arDelivery['price'], 162 | $componentClass->order->getCurrency() 163 | ); 164 | $arDelivery['discount'] = $data['DISCOUNT_DATA']['DISCOUNT']; 165 | $arDelivery['discount_display'] = SaleFormatCurrency( 166 | $arDelivery['discount'], 167 | $componentClass->order->getCurrency() 168 | ); 169 | } else { 170 | $arDelivery['price'] = $arDelivery['base_price']; 171 | $arDelivery['price_display'] = $arDelivery['base_price_display']; 172 | $arDelivery['discount'] = 0; 173 | } 174 | 175 | $arDelivery['errors'] = []; 176 | if (!$calculationResult->isSuccess()) { 177 | foreach ($calculationResult->getErrorMessages() as $message) { 178 | $arDelivery['errors'][] = $message; 179 | } 180 | } 181 | 182 | $calculatedDeliveries[$arDelivery['id']] = $arDelivery; 183 | } 184 | 185 | return $calculatedDeliveries; 186 | } 187 | 188 | /** 189 | * @param int $person_type_id 190 | * @param array $properties 191 | * @param int $delivery_id 192 | * @param int $pay_system_id 193 | * @return array 194 | * @throws Exception 195 | */ 196 | public function saveOrderAction(int $person_type_id, array $properties, int $delivery_id, int $pay_system_id): array 197 | { 198 | $data = []; 199 | 200 | CBitrixComponent::includeComponentClass('opensource:order'); 201 | 202 | $componentClass = new OpenSourceOrderComponent(); 203 | $componentClass->createVirtualOrder($person_type_id); 204 | $componentClass->setOrderProperties($properties); 205 | $componentClass->createOrderShipment($delivery_id); 206 | $componentClass->createOrderPayment($pay_system_id); 207 | 208 | $validationResult = $componentClass->validateOrder(); 209 | if ($validationResult->isSuccess()) { 210 | $saveResult = $componentClass->order->save(); 211 | if ($saveResult->isSuccess()) { 212 | $data['saved'] = true; 213 | $data['order_id'] = $saveResult->getId(); 214 | } else { 215 | $this->errorCollection->add($saveResult->getErrors()); 216 | } 217 | } else { 218 | $this->errorCollection->add($validationResult->getErrors()); 219 | } 220 | 221 | return $data; 222 | } 223 | 224 | } -------------------------------------------------------------------------------- /install/components/opensource/order/class.php: -------------------------------------------------------------------------------- 1 | errorCollection = new ErrorCollection(); 51 | } 52 | 53 | public function onIncludeComponentLang() 54 | { 55 | Loc::loadLanguageFile(__FILE__); 56 | } 57 | 58 | public function onPrepareComponentParams($arParams = []): array 59 | { 60 | if (isset($arParams['DEFAULT_PERSON_TYPE_ID']) && (int)$arParams['DEFAULT_PERSON_TYPE_ID'] > 0) { 61 | $arParams['DEFAULT_PERSON_TYPE_ID'] = (int)$arParams['DEFAULT_PERSON_TYPE_ID']; 62 | } else { 63 | $arPersonTypes = $this->getPersonTypes(); 64 | $arPersonType = reset($arPersonTypes); 65 | if (is_array($arPersonType)) { 66 | $arParams['DEFAULT_PERSON_TYPE_ID'] = (int)reset($arPersonTypes)['ID']; 67 | } else { 68 | $arParams['DEFAULT_PERSON_TYPE_ID'] = 1; 69 | } 70 | } 71 | 72 | if (isset($this->request['person_type_id']) && (int)$this->request['person_type_id'] > 0) { 73 | $arParams['PERSON_TYPE_ID'] = (int)$this->request['person_type_id']; 74 | } else { 75 | $arParams['PERSON_TYPE_ID'] = $arParams['DEFAULT_PERSON_TYPE_ID']; 76 | } 77 | 78 | if (isset($arParams['SAVE'])) { 79 | $arParams['SAVE'] = $arParams['SAVE'] === 'Y'; 80 | } elseif (isset($this->request['save'])) { 81 | $arParams['SAVE'] = $this->request['save'] === 'y'; 82 | } else { 83 | $arParams['SAVE'] = false; 84 | } 85 | 86 | return $arParams; 87 | } 88 | 89 | /** 90 | * @return array 91 | */ 92 | public function getPersonTypes(): array 93 | { 94 | if (empty($this->personTypes)) { 95 | $personType = new CSalePersonType(); 96 | $rsPersonTypes = $personType->GetList(['SORT' => 'ASC']); 97 | while ($arPersonType = $rsPersonTypes->Fetch()) { 98 | $arPersonType['ID'] = (int)$arPersonType['ID']; 99 | $this->personTypes[$arPersonType['ID']] = $arPersonType; 100 | } 101 | } 102 | 103 | return $this->personTypes; 104 | } 105 | 106 | /** 107 | * @param int $personTypeId 108 | * @return Order 109 | * @throws Exception 110 | */ 111 | public function createVirtualOrder(int $personTypeId) 112 | { 113 | global $USER; 114 | 115 | if (!isset($this->getPersonTypes()[$personTypeId])) { 116 | throw new RuntimeException(Loc::getMessage('OPEN_SOURCE_ORDER_UNKNOWN_PERSON_TYPE')); 117 | } 118 | 119 | $siteId = Context::getCurrent() 120 | ->getSite(); 121 | 122 | $basketItems = Basket::loadItemsForFUser(Fuser::getId(), $siteId) 123 | ->getOrderableItems(); 124 | 125 | if (count($basketItems) === 0) { 126 | throw new LengthException(Loc::getMessage('OPEN_SOURCE_ORDER_EMPTY_BASKET')); 127 | } 128 | 129 | $this->order = Order::create($siteId, $USER->GetID()); 130 | $this->order->setPersonTypeId($personTypeId); 131 | $this->order->setBasket($basketItems); 132 | 133 | return $this->order; 134 | } 135 | 136 | /** 137 | * @param array $propertyValues 138 | * @throws Exception 139 | */ 140 | public function setOrderProperties(array $propertyValues) 141 | { 142 | foreach ($this->order->getPropertyCollection() as $prop) { 143 | /** 144 | * @var PropertyValue $prop 145 | */ 146 | if ($prop->isUtil()) { 147 | continue; 148 | } 149 | 150 | $value = $propertyValues[$prop->getField('CODE')] ?? null; 151 | 152 | if (empty($value)) { 153 | $value = $prop->getProperty()['DEFAULT_VALUE']; 154 | } 155 | 156 | if (!empty($value)) { 157 | $prop->setValue($value); 158 | } 159 | } 160 | } 161 | 162 | /** 163 | * @param int $deliveryId 164 | * @return Shipment 165 | * @throws Exception 166 | */ 167 | public function createOrderShipment(int $deliveryId = 0) 168 | { 169 | /* @var $shipmentCollection ShipmentCollection */ 170 | $shipmentCollection = $this->order->getShipmentCollection(); 171 | 172 | if ($deliveryId > 0) { 173 | $shipment = $shipmentCollection->createItem( 174 | Bitrix\Sale\Delivery\Services\Manager::getObjectById($deliveryId) 175 | ); 176 | } else { 177 | $shipment = $shipmentCollection->createItem(); 178 | } 179 | 180 | /** @var $shipmentItemCollection ShipmentItemCollection */ 181 | $shipmentItemCollection = $shipment->getShipmentItemCollection(); 182 | $shipment->setField('CURRENCY', $this->order->getCurrency()); 183 | 184 | foreach ($this->order->getBasket()->getOrderableItems() as $basketItem) { 185 | /** 186 | * @var $basketItem BasketItem 187 | * @var $shipmentItem ShipmentItem 188 | */ 189 | $shipmentItem = $shipmentItemCollection->createItem($basketItem); 190 | $shipmentItem->setQuantity($basketItem->getQuantity()); 191 | } 192 | 193 | return $shipment; 194 | } 195 | 196 | /** 197 | * @param int $paySystemId 198 | * @return Payment 199 | * @throws Exception 200 | */ 201 | public function createOrderPayment(int $paySystemId) 202 | { 203 | $paymentCollection = $this->order->getPaymentCollection(); 204 | $payment = $paymentCollection->createItem( 205 | Bitrix\Sale\PaySystem\Manager::getObjectById($paySystemId) 206 | ); 207 | $payment->setField('SUM', $this->order->getPrice()); 208 | $payment->setField('CURRENCY', $this->order->getCurrency()); 209 | 210 | return $payment; 211 | } 212 | 213 | /** 214 | * @return Result 215 | * 216 | * @throws Exception 217 | */ 218 | public function validateProperties() 219 | { 220 | $result = new Result(); 221 | 222 | foreach ($this->order->getPropertyCollection() as $prop) { 223 | /** 224 | * @var PropertyValue $prop 225 | */ 226 | if ($prop->isUtil()) { 227 | continue; 228 | } 229 | 230 | $r = $prop->checkRequiredValue($prop->getField('CODE'), $prop->getValue()); 231 | if ($r->isSuccess()) { 232 | $r = $prop->checkValue($prop->getField('CODE'), $prop->getValue()); 233 | if (!$r->isSuccess()) { 234 | $result->addErrors($r->getErrors()); 235 | } 236 | } else { 237 | $result->addErrors($r->getErrors()); 238 | } 239 | } 240 | 241 | return $result; 242 | } 243 | 244 | /** 245 | * @return Result 246 | * @throws Exception 247 | */ 248 | public function validateDelivery() 249 | { 250 | $result = new Result(); 251 | 252 | $shipment = OrderHelper::getFirstNonSystemShipment($this->order); 253 | 254 | if ($shipment !== null) { 255 | if ($shipment->getDelivery() instanceof Delivery\Services\Base) { 256 | $obDelivery = $shipment->getDelivery(); 257 | $availableDeliveries = Delivery\Services\Manager::getRestrictedObjectsList($shipment); 258 | if (!isset($availableDeliveries[$obDelivery->getId()])) { 259 | $result->addError(new Error( 260 | Loc::getMessage( 261 | 'OPEN_SOURCE_ORDER_DELIVERY_UNAVAILABLE', 262 | [ 263 | '#DELIVERY_NAME#' => $obDelivery->getNameWithParent() 264 | ] 265 | ), 266 | 'delivery', 267 | [ 268 | 'type' => 'unavailable' 269 | ] 270 | )); 271 | } 272 | } else { 273 | $result->addError(new Error( 274 | Loc::getMessage('OPEN_SOURCE_ORDER_NO_DELIVERY_SELECTED'), 275 | 'delivery', 276 | [ 277 | 'type' => 'undefined' 278 | ] 279 | )); 280 | } 281 | } else { 282 | $result->addError(new Error( 283 | Loc::getMessage('OPEN_SOURCE_ORDER_SHIPMENT_NOT_FOUND'), 284 | 'delivery', 285 | [ 286 | 'type' => 'undefined' 287 | ] 288 | )); 289 | } 290 | 291 | return $result; 292 | } 293 | 294 | /** 295 | * @return Result 296 | * @throws Exception 297 | */ 298 | public function validatePayment() 299 | { 300 | $result = new Result(); 301 | 302 | if (!$this->order->getPaymentCollection()->isEmpty()) { 303 | $payment = $this->order->getPaymentCollection()->current(); 304 | /** 305 | * @var Payment $payment 306 | */ 307 | $obPaySystem = $payment->getPaySystem(); 308 | if ($obPaySystem instanceof PaySystem\Service) { 309 | $availablePaySystems = PaySystem\Manager::getListWithRestrictions($payment); 310 | if (!isset($availablePaySystems[$payment->getPaymentSystemId()])) { 311 | $result->addError(new Error( 312 | Loc::getMessage( 313 | 'OPEN_SOURCE_ORDER_PAYMENT_UNAVAILABLE', 314 | [ 315 | '#PAYMENT_NAME#' => $payment->getPaymentSystemName() 316 | ] 317 | ), 318 | 'payment', 319 | [ 320 | 'type' => 'unavailable' 321 | ] 322 | )); 323 | } 324 | } else { 325 | $result->addError(new Error( 326 | Loc::getMessage('OPEN_SOURCE_ORDER_NO_PAY_SYSTEM_SELECTED'), 327 | 'payment', 328 | [ 329 | 'type' => 'undefined' 330 | ] 331 | )); 332 | } 333 | } else { 334 | $result->addError(new Error( 335 | Loc::getMessage('OPEN_SOURCE_ORDER_NO_PAY_SYSTEM_SELECTED'), 336 | 'payment', 337 | [ 338 | 'type' => 'undefined' 339 | ] 340 | )); 341 | } 342 | 343 | return $result; 344 | } 345 | 346 | /** 347 | * @return Result 348 | * @throws Exception 349 | */ 350 | public function validateOrder() 351 | { 352 | $result = new Result(); 353 | 354 | $propValidationResult = $this->validateProperties(); 355 | if (!$propValidationResult->isSuccess()) { 356 | $result->addErrors($propValidationResult->getErrors()); 357 | } 358 | 359 | $deliveryValidationResult = $this->validateDelivery(); 360 | if (!$deliveryValidationResult->isSuccess()) { 361 | $result->addErrors($deliveryValidationResult->getErrors()); 362 | } 363 | 364 | $paymentValidationResult = $this->validatePayment(); 365 | if (!$paymentValidationResult->isSuccess()) { 366 | $result->addErrors($paymentValidationResult->getErrors()); 367 | } 368 | 369 | return $result; 370 | } 371 | 372 | public function executeComponent() 373 | { 374 | try { 375 | $this->createVirtualOrder($this->arParams['PERSON_TYPE_ID']); 376 | 377 | $propertiesList = $this->request['properties'] ?? $this->arParams['DEFAULT_PROPERTIES'] ?? []; 378 | if (!empty($propertiesList)) { 379 | $this->setOrderProperties($propertiesList); 380 | } 381 | 382 | $deliveryId = $this->request['delivery_id'] ?? $this->arParams['DEFAULT_DELIVERY_ID'] ?? 0; 383 | $this->createOrderShipment($deliveryId); 384 | 385 | $paySystemId = $this->request['pay_system_id'] ?? $this->arParams['DEFAULT_PAY_SYSTEM_ID'] ?? 0; 386 | if ($paySystemId > 0) { 387 | $this->createOrderPayment($paySystemId); 388 | } 389 | 390 | if ($this->arParams['SAVE']) { 391 | $validationResult = $this->validateOrder(); 392 | 393 | if ($validationResult->isSuccess()) { 394 | $saveResult = $this->order->save(); 395 | if (!$saveResult->isSuccess()) { 396 | $this->errorCollection->add($saveResult->getErrors()); 397 | } 398 | } else { 399 | $this->errorCollection->add($validationResult->getErrors()); 400 | } 401 | } 402 | } catch (Exception $exception) { 403 | $this->errorCollection->setError(new Error($exception->getMessage())); 404 | } 405 | 406 | $this->includeComponentTemplate(); 407 | } 408 | 409 | } -------------------------------------------------------------------------------- /install/components/opensource/order/lang/ru/.description.php: -------------------------------------------------------------------------------- 1 | 22 | 23 | $arResult['ID'] 25 | ]) ?> 26 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/form.php: -------------------------------------------------------------------------------- 1 | 22 |
23 | 24 | 25 | 26 |

:

27 | 28 | $arProp): ?> 29 | 30 | 44 | 100 | 101 | 102 |
31 | 38 | 41 |
getMessage() ?>
42 | 43 |
45 | 49 |
50 | 56 |
57 | $name):?> 62 | 66 | IncludeComponent( 71 | 'bitrix:main.calendar', 72 | '', 73 | [ 74 | 'SHOW_INPUT' => 'Y', 75 | 'FORM_NAME' => 'os-order-form', 76 | 'INPUT_NAME' => $arProp['FORM_NAME'], 77 | 'INPUT_VALUE' => $arProp['VALUE'], 78 | 'SHOW_TIME' => 'Y', 79 | //'HIDE_TIMEBAR' => 'Y', 80 | 'INPUT_ADDITIONAL_ATTR' => 'placeholder="выберите дату"' 81 | ] 82 | ); 83 | break; 84 | 85 | case 'Y/N': 86 | ?> 87 | 90 | 95 | 98 | 99 |
103 | 104 |

:

105 | 108 |
getMessage() ?>
109 | 111 | 119 |
120 | 121 | 122 |

:

123 | 126 |
getMessage() ?>
127 | 129 | 136 |
137 | 138 | 139 |

140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 162 | 163 | 164 | 165 | 166 | 167 | 168 |
151 | 152 | 153 |
154 | 155 | 156 | 157 |
158 | 159 |
160 | 161 |
169 | 170 |

171 |

:

172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 | 187 |

:

188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 |
202 | 203 |

:

204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 |
218 | 219 | 220 |
221 | 222 |
223 |
224 | 225 |
226 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/lang/ru/template.php: -------------------------------------------------------------------------------- 1 | __component; 17 | $order = $component->order; 18 | 19 | if (!$order instanceof Order) { 20 | return; 21 | } 22 | 23 | /** 24 | * ORDER FIELDS 25 | */ 26 | $arResult = $order->getFieldValues(); 27 | 28 | /** 29 | * ORDER PROPERTIES 30 | */ 31 | $arResult['PROPERTIES'] = []; 32 | foreach ($order->getPropertyCollection() as $prop) { 33 | /** 34 | * @var PropertyValue $prop 35 | */ 36 | if ($prop->isUtil()) { 37 | continue; 38 | } 39 | 40 | $arProp['FORM_NAME'] = 'properties[' . $prop->getField('CODE') . ']'; 41 | $arProp['FORM_LABEL'] = 'property_' . $prop->getField('CODE'); 42 | 43 | $arProp['TYPE'] = $prop->getType(); 44 | $arProp['NAME'] = $prop->getName(); 45 | $arProp['VALUE'] = $prop->getValue(); 46 | $arProp['IS_REQUIRED'] = $prop->isRequired(); 47 | $arProp['ERRORS'] = $component->errorCollection->getAllErrorsByCode('PROPERTIES[' . $prop->getField('CODE') . ']'); 48 | 49 | switch ($prop->getType()) { 50 | case 'LOCATION': 51 | if (!empty($arProp['VALUE'])) { 52 | $arProp['LOCATION_DATA'] = LocationHelper::getDisplayByCode($arProp['VALUE']); 53 | } 54 | break; 55 | 56 | case 'ENUM': 57 | $arProp['OPTIONS'] = $prop->getPropertyObject() 58 | ->getOptions(); 59 | break; 60 | } 61 | 62 | $arResult['PROPERTIES'][$prop->getField('CODE')] = $arProp; 63 | } 64 | 65 | 66 | /** 67 | * DELIVERY 68 | */ 69 | $arResult['DELIVERY_ERRORS'] = []; 70 | foreach ($component->errorCollection->getAllErrorsByCode('delivery') as $error) { 71 | $arResult['DELIVERY_ERRORS'][] = $error; 72 | } 73 | 74 | $arResult['DELIVERY_LIST'] = []; 75 | $shipment = OrderHelper::getFirstNonSystemShipment($order); 76 | if ($shipment !== null) { 77 | $availableDeliveries = Delivery\Services\Manager::getRestrictedObjectsList($shipment); 78 | $allDeliveryIDs = $order->getDeliveryIdList(); 79 | $checkedDeliveryId = end($allDeliveryIDs); 80 | 81 | foreach (OrderHelper::calcDeliveries($shipment, $availableDeliveries) as $deliveryID => $calculationResult) { 82 | /** 83 | * @var Delivery\Services\Base $obDelivery 84 | */ 85 | $obDelivery = $availableDeliveries[$deliveryID]; 86 | 87 | $arDelivery = []; 88 | $arDelivery['ID'] = $obDelivery->getId(); 89 | $arDelivery['NAME'] = $obDelivery->getName(); 90 | $arDelivery['CHECKED'] = $checkedDeliveryId === $obDelivery->getId(); 91 | $arDelivery['PRICE'] = $calculationResult->getPrice(); 92 | $arDelivery['PRICE_DISPLAY'] = SaleFormatCurrency( 93 | $calculationResult->getDeliveryPrice(), 94 | $order->getCurrency() 95 | ); 96 | 97 | $arResult['DELIVERY_LIST'][$deliveryID] = $arDelivery; 98 | } 99 | } 100 | 101 | 102 | /** 103 | * PAY SYSTEM 104 | */ 105 | $arResult['PAY_SYSTEM_ERRORS'] = []; 106 | foreach ($component->errorCollection->getAllErrorsByCode('payment') as $error) { 107 | $arResult['PAY_SYSTEM_ERRORS'][] = $error; 108 | } 109 | 110 | $arResult['PAY_SYSTEM_LIST'] = []; 111 | $availablePaySystem = OrderHelper::getAvailablePaySystems($order); 112 | $checkedPaySystemId = 0; 113 | if (!$order->getPaymentCollection()->isEmpty()) { 114 | $payment = $order->getPaymentCollection()->current(); 115 | $checkedPaySystemId = $payment->getPaymentSystemId(); 116 | } 117 | foreach ($availablePaySystem as $paySystem) { 118 | $arPaySystem = []; 119 | 120 | $arPaySystem['ID'] = $paySystem->getField('ID'); 121 | $arPaySystem['NAME'] = $paySystem->getField('NAME'); 122 | $arPaySystem['CHECKED'] = $arPaySystem['ID'] === $checkedPaySystemId; 123 | 124 | $arResult['PAY_SYSTEM_LIST'][$arPaySystem['ID']] = $arPaySystem; 125 | } 126 | 127 | /** 128 | * BASKET 129 | */ 130 | $arResult['BASKET'] = []; 131 | foreach ($order->getBasket() as $basketItem) { 132 | /** 133 | * @var BasketItem $basketItem 134 | */ 135 | $arBasketItem = []; 136 | $arBasketItem['ID'] = $basketItem->getId(); 137 | $arBasketItem['NAME'] = $basketItem->getField('NAME'); 138 | $arBasketItem['CURRENCY'] = $basketItem->getCurrency(); 139 | 140 | $arBasketItem['PROPERTIES'] = []; 141 | foreach ($basketItem->getPropertyCollection() as $basketPropertyItem): 142 | /** 143 | * @var BasketPropertyItem $basketPropertyItem 144 | */ 145 | $propCode = $basketPropertyItem->getField('CODE'); 146 | if ($propCode !== 'CATALOG.XML_ID' && $propCode !== 'PRODUCT.XML_ID') { 147 | $arBasketItem['PROPERTIES'][] = [ 148 | 'NAME' => $basketPropertyItem->getField('NAME'), 149 | 'VALUE' => $basketPropertyItem->getField('VALUE'), 150 | ]; 151 | } 152 | endforeach; 153 | 154 | $arBasketItem['QUANTITY'] = $basketItem->getQuantity(); 155 | $arBasketItem['QUANTITY_DISPLAY'] = $basketItem->getQuantity(); 156 | $arBasketItem['QUANTITY_DISPLAY'] .= ' ' . $basketItem->getField('MEASURE_NAME'); 157 | 158 | $arBasketItem['BASE_PRICE'] = $basketItem->getBasePrice(); 159 | $arBasketItem['BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 160 | $arBasketItem['BASE_PRICE'], 161 | $arBasketItem['CURRENCY'] 162 | ); 163 | 164 | $arBasketItem['PRICE'] = $basketItem->getPrice(); 165 | $arBasketItem['PRICE_DISPLAY'] = SaleFormatCurrency( 166 | $arBasketItem['PRICE'], 167 | $arBasketItem['CURRENCY'] 168 | ); 169 | 170 | $arBasketItem['SUM'] = $basketItem->getPrice() * $basketItem->getQuantity(); 171 | $arBasketItem['SUM_DISPLAY'] = SaleFormatCurrency( 172 | $arBasketItem['SUM'], 173 | $arBasketItem['CURRENCY'] 174 | ); 175 | 176 | $arResult['BASKET'][$arBasketItem['ID']] = $arBasketItem; 177 | } 178 | 179 | /** 180 | * ORDER TOTAL BASKET PRICES 181 | */ 182 | //Стоимость товаров без скидок 183 | $arResult['PRODUCTS_BASE_PRICE'] = $order->getBasket()->getBasePrice(); 184 | $arResult['PRODUCTS_BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 185 | $arResult['PRODUCTS_BASE_PRICE'], 186 | $arResult['CURRENCY'] 187 | ); 188 | 189 | //Стоимость товаров со скидами 190 | $arResult['PRODUCTS_PRICE'] = $order->getBasket()->getPrice(); 191 | $arResult['PRODUCTS_PRICE_DISPLAY'] = SaleFormatCurrency( 192 | $arResult['PRODUCTS_PRICE'], 193 | $arResult['CURRENCY'] 194 | ); 195 | 196 | //Скидка на товары 197 | $arResult['PRODUCTS_DISCOUNT'] = $arResult['PRODUCTS_BASE_PRICE'] - $arResult['PRODUCTS_PRICE']; 198 | $arResult['PRODUCTS_DISCOUNT_DISPLAY'] = SaleFormatCurrency( 199 | $arResult['PRODUCTS_DISCOUNT'], 200 | $arResult['CURRENCY'] 201 | ); 202 | 203 | /** 204 | * ORDER TOTAL DELIVERY PRICES 205 | */ 206 | $arShowPrices = $order->getDiscount() 207 | ->getShowPrices(); 208 | 209 | //Стоимость доставки без скидок 210 | $arResult['DELIVERY_BASE_PRICE'] = $arShowPrices['DELIVERY']['BASE_PRICE'] ?? 0; 211 | $arResult['DELIVERY_BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 212 | $arResult['DELIVERY_BASE_PRICE'], 213 | $arResult['CURRENCY'] 214 | ); 215 | 216 | //Стоимость доставки с учетом скидок 217 | $arResult['DELIVERY_PRICE'] = $order->getDeliveryPrice(); 218 | $arResult['DELIVERY_PRICE_DISPLAY'] = SaleFormatCurrency( 219 | $arResult['DELIVERY_PRICE'], 220 | $arResult['CURRENCY'] 221 | ); 222 | 223 | //Скидка на доставку 224 | $arResult['DELIVERY_DISCOUNT'] = $arShowPrices['DELIVERY']['DISCOUNT'] ?? 0; 225 | $arResult['DELIVERY_DISCOUNT_DISPLAY'] = SaleFormatCurrency( 226 | $arResult['DELIVERY_PRICE'], 227 | $arResult['CURRENCY'] 228 | ); 229 | 230 | /** 231 | * ORDER TOTAL PRICES 232 | */ 233 | //Общая цена без скидок 234 | $arResult['SUM_BASE'] = $arResult['PRODUCTS_BASE_PRICE'] + $arResult['DELIVERY_BASE_PRICE']; 235 | $arResult['SUM_BASE_DISPLAY'] = SaleFormatCurrency( 236 | $arResult['SUM_BASE'], 237 | $arResult['CURRENCY'] 238 | ); 239 | 240 | //Общая скидка 241 | $arResult['DISCOUNT_VALUE'] = $arResult['SUM_BASE'] - $order->getPrice(); 242 | $arResult['DISCOUNT_VALUE_DISPLAY'] = SaleFormatCurrency( 243 | $arResult['DISCOUNT_VALUE'], 244 | $arResult['CURRENCY'] 245 | ); 246 | 247 | //К оплате 248 | $arResult['SUM'] = $order->getPrice(); 249 | $arResult['SUM_DISPLAY'] = SaleFormatCurrency( 250 | $arResult['SUM'], 251 | $arResult['CURRENCY'] 252 | ); -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $('.location-search').selectize({ 3 | valueField: 'code', 4 | labelField: 'label', 5 | searchField: 'label', 6 | create: false, 7 | render: { 8 | option: function (item, escape) { 9 | return '
' + escape(item.label) + '
'; 10 | } 11 | }, 12 | load: function (q, callback) { 13 | if (!q.length) return callback(); 14 | 15 | var query = { 16 | c: 'opensource:order', 17 | action: 'searchLocation', 18 | mode: 'ajax', 19 | q: q 20 | }; 21 | 22 | $.ajax({ 23 | url: '/bitrix/services/main/ajax.php?' + $.param(query, true), 24 | type: 'GET', 25 | error: function () { 26 | callback(); 27 | }, 28 | success: function (res) { 29 | if (res.status === 'success') { 30 | callback(res.data); 31 | } else { 32 | console.log(res.errors); 33 | callback(); 34 | } 35 | } 36 | }); 37 | } 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/selectize/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alorian/bxorder/427a5037dfd956fdabada1bb672c25867dab1abf/install/components/opensource/order/templates/.default/selectize/images/spinner.gif -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/selectize/selectize.default.css: -------------------------------------------------------------------------------- 1 | /** 2 | * selectize.default.css (v0.12.6) - Default Theme 3 | * Copyright (c) 2013–2015 Brian Reavis & contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 6 | * file except in compliance with the License. You may obtain a copy of the License at: 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under 10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | * ANY KIND, either express or implied. See the License for the specific language 12 | * governing permissions and limitations under the License. 13 | * 14 | * @author Brian Reavis 15 | */ 16 | .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { 17 | visibility: visible !important; 18 | background: #f2f2f2 !important; 19 | background: rgba(0, 0, 0, 0.06) !important; 20 | border: 0 none !important; 21 | -webkit-box-shadow: inset 0 0 12px 4px #fff; 22 | box-shadow: inset 0 0 12px 4px #fff; 23 | } 24 | .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { 25 | content: '!'; 26 | visibility: hidden; 27 | } 28 | .selectize-control.plugin-drag_drop .ui-sortable-helper { 29 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 30 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 31 | } 32 | .selectize-dropdown-header { 33 | position: relative; 34 | padding: 5px 8px; 35 | border-bottom: 1px solid #d0d0d0; 36 | background: #f8f8f8; 37 | -webkit-border-radius: 3px 3px 0 0; 38 | -moz-border-radius: 3px 3px 0 0; 39 | border-radius: 3px 3px 0 0; 40 | } 41 | .selectize-dropdown-header-close { 42 | position: absolute; 43 | right: 8px; 44 | top: 50%; 45 | color: #303030; 46 | opacity: 0.4; 47 | margin-top: -12px; 48 | line-height: 20px; 49 | font-size: 20px !important; 50 | } 51 | .selectize-dropdown-header-close:hover { 52 | color: #000000; 53 | } 54 | .selectize-dropdown.plugin-optgroup_columns .optgroup { 55 | border-right: 1px solid #f2f2f2; 56 | border-top: 0 none; 57 | float: left; 58 | -webkit-box-sizing: border-box; 59 | -moz-box-sizing: border-box; 60 | box-sizing: border-box; 61 | } 62 | .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { 63 | border-right: 0 none; 64 | } 65 | .selectize-dropdown.plugin-optgroup_columns .optgroup:before { 66 | display: none; 67 | } 68 | .selectize-dropdown.plugin-optgroup_columns .optgroup-header { 69 | border-top: 0 none; 70 | } 71 | .selectize-control.plugin-remove_button [data-value] { 72 | position: relative; 73 | padding-right: 24px !important; 74 | } 75 | .selectize-control.plugin-remove_button [data-value] .remove { 76 | z-index: 1; 77 | /* fixes ie bug (see #392) */ 78 | position: absolute; 79 | top: 0; 80 | right: 0; 81 | bottom: 0; 82 | width: 17px; 83 | text-align: center; 84 | font-weight: bold; 85 | font-size: 12px; 86 | color: inherit; 87 | text-decoration: none; 88 | vertical-align: middle; 89 | display: inline-block; 90 | padding: 2px 0 0 0; 91 | border-left: 1px solid #0073bb; 92 | -webkit-border-radius: 0 2px 2px 0; 93 | -moz-border-radius: 0 2px 2px 0; 94 | border-radius: 0 2px 2px 0; 95 | -webkit-box-sizing: border-box; 96 | -moz-box-sizing: border-box; 97 | box-sizing: border-box; 98 | } 99 | .selectize-control.plugin-remove_button [data-value] .remove:hover { 100 | background: rgba(0, 0, 0, 0.05); 101 | } 102 | .selectize-control.plugin-remove_button [data-value].active .remove { 103 | border-left-color: #00578d; 104 | } 105 | .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { 106 | background: none; 107 | } 108 | .selectize-control.plugin-remove_button .disabled [data-value] .remove { 109 | border-left-color: #aaaaaa; 110 | } 111 | .selectize-control.plugin-remove_button .remove-single { 112 | position: absolute; 113 | right: 0; 114 | top: 0; 115 | font-size: 23px; 116 | } 117 | .selectize-control { 118 | position: relative; 119 | } 120 | .selectize-dropdown, 121 | .selectize-input, 122 | .selectize-input input { 123 | color: #303030; 124 | font-family: inherit; 125 | font-size: 13px; 126 | line-height: 18px; 127 | -webkit-font-smoothing: inherit; 128 | } 129 | .selectize-input, 130 | .selectize-control.single .selectize-input.input-active { 131 | background: #fff; 132 | cursor: text; 133 | display: inline-block; 134 | } 135 | .selectize-input { 136 | border: 1px solid #d0d0d0; 137 | padding: 8px 8px; 138 | display: inline-block; 139 | width: 100%; 140 | overflow: hidden; 141 | position: relative; 142 | z-index: 1; 143 | -webkit-box-sizing: border-box; 144 | -moz-box-sizing: border-box; 145 | box-sizing: border-box; 146 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); 147 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); 148 | -webkit-border-radius: 3px; 149 | -moz-border-radius: 3px; 150 | border-radius: 3px; 151 | } 152 | .selectize-control.multi .selectize-input.has-items { 153 | padding: 5px 8px 2px; 154 | } 155 | .selectize-input.full { 156 | background-color: #fff; 157 | } 158 | .selectize-input.disabled, 159 | .selectize-input.disabled * { 160 | cursor: default !important; 161 | } 162 | .selectize-input.focus { 163 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); 164 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); 165 | } 166 | .selectize-input.dropdown-active { 167 | -webkit-border-radius: 3px 3px 0 0; 168 | -moz-border-radius: 3px 3px 0 0; 169 | border-radius: 3px 3px 0 0; 170 | } 171 | .selectize-input > * { 172 | vertical-align: baseline; 173 | display: -moz-inline-stack; 174 | display: inline-block; 175 | zoom: 1; 176 | *display: inline; 177 | } 178 | .selectize-control.multi .selectize-input > div { 179 | cursor: pointer; 180 | margin: 0 3px 3px 0; 181 | padding: 2px 6px; 182 | background: #1da7ee; 183 | color: #fff; 184 | border: 1px solid #0073bb; 185 | } 186 | .selectize-control.multi .selectize-input > div.active { 187 | background: #92c836; 188 | color: #fff; 189 | border: 1px solid #00578d; 190 | } 191 | .selectize-control.multi .selectize-input.disabled > div, 192 | .selectize-control.multi .selectize-input.disabled > div.active { 193 | color: #ffffff; 194 | background: #d2d2d2; 195 | border: 1px solid #aaaaaa; 196 | } 197 | .selectize-input > input { 198 | display: inline-block !important; 199 | padding: 0 !important; 200 | min-height: 0 !important; 201 | max-height: none !important; 202 | max-width: 100% !important; 203 | margin: 0 1px !important; 204 | text-indent: 0 !important; 205 | border: 0 none !important; 206 | background: none !important; 207 | line-height: inherit !important; 208 | -webkit-user-select: auto !important; 209 | -webkit-box-shadow: none !important; 210 | box-shadow: none !important; 211 | } 212 | .selectize-input > input::-ms-clear { 213 | display: none; 214 | } 215 | .selectize-input > input:focus { 216 | outline: none !important; 217 | } 218 | .selectize-input::after { 219 | content: ' '; 220 | display: block; 221 | clear: left; 222 | } 223 | .selectize-input.dropdown-active::before { 224 | content: ' '; 225 | display: block; 226 | position: absolute; 227 | background: #f0f0f0; 228 | height: 1px; 229 | bottom: 0; 230 | left: 0; 231 | right: 0; 232 | } 233 | .selectize-dropdown { 234 | position: absolute; 235 | z-index: 10; 236 | border: 1px solid #d0d0d0; 237 | background: #fff; 238 | margin: -1px 0 0 0; 239 | border-top: 0 none; 240 | -webkit-box-sizing: border-box; 241 | -moz-box-sizing: border-box; 242 | box-sizing: border-box; 243 | -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 244 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 245 | -webkit-border-radius: 0 0 3px 3px; 246 | -moz-border-radius: 0 0 3px 3px; 247 | border-radius: 0 0 3px 3px; 248 | } 249 | .selectize-dropdown [data-selectable] { 250 | cursor: pointer; 251 | overflow: hidden; 252 | } 253 | .selectize-dropdown [data-selectable] .highlight { 254 | background: rgba(125, 168, 208, 0.2); 255 | -webkit-border-radius: 1px; 256 | -moz-border-radius: 1px; 257 | border-radius: 1px; 258 | } 259 | .selectize-dropdown .option, 260 | .selectize-dropdown .optgroup-header { 261 | padding: 5px 8px; 262 | } 263 | .selectize-dropdown .option, 264 | .selectize-dropdown [data-disabled], 265 | .selectize-dropdown [data-disabled] [data-selectable].option { 266 | cursor: inherit; 267 | opacity: 0.5; 268 | } 269 | .selectize-dropdown [data-selectable].option { 270 | opacity: 1; 271 | } 272 | .selectize-dropdown .optgroup:first-child .optgroup-header { 273 | border-top: 0 none; 274 | } 275 | .selectize-dropdown .optgroup-header { 276 | color: #303030; 277 | background: #fff; 278 | cursor: default; 279 | } 280 | .selectize-dropdown .active { 281 | background-color: #f5fafd; 282 | color: #495c68; 283 | } 284 | .selectize-dropdown .active.create { 285 | color: #495c68; 286 | } 287 | .selectize-dropdown .create { 288 | color: rgba(48, 48, 48, 0.5); 289 | } 290 | .selectize-dropdown-content { 291 | overflow-y: auto; 292 | overflow-x: hidden; 293 | max-height: 200px; 294 | -webkit-overflow-scrolling: touch; 295 | } 296 | .selectize-control.single .selectize-input, 297 | .selectize-control.single .selectize-input input { 298 | cursor: pointer; 299 | } 300 | .selectize-control.single .selectize-input.input-active, 301 | .selectize-control.single .selectize-input.input-active input { 302 | cursor: text; 303 | } 304 | .selectize-control.single .selectize-input:after { 305 | content: ' '; 306 | display: block; 307 | position: absolute; 308 | top: 50%; 309 | right: 15px; 310 | margin-top: -3px; 311 | width: 0; 312 | height: 0; 313 | border-style: solid; 314 | border-width: 5px 5px 0 5px; 315 | border-color: #808080 transparent transparent transparent; 316 | } 317 | .selectize-control.single .selectize-input.dropdown-active:after { 318 | margin-top: -4px; 319 | border-width: 0 5px 5px 5px; 320 | border-color: transparent transparent #808080 transparent; 321 | } 322 | .selectize-control.rtl.single .selectize-input:after { 323 | left: 15px; 324 | right: auto; 325 | } 326 | .selectize-control.rtl .selectize-input > input { 327 | margin: 0 4px 0 -2px !important; 328 | } 329 | .selectize-control .selectize-input.disabled { 330 | opacity: 0.5; 331 | background-color: #fafafa; 332 | } 333 | .selectize-control.multi .selectize-input.has-items { 334 | padding-left: 5px; 335 | padding-right: 5px; 336 | } 337 | .selectize-control.multi .selectize-input.disabled [data-value] { 338 | color: #999; 339 | text-shadow: none; 340 | background: none; 341 | -webkit-box-shadow: none; 342 | box-shadow: none; 343 | } 344 | .selectize-control.multi .selectize-input.disabled [data-value], 345 | .selectize-control.multi .selectize-input.disabled [data-value] .remove { 346 | border-color: #e6e6e6; 347 | } 348 | .selectize-control.multi .selectize-input.disabled [data-value] .remove { 349 | background: none; 350 | } 351 | .selectize-control.multi .selectize-input [data-value] { 352 | text-shadow: 0 1px 0 rgba(0, 51, 83, 0.3); 353 | -webkit-border-radius: 3px; 354 | -moz-border-radius: 3px; 355 | border-radius: 3px; 356 | background-color: #1b9dec; 357 | background-image: -moz-linear-gradient(top, #1da7ee, #178ee9); 358 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#1da7ee), to(#178ee9)); 359 | background-image: -webkit-linear-gradient(top, #1da7ee, #178ee9); 360 | background-image: -o-linear-gradient(top, #1da7ee, #178ee9); 361 | background-image: linear-gradient(to bottom, #1da7ee, #178ee9); 362 | background-repeat: repeat-x; 363 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1da7ee', endColorstr='#ff178ee9', GradientType=0); 364 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03); 365 | box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03); 366 | } 367 | .selectize-control.multi .selectize-input [data-value].active { 368 | background-color: #0085d4; 369 | background-image: -moz-linear-gradient(top, #008fd8, #0075cf); 370 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#008fd8), to(#0075cf)); 371 | background-image: -webkit-linear-gradient(top, #008fd8, #0075cf); 372 | background-image: -o-linear-gradient(top, #008fd8, #0075cf); 373 | background-image: linear-gradient(to bottom, #008fd8, #0075cf); 374 | background-repeat: repeat-x; 375 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff008fd8', endColorstr='#ff0075cf', GradientType=0); 376 | } 377 | .selectize-control.single .selectize-input { 378 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8); 379 | box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8); 380 | background-color: #f9f9f9; 381 | background-image: -moz-linear-gradient(top, #fefefe, #f2f2f2); 382 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fefefe), to(#f2f2f2)); 383 | background-image: -webkit-linear-gradient(top, #fefefe, #f2f2f2); 384 | background-image: -o-linear-gradient(top, #fefefe, #f2f2f2); 385 | background-image: linear-gradient(to bottom, #fefefe, #f2f2f2); 386 | background-repeat: repeat-x; 387 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffefefe', endColorstr='#fff2f2f2', GradientType=0); 388 | } 389 | .selectize-control.single .selectize-input, 390 | .selectize-dropdown.single { 391 | border-color: #b8b8b8; 392 | } 393 | .selectize-dropdown .optgroup-header { 394 | padding-top: 7px; 395 | font-weight: bold; 396 | font-size: 0.85em; 397 | } 398 | .selectize-dropdown .optgroup { 399 | border-top: 1px solid #f0f0f0; 400 | } 401 | .selectize-dropdown .optgroup:first-child { 402 | border-top: 0 none; 403 | } 404 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/selectize/selectize.dropdown.css: -------------------------------------------------------------------------------- 1 | .selectize-control.location-search .selectize-dropdown > div { 2 | border-bottom: 1px solid rgba(0, 0, 0, 0.05); 3 | } 4 | 5 | .selectize-control.location-search .selectize-dropdown .name { 6 | font-weight: bold; 7 | margin-right: 5px; 8 | } 9 | 10 | .selectize-control.location-search .selectize-dropdown .title { 11 | padding: 10px; 12 | } 13 | 14 | .selectize-control.location-search::before { 15 | -moz-transition: opacity 0.2s; 16 | -webkit-transition: opacity 0.2s; 17 | transition: opacity 0.2s; 18 | content: ' '; 19 | z-index: 2; 20 | position: absolute; 21 | display: block; 22 | top: 12px; 23 | right: 34px; 24 | width: 16px; 25 | height: 16px; 26 | background: url(images/spinner.gif); 27 | background-size: 16px 16px; 28 | opacity: 0; 29 | } 30 | 31 | .selectize-control.location-search.loading::before { 32 | opacity: 0.4; 33 | } -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/style.css: -------------------------------------------------------------------------------- 1 | .os-order { 2 | } 3 | 4 | .os-order .error { 5 | color: #a40000; 6 | } 7 | 8 | .os-order .basket-properties { 9 | color: #919191; 10 | } 11 | 12 | .os-order table { 13 | border-collapse: collapse; 14 | } 15 | 16 | .os-order table th { 17 | background: #DFDFDF; 18 | padding: 5px; 19 | border: 1px solid #c9c9c9; 20 | } 21 | 22 | .os-order table td { 23 | padding: 5px; 24 | border: 1px solid #DFDFDF; 25 | } 26 | 27 | .os-order .location { 28 | min-width: 400px; 29 | } 30 | 31 | .enum-option { 32 | display:block; 33 | } -------------------------------------------------------------------------------- /install/components/opensource/order/templates/.default/template.php: -------------------------------------------------------------------------------- 1 | addExternalJs($templateFolder . '/selectize/selectize.js'); 22 | $this->addExternalCss($templateFolder . '/selectize/selectize.default.css'); 23 | $this->addExternalCss($templateFolder . '/selectize/selectize.dropdown.css'); 24 | ?> 25 |
26 | errorCollection) > 0): ?> 27 |
28 | errorCollection as $error): 29 | /** 30 | * @var Error $error 31 | */ 32 | ?> 33 |
getMessage() ?>
34 | 35 |
36 | 37 | 38 | 0) { 39 | include 'done.php'; 40 | } elseif ($component->order instanceof Order && count($component->order->getBasket()) > 0) { 41 | include 'form.php'; 42 | } ?> 43 |
44 | 45 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/done.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | Заказ № успешно создан 23 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/form.php: -------------------------------------------------------------------------------- 1 | 21 |
22 | 23 |

24 |
25 | 26 | 31 |
32 | 33 |
34 | 35 |

:

36 | $propertiesList): ?> 37 | 38 | 39 | 40 | 48 | 105 | 106 | 107 |
41 | 42 | 45 |
getMessage() ?>
46 | 47 |
49 | 53 |
54 | 61 |
62 | $name):?> 67 | 71 | IncludeComponent( 76 | 'bitrix:main.calendar', 77 | '', 78 | [ 79 | 'SHOW_INPUT' => 'Y', 80 | 'FORM_NAME' => 'os-order-form', 81 | 'INPUT_NAME' => $arProp['FORM_NAME'], 82 | 'INPUT_VALUE' => $arProp['VALUE'], 83 | 'SHOW_TIME' => 'Y', 84 | //'HIDE_TIMEBAR' => 'Y', 85 | 'INPUT_ADDITIONAL_ATTR' => 'placeholder="выберите дату"' 86 | ] 87 | ); 88 | break; 89 | 90 | case 'Y/N': 91 | ?> 92 | 95 | 100 | 103 | 104 |
108 | 109 | 110 |

:

111 | 114 |
getMessage() ?>
115 | 117 | 125 |
126 | 127 | 128 |

:

129 | 132 |
getMessage() ?>
133 | 135 | 142 |
143 | 144 | 145 |

146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 168 | 169 | 170 | 171 | 172 | 173 | 174 |
157 | 158 | 159 |
160 | 161 | 162 | 163 |
164 | 165 |
166 | 167 |
175 | 176 |

177 |

:

178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 |
192 | 193 |

:

194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 |
208 | 209 |

:

210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 | 225 | 226 |
227 | 228 |
229 |
230 | 231 |
232 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/lang/ru/template.php: -------------------------------------------------------------------------------- 1 | __component; 17 | $order = $component->order; 18 | 19 | if (!$order instanceof Order) { 20 | return; 21 | } 22 | 23 | /** 24 | * ORDER FIELDS 25 | */ 26 | $arResult = $order->getFieldValues(); 27 | 28 | $arResult['PERSON_TYPES'] = $component->getPersonTypes(); 29 | foreach ($arResult['PERSON_TYPES'] as $key => &$arPersonType) { 30 | if ($arParams['PERSON_TYPE_ID'] === $arPersonType['ID']) { 31 | $arPersonType['CHECKED'] = true; 32 | } else { 33 | $arPersonType['CHECKED'] = false; 34 | } 35 | } 36 | unset($arPersonType); 37 | 38 | 39 | /** 40 | * ORDER PROPERTIES 41 | */ 42 | $arResult['PROPERTIES'] = []; 43 | foreach ($component->getPersonTypes() as $arPersonType) { 44 | $arResult['PROPERTIES'][$arPersonType['ID']] = []; 45 | 46 | if ($arParams['PERSON_TYPE_ID'] === $arPersonType['ID']) { 47 | $propertyCollection = $order->getPropertyCollection(); 48 | } else { 49 | $order->setPersonTypeId($arPersonType['ID']); 50 | $propertyCollection = $order->loadPropertyCollection(); 51 | $order->setPersonTypeId($arParams['PERSON_TYPE_ID']); 52 | } 53 | 54 | foreach ($propertyCollection as $prop) { 55 | /** 56 | * @var PropertyValue $prop 57 | */ 58 | if ($prop->isUtil()) { 59 | continue; 60 | } 61 | 62 | $arProp['FORM_NAME'] = 'properties[' . $prop->getField('CODE') . ']'; 63 | $arProp['FORM_LABEL'] = 'property_' . $prop->getField('CODE'); 64 | 65 | $arProp['TYPE'] = $prop->getType(); 66 | $arProp['NAME'] = $prop->getName(); 67 | $arProp['VALUE'] = $prop->getValue(); 68 | $arProp['ERRORS'] = $component->errorCollection->getAllErrorsByCode('PROPERTIES[' . $prop->getField('CODE') . ']'); 69 | 70 | switch ($prop->getType()) { 71 | case 'LOCATION': 72 | if (!empty($arProp['VALUE'])) { 73 | $arProp['LOCATION_DATA'] = LocationHelper::getDisplayByCode($arProp['VALUE']); 74 | } 75 | break; 76 | 77 | case 'ENUM': 78 | $arProp['OPTIONS'] = $prop->getPropertyObject() 79 | ->getOptions(); 80 | break; 81 | } 82 | 83 | $arResult['PROPERTIES'][$arPersonType['ID']][$prop->getField('CODE')] = $arProp; 84 | } 85 | } 86 | 87 | 88 | /** 89 | * DELIVERY 90 | */ 91 | $arResult['DELIVERY_ERRORS'] = []; 92 | foreach ($component->errorCollection->getAllErrorsByCode('delivery') as $error) { 93 | $arResult['DELIVERY_ERRORS'][] = $error; 94 | } 95 | 96 | $arResult['DELIVERY_LIST'] = []; 97 | $shipment = OrderHelper::getFirstNonSystemShipment($order); 98 | if ($shipment !== null) { 99 | $availableDeliveries = Delivery\Services\Manager::getRestrictedObjectsList($shipment); 100 | $allDeliveryIDs = $order->getDeliveryIdList(); 101 | $checkedDeliveryId = end($allDeliveryIDs); 102 | 103 | foreach (OrderHelper::calcDeliveries($shipment, $availableDeliveries) as $deliveryID => $calculationResult) { 104 | /** 105 | * @var Delivery\Services\Base $obDelivery 106 | */ 107 | $obDelivery = $availableDeliveries[$deliveryID]; 108 | 109 | $arDelivery = []; 110 | $arDelivery['ID'] = $obDelivery->getId(); 111 | $arDelivery['NAME'] = $obDelivery->getName(); 112 | $arDelivery['CHECKED'] = $checkedDeliveryId === $obDelivery->getId(); 113 | $arDelivery['PRICE'] = $calculationResult->getPrice(); 114 | $arDelivery['PRICE_DISPLAY'] = SaleFormatCurrency( 115 | $calculationResult->getDeliveryPrice(), 116 | $order->getCurrency() 117 | ); 118 | 119 | $arResult['DELIVERY_LIST'][$deliveryID] = $arDelivery; 120 | } 121 | } 122 | 123 | 124 | /** 125 | * PAY SYSTEM 126 | */ 127 | $arResult['PAY_SYSTEM_ERRORS'] = []; 128 | foreach ($component->errorCollection->getAllErrorsByCode('payment') as $error) { 129 | $arResult['PAY_SYSTEM_ERRORS'][] = $error; 130 | } 131 | 132 | $arResult['PAY_SYSTEM_LIST'] = []; 133 | $availablePaySystem = OrderHelper::getAvailablePaySystems($order); 134 | $checkedPaySystemId = 0; 135 | if (!$order->getPaymentCollection()->isEmpty()) { 136 | $payment = $order->getPaymentCollection()->current(); 137 | $checkedPaySystemId = $payment->getPaymentSystemId(); 138 | } 139 | foreach ($availablePaySystem as $paySystem) { 140 | $arPaySystem = []; 141 | 142 | $arPaySystem['ID'] = $paySystem->getField('ID'); 143 | $arPaySystem['NAME'] = $paySystem->getField('NAME'); 144 | $arPaySystem['CHECKED'] = $arPaySystem['ID'] === $checkedPaySystemId; 145 | 146 | $arResult['PAY_SYSTEM_LIST'][$arPaySystem['ID']] = $arPaySystem; 147 | } 148 | 149 | /** 150 | * BASKET 151 | */ 152 | $arResult['BASKET'] = []; 153 | foreach ($order->getBasket() as $basketItem) { 154 | /** 155 | * @var BasketItem $basketItem 156 | */ 157 | $arBasketItem = []; 158 | $arBasketItem['ID'] = $basketItem->getId(); 159 | $arBasketItem['NAME'] = $basketItem->getField('NAME'); 160 | $arBasketItem['CURRENCY'] = $basketItem->getCurrency(); 161 | 162 | $arBasketItem['PROPERTIES'] = []; 163 | foreach ($basketItem->getPropertyCollection() as $basketPropertyItem): 164 | /** 165 | * @var BasketPropertyItem $basketPropertyItem 166 | */ 167 | $propCode = $basketPropertyItem->getField('CODE'); 168 | if ($propCode !== 'CATALOG.XML_ID' && $propCode !== 'PRODUCT.XML_ID') { 169 | $arBasketItem['PROPERTIES'][] = [ 170 | 'NAME' => $basketPropertyItem->getField('NAME'), 171 | 'VALUE' => $basketPropertyItem->getField('VALUE'), 172 | ]; 173 | } 174 | endforeach; 175 | 176 | $arBasketItem['QUANTITY'] = $basketItem->getQuantity(); 177 | $arBasketItem['QUANTITY_DISPLAY'] = $basketItem->getQuantity(); 178 | $arBasketItem['QUANTITY_DISPLAY'] .= ' ' . $basketItem->getField('MEASURE_NAME'); 179 | 180 | $arBasketItem['BASE_PRICE'] = $basketItem->getBasePrice(); 181 | $arBasketItem['BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 182 | $arBasketItem['BASE_PRICE'], 183 | $arBasketItem['CURRENCY'] 184 | ); 185 | 186 | $arBasketItem['PRICE'] = $basketItem->getPrice(); 187 | $arBasketItem['PRICE_DISPLAY'] = SaleFormatCurrency( 188 | $arBasketItem['PRICE'], 189 | $arBasketItem['CURRENCY'] 190 | ); 191 | 192 | $arBasketItem['SUM'] = $basketItem->getPrice() * $basketItem->getQuantity(); 193 | $arBasketItem['SUM_DISPLAY'] = SaleFormatCurrency( 194 | $arBasketItem['SUM'], 195 | $arBasketItem['CURRENCY'] 196 | ); 197 | 198 | $arResult['BASKET'][$arBasketItem['ID']] = $arBasketItem; 199 | } 200 | 201 | /** 202 | * ORDER TOTAL BASKET PRICES 203 | */ 204 | //Стоимость товаров без скидок 205 | $arResult['PRODUCTS_BASE_PRICE'] = $order->getBasket()->getBasePrice(); 206 | $arResult['PRODUCTS_BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 207 | $arResult['PRODUCTS_BASE_PRICE'], 208 | $arResult['CURRENCY'] 209 | ); 210 | 211 | //Стоимость товаров со скидами 212 | $arResult['PRODUCTS_PRICE'] = $order->getBasket()->getPrice(); 213 | $arResult['PRODUCTS_PRICE_DISPLAY'] = SaleFormatCurrency( 214 | $arResult['PRODUCTS_PRICE'], 215 | $arResult['CURRENCY'] 216 | ); 217 | 218 | //Скидка на товары 219 | $arResult['PRODUCTS_DISCOUNT'] = $arResult['PRODUCTS_BASE_PRICE'] - $arResult['PRODUCTS_PRICE']; 220 | $arResult['PRODUCTS_DISCOUNT_DISPLAY'] = SaleFormatCurrency( 221 | $arResult['PRODUCTS_DISCOUNT'], 222 | $arResult['CURRENCY'] 223 | ); 224 | 225 | /** 226 | * ORDER TOTAL DELIVERY PRICES 227 | */ 228 | $arShowPrices = $order->getDiscount() 229 | ->getShowPrices(); 230 | 231 | //Стоимость доставки без скидок 232 | $arResult['DELIVERY_BASE_PRICE'] = $arShowPrices['DELIVERY']['BASE_PRICE'] ?? 0; 233 | $arResult['DELIVERY_BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 234 | $arResult['DELIVERY_BASE_PRICE'], 235 | $arResult['CURRENCY'] 236 | ); 237 | 238 | //Стоимость доставки с учетом скидок 239 | $arResult['DELIVERY_PRICE'] = $order->getDeliveryPrice(); 240 | $arResult['DELIVERY_PRICE_DISPLAY'] = SaleFormatCurrency( 241 | $arResult['DELIVERY_PRICE'], 242 | $arResult['CURRENCY'] 243 | ); 244 | 245 | //Скидка на доставку 246 | $arResult['DELIVERY_DISCOUNT'] = $arShowPrices['DELIVERY']['DISCOUNT'] ?? 0; 247 | $arResult['DELIVERY_DISCOUNT_DISPLAY'] = SaleFormatCurrency( 248 | $arResult['DELIVERY_PRICE'], 249 | $arResult['CURRENCY'] 250 | ); 251 | 252 | /** 253 | * ORDER TOTAL PRICES 254 | */ 255 | //Общая цена без скидок 256 | $arResult['SUM_BASE'] = $arResult['PRODUCTS_BASE_PRICE'] + $arResult['DELIVERY_BASE_PRICE']; 257 | $arResult['SUM_BASE_DISPLAY'] = SaleFormatCurrency( 258 | $arResult['SUM_BASE'], 259 | $arResult['CURRENCY'] 260 | ); 261 | 262 | //Общая скидка 263 | $arResult['DISCOUNT_VALUE'] = $arResult['SUM_BASE'] - $order->getPrice(); 264 | $arResult['DISCOUNT_VALUE_DISPLAY'] = SaleFormatCurrency( 265 | $arResult['DISCOUNT_VALUE'], 266 | $arResult['CURRENCY'] 267 | ); 268 | 269 | //К оплате 270 | $arResult['SUM'] = $order->getPrice(); 271 | $arResult['SUM_DISPLAY'] = SaleFormatCurrency( 272 | $arResult['SUM'], 273 | $arResult['CURRENCY'] 274 | ); -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $('.location-search').selectize({ 3 | valueField: 'code', 4 | labelField: 'label', 5 | searchField: 'label', 6 | create: false, 7 | render: { 8 | option: function (item, escape) { 9 | return '
' + escape(item.label) + '
'; 10 | } 11 | }, 12 | load: function (q, callback) { 13 | if (!q.length) return callback(); 14 | 15 | var query = { 16 | c: 'opensource:order', 17 | action: 'searchLocation', 18 | mode: 'ajax', 19 | q: q 20 | }; 21 | 22 | $.ajax({ 23 | url: '/bitrix/services/main/ajax.php?' + $.param(query, true), 24 | type: 'GET', 25 | error: function () { 26 | callback(); 27 | }, 28 | success: function (res) { 29 | if (res.status === 'success') { 30 | callback(res.data); 31 | } else { 32 | console.log(res.errors); 33 | callback(); 34 | } 35 | } 36 | }); 37 | } 38 | }); 39 | 40 | /** 41 | * Disabling all non active properties 42 | */ 43 | $('.properties-table').each(function (index, element) { 44 | var propTable = $(element); 45 | if (!propTable.hasClass('active')) { 46 | propTable.find(':input').prop('disabled', true); 47 | } 48 | }); 49 | 50 | /** 51 | * Show property table and enable it properties on person type change 52 | */ 53 | $('.person-type-selector input').change(function () { 54 | var currentPropTable = $('.properties-table.active'); 55 | currentPropTable.find(':input').prop('disabled', true); 56 | currentPropTable.removeClass('active'); 57 | 58 | var personTypeId = $(this).val(); 59 | var newPropTable = $('.properties-table.properties-' + personTypeId); 60 | newPropTable.find(':input').prop('disabled', false); 61 | newPropTable.addClass('active'); 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/selectize/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alorian/bxorder/427a5037dfd956fdabada1bb672c25867dab1abf/install/components/opensource/order/templates/example_person_type/selectize/images/spinner.gif -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/selectize/selectize.default.css: -------------------------------------------------------------------------------- 1 | /** 2 | * selectize.default.css (v0.12.6) - Default Theme 3 | * Copyright (c) 2013–2015 Brian Reavis & contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 6 | * file except in compliance with the License. You may obtain a copy of the License at: 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under 10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | * ANY KIND, either express or implied. See the License for the specific language 12 | * governing permissions and limitations under the License. 13 | * 14 | * @author Brian Reavis 15 | */ 16 | .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { 17 | visibility: visible !important; 18 | background: #f2f2f2 !important; 19 | background: rgba(0, 0, 0, 0.06) !important; 20 | border: 0 none !important; 21 | -webkit-box-shadow: inset 0 0 12px 4px #fff; 22 | box-shadow: inset 0 0 12px 4px #fff; 23 | } 24 | .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { 25 | content: '!'; 26 | visibility: hidden; 27 | } 28 | .selectize-control.plugin-drag_drop .ui-sortable-helper { 29 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 30 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 31 | } 32 | .selectize-dropdown-header { 33 | position: relative; 34 | padding: 5px 8px; 35 | border-bottom: 1px solid #d0d0d0; 36 | background: #f8f8f8; 37 | -webkit-border-radius: 3px 3px 0 0; 38 | -moz-border-radius: 3px 3px 0 0; 39 | border-radius: 3px 3px 0 0; 40 | } 41 | .selectize-dropdown-header-close { 42 | position: absolute; 43 | right: 8px; 44 | top: 50%; 45 | color: #303030; 46 | opacity: 0.4; 47 | margin-top: -12px; 48 | line-height: 20px; 49 | font-size: 20px !important; 50 | } 51 | .selectize-dropdown-header-close:hover { 52 | color: #000000; 53 | } 54 | .selectize-dropdown.plugin-optgroup_columns .optgroup { 55 | border-right: 1px solid #f2f2f2; 56 | border-top: 0 none; 57 | float: left; 58 | -webkit-box-sizing: border-box; 59 | -moz-box-sizing: border-box; 60 | box-sizing: border-box; 61 | } 62 | .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { 63 | border-right: 0 none; 64 | } 65 | .selectize-dropdown.plugin-optgroup_columns .optgroup:before { 66 | display: none; 67 | } 68 | .selectize-dropdown.plugin-optgroup_columns .optgroup-header { 69 | border-top: 0 none; 70 | } 71 | .selectize-control.plugin-remove_button [data-value] { 72 | position: relative; 73 | padding-right: 24px !important; 74 | } 75 | .selectize-control.plugin-remove_button [data-value] .remove { 76 | z-index: 1; 77 | /* fixes ie bug (see #392) */ 78 | position: absolute; 79 | top: 0; 80 | right: 0; 81 | bottom: 0; 82 | width: 17px; 83 | text-align: center; 84 | font-weight: bold; 85 | font-size: 12px; 86 | color: inherit; 87 | text-decoration: none; 88 | vertical-align: middle; 89 | display: inline-block; 90 | padding: 2px 0 0 0; 91 | border-left: 1px solid #0073bb; 92 | -webkit-border-radius: 0 2px 2px 0; 93 | -moz-border-radius: 0 2px 2px 0; 94 | border-radius: 0 2px 2px 0; 95 | -webkit-box-sizing: border-box; 96 | -moz-box-sizing: border-box; 97 | box-sizing: border-box; 98 | } 99 | .selectize-control.plugin-remove_button [data-value] .remove:hover { 100 | background: rgba(0, 0, 0, 0.05); 101 | } 102 | .selectize-control.plugin-remove_button [data-value].active .remove { 103 | border-left-color: #00578d; 104 | } 105 | .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { 106 | background: none; 107 | } 108 | .selectize-control.plugin-remove_button .disabled [data-value] .remove { 109 | border-left-color: #aaaaaa; 110 | } 111 | .selectize-control.plugin-remove_button .remove-single { 112 | position: absolute; 113 | right: 0; 114 | top: 0; 115 | font-size: 23px; 116 | } 117 | .selectize-control { 118 | position: relative; 119 | } 120 | .selectize-dropdown, 121 | .selectize-input, 122 | .selectize-input input { 123 | color: #303030; 124 | font-family: inherit; 125 | font-size: 13px; 126 | line-height: 18px; 127 | -webkit-font-smoothing: inherit; 128 | } 129 | .selectize-input, 130 | .selectize-control.single .selectize-input.input-active { 131 | background: #fff; 132 | cursor: text; 133 | display: inline-block; 134 | } 135 | .selectize-input { 136 | border: 1px solid #d0d0d0; 137 | padding: 8px 8px; 138 | display: inline-block; 139 | width: 100%; 140 | overflow: hidden; 141 | position: relative; 142 | z-index: 1; 143 | -webkit-box-sizing: border-box; 144 | -moz-box-sizing: border-box; 145 | box-sizing: border-box; 146 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); 147 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); 148 | -webkit-border-radius: 3px; 149 | -moz-border-radius: 3px; 150 | border-radius: 3px; 151 | } 152 | .selectize-control.multi .selectize-input.has-items { 153 | padding: 5px 8px 2px; 154 | } 155 | .selectize-input.full { 156 | background-color: #fff; 157 | } 158 | .selectize-input.disabled, 159 | .selectize-input.disabled * { 160 | cursor: default !important; 161 | } 162 | .selectize-input.focus { 163 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); 164 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); 165 | } 166 | .selectize-input.dropdown-active { 167 | -webkit-border-radius: 3px 3px 0 0; 168 | -moz-border-radius: 3px 3px 0 0; 169 | border-radius: 3px 3px 0 0; 170 | } 171 | .selectize-input > * { 172 | vertical-align: baseline; 173 | display: -moz-inline-stack; 174 | display: inline-block; 175 | zoom: 1; 176 | *display: inline; 177 | } 178 | .selectize-control.multi .selectize-input > div { 179 | cursor: pointer; 180 | margin: 0 3px 3px 0; 181 | padding: 2px 6px; 182 | background: #1da7ee; 183 | color: #fff; 184 | border: 1px solid #0073bb; 185 | } 186 | .selectize-control.multi .selectize-input > div.active { 187 | background: #92c836; 188 | color: #fff; 189 | border: 1px solid #00578d; 190 | } 191 | .selectize-control.multi .selectize-input.disabled > div, 192 | .selectize-control.multi .selectize-input.disabled > div.active { 193 | color: #ffffff; 194 | background: #d2d2d2; 195 | border: 1px solid #aaaaaa; 196 | } 197 | .selectize-input > input { 198 | display: inline-block !important; 199 | padding: 0 !important; 200 | min-height: 0 !important; 201 | max-height: none !important; 202 | max-width: 100% !important; 203 | margin: 0 1px !important; 204 | text-indent: 0 !important; 205 | border: 0 none !important; 206 | background: none !important; 207 | line-height: inherit !important; 208 | -webkit-user-select: auto !important; 209 | -webkit-box-shadow: none !important; 210 | box-shadow: none !important; 211 | } 212 | .selectize-input > input::-ms-clear { 213 | display: none; 214 | } 215 | .selectize-input > input:focus { 216 | outline: none !important; 217 | } 218 | .selectize-input::after { 219 | content: ' '; 220 | display: block; 221 | clear: left; 222 | } 223 | .selectize-input.dropdown-active::before { 224 | content: ' '; 225 | display: block; 226 | position: absolute; 227 | background: #f0f0f0; 228 | height: 1px; 229 | bottom: 0; 230 | left: 0; 231 | right: 0; 232 | } 233 | .selectize-dropdown { 234 | position: absolute; 235 | z-index: 10; 236 | border: 1px solid #d0d0d0; 237 | background: #fff; 238 | margin: -1px 0 0 0; 239 | border-top: 0 none; 240 | -webkit-box-sizing: border-box; 241 | -moz-box-sizing: border-box; 242 | box-sizing: border-box; 243 | -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 244 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 245 | -webkit-border-radius: 0 0 3px 3px; 246 | -moz-border-radius: 0 0 3px 3px; 247 | border-radius: 0 0 3px 3px; 248 | } 249 | .selectize-dropdown [data-selectable] { 250 | cursor: pointer; 251 | overflow: hidden; 252 | } 253 | .selectize-dropdown [data-selectable] .highlight { 254 | background: rgba(125, 168, 208, 0.2); 255 | -webkit-border-radius: 1px; 256 | -moz-border-radius: 1px; 257 | border-radius: 1px; 258 | } 259 | .selectize-dropdown .option, 260 | .selectize-dropdown .optgroup-header { 261 | padding: 5px 8px; 262 | } 263 | .selectize-dropdown .option, 264 | .selectize-dropdown [data-disabled], 265 | .selectize-dropdown [data-disabled] [data-selectable].option { 266 | cursor: inherit; 267 | opacity: 0.5; 268 | } 269 | .selectize-dropdown [data-selectable].option { 270 | opacity: 1; 271 | } 272 | .selectize-dropdown .optgroup:first-child .optgroup-header { 273 | border-top: 0 none; 274 | } 275 | .selectize-dropdown .optgroup-header { 276 | color: #303030; 277 | background: #fff; 278 | cursor: default; 279 | } 280 | .selectize-dropdown .active { 281 | background-color: #f5fafd; 282 | color: #495c68; 283 | } 284 | .selectize-dropdown .active.create { 285 | color: #495c68; 286 | } 287 | .selectize-dropdown .create { 288 | color: rgba(48, 48, 48, 0.5); 289 | } 290 | .selectize-dropdown-content { 291 | overflow-y: auto; 292 | overflow-x: hidden; 293 | max-height: 200px; 294 | -webkit-overflow-scrolling: touch; 295 | } 296 | .selectize-control.single .selectize-input, 297 | .selectize-control.single .selectize-input input { 298 | cursor: pointer; 299 | } 300 | .selectize-control.single .selectize-input.input-active, 301 | .selectize-control.single .selectize-input.input-active input { 302 | cursor: text; 303 | } 304 | .selectize-control.single .selectize-input:after { 305 | content: ' '; 306 | display: block; 307 | position: absolute; 308 | top: 50%; 309 | right: 15px; 310 | margin-top: -3px; 311 | width: 0; 312 | height: 0; 313 | border-style: solid; 314 | border-width: 5px 5px 0 5px; 315 | border-color: #808080 transparent transparent transparent; 316 | } 317 | .selectize-control.single .selectize-input.dropdown-active:after { 318 | margin-top: -4px; 319 | border-width: 0 5px 5px 5px; 320 | border-color: transparent transparent #808080 transparent; 321 | } 322 | .selectize-control.rtl.single .selectize-input:after { 323 | left: 15px; 324 | right: auto; 325 | } 326 | .selectize-control.rtl .selectize-input > input { 327 | margin: 0 4px 0 -2px !important; 328 | } 329 | .selectize-control .selectize-input.disabled { 330 | opacity: 0.5; 331 | background-color: #fafafa; 332 | } 333 | .selectize-control.multi .selectize-input.has-items { 334 | padding-left: 5px; 335 | padding-right: 5px; 336 | } 337 | .selectize-control.multi .selectize-input.disabled [data-value] { 338 | color: #999; 339 | text-shadow: none; 340 | background: none; 341 | -webkit-box-shadow: none; 342 | box-shadow: none; 343 | } 344 | .selectize-control.multi .selectize-input.disabled [data-value], 345 | .selectize-control.multi .selectize-input.disabled [data-value] .remove { 346 | border-color: #e6e6e6; 347 | } 348 | .selectize-control.multi .selectize-input.disabled [data-value] .remove { 349 | background: none; 350 | } 351 | .selectize-control.multi .selectize-input [data-value] { 352 | text-shadow: 0 1px 0 rgba(0, 51, 83, 0.3); 353 | -webkit-border-radius: 3px; 354 | -moz-border-radius: 3px; 355 | border-radius: 3px; 356 | background-color: #1b9dec; 357 | background-image: -moz-linear-gradient(top, #1da7ee, #178ee9); 358 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#1da7ee), to(#178ee9)); 359 | background-image: -webkit-linear-gradient(top, #1da7ee, #178ee9); 360 | background-image: -o-linear-gradient(top, #1da7ee, #178ee9); 361 | background-image: linear-gradient(to bottom, #1da7ee, #178ee9); 362 | background-repeat: repeat-x; 363 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1da7ee', endColorstr='#ff178ee9', GradientType=0); 364 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03); 365 | box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03); 366 | } 367 | .selectize-control.multi .selectize-input [data-value].active { 368 | background-color: #0085d4; 369 | background-image: -moz-linear-gradient(top, #008fd8, #0075cf); 370 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#008fd8), to(#0075cf)); 371 | background-image: -webkit-linear-gradient(top, #008fd8, #0075cf); 372 | background-image: -o-linear-gradient(top, #008fd8, #0075cf); 373 | background-image: linear-gradient(to bottom, #008fd8, #0075cf); 374 | background-repeat: repeat-x; 375 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff008fd8', endColorstr='#ff0075cf', GradientType=0); 376 | } 377 | .selectize-control.single .selectize-input { 378 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8); 379 | box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8); 380 | background-color: #f9f9f9; 381 | background-image: -moz-linear-gradient(top, #fefefe, #f2f2f2); 382 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fefefe), to(#f2f2f2)); 383 | background-image: -webkit-linear-gradient(top, #fefefe, #f2f2f2); 384 | background-image: -o-linear-gradient(top, #fefefe, #f2f2f2); 385 | background-image: linear-gradient(to bottom, #fefefe, #f2f2f2); 386 | background-repeat: repeat-x; 387 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffefefe', endColorstr='#fff2f2f2', GradientType=0); 388 | } 389 | .selectize-control.single .selectize-input, 390 | .selectize-dropdown.single { 391 | border-color: #b8b8b8; 392 | } 393 | .selectize-dropdown .optgroup-header { 394 | padding-top: 7px; 395 | font-weight: bold; 396 | font-size: 0.85em; 397 | } 398 | .selectize-dropdown .optgroup { 399 | border-top: 1px solid #f0f0f0; 400 | } 401 | .selectize-dropdown .optgroup:first-child { 402 | border-top: 0 none; 403 | } 404 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/selectize/selectize.dropdown.css: -------------------------------------------------------------------------------- 1 | .selectize-control.location-search .selectize-dropdown > div { 2 | border-bottom: 1px solid rgba(0, 0, 0, 0.05); 3 | } 4 | 5 | .selectize-control.location-search .selectize-dropdown .name { 6 | font-weight: bold; 7 | margin-right: 5px; 8 | } 9 | 10 | .selectize-control.location-search .selectize-dropdown .title { 11 | padding: 10px; 12 | } 13 | 14 | .selectize-control.location-search::before { 15 | -moz-transition: opacity 0.2s; 16 | -webkit-transition: opacity 0.2s; 17 | transition: opacity 0.2s; 18 | content: ' '; 19 | z-index: 2; 20 | position: absolute; 21 | display: block; 22 | top: 12px; 23 | right: 34px; 24 | width: 16px; 25 | height: 16px; 26 | background: url(images/spinner.gif); 27 | background-size: 16px 16px; 28 | opacity: 0; 29 | } 30 | 31 | .selectize-control.location-search.loading::before { 32 | opacity: 0.4; 33 | } -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/style.css: -------------------------------------------------------------------------------- 1 | .os-order { 2 | } 3 | 4 | .os-order .error { 5 | color: #a40000; 6 | } 7 | 8 | .os-order .basket-properties { 9 | color: #919191; 10 | } 11 | 12 | .os-order table { 13 | border-collapse: collapse; 14 | } 15 | 16 | .os-order table th { 17 | background: #DFDFDF; 18 | padding: 5px; 19 | border: 1px solid #c9c9c9; 20 | } 21 | 22 | .os-order table td { 23 | padding: 5px; 24 | border: 1px solid #DFDFDF; 25 | } 26 | 27 | .os-order .location { 28 | min-width: 400px; 29 | } 30 | 31 | .enum-option { 32 | display:block; 33 | } 34 | 35 | .properties-table { 36 | display: none; 37 | } 38 | 39 | .properties-table.active { 40 | display: table; 41 | } -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_person_type/template.php: -------------------------------------------------------------------------------- 1 | addExternalJs($templateFolder . '/selectize/selectize.js'); 22 | $this->addExternalCss($templateFolder . '/selectize/selectize.default.css'); 23 | $this->addExternalCss($templateFolder . '/selectize/selectize.dropdown.css'); 24 | ?> 25 |
26 | errorCollection) > 0): ?> 27 |
28 | errorCollection as $error): 29 | /** 30 | * @var Error $error 31 | */ 32 | ?> 33 |
getMessage() ?>
34 | 35 |
36 | 37 | 38 | 0) { 39 | include 'done.php'; 40 | } elseif ($component->order instanceof Order && count($component->order->getBasket()) > 0) { 41 | include 'form.php'; 42 | } ?> 43 |
44 | 45 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/done.php: -------------------------------------------------------------------------------- 1 | 22 | 23 | $arResult['ID'] 25 | ]) ?> 26 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/form.php: -------------------------------------------------------------------------------- 1 | 21 |
22 | 23 | 24 | 25 |

:

26 | 27 | $arProp): ?> 28 | 29 | 37 | 94 | 95 | 96 |
30 | 31 | 34 |
getMessage() ?>
35 | 36 |
38 | 42 |
43 | 50 |
51 | $name):?> 56 | 60 | IncludeComponent( 65 | 'bitrix:main.calendar', 66 | '', 67 | [ 68 | 'SHOW_INPUT' => 'Y', 69 | 'FORM_NAME' => 'os-order-form', 70 | 'INPUT_NAME' => $arProp['FORM_NAME'], 71 | 'INPUT_VALUE' => $arProp['VALUE'], 72 | 'SHOW_TIME' => 'Y', 73 | //'HIDE_TIMEBAR' => 'Y', 74 | 'INPUT_ADDITIONAL_ATTR' => 'placeholder="выберите дату"' 75 | ] 76 | ); 77 | break; 78 | 79 | case 'Y/N': 80 | ?> 81 | 84 | 89 | 92 | 93 |
97 | 98 |

:

99 | 102 |
getMessage() ?>
103 | 104 |
105 | 106 | 115 |
116 | 117 |
118 | 119 |

:

120 | 123 |
getMessage() ?>
124 | 126 | 133 |
134 | 135 | 136 |

137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 159 | 160 | 161 | 162 | 163 | 164 | 165 |
148 | 149 | 150 |
151 | 152 | 153 | 154 |
155 | 156 |
157 | 158 |
166 | 167 |

168 |

:

169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
183 | 184 |

:

185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 |
199 | 200 |

:

201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 |
215 | 216 | 217 |
218 | 219 |
220 |
221 | 222 |
223 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/lang/ru/template.php: -------------------------------------------------------------------------------- 1 | __component; 17 | $order = $component->order; 18 | 19 | if (!$order instanceof Order) { 20 | return; 21 | } 22 | 23 | /** 24 | * ORDER FIELDS 25 | */ 26 | $arResult = $order->getFieldValues(); 27 | 28 | /** 29 | * ORDER PROPERTIES 30 | */ 31 | $arResult['PROPERTIES'] = []; 32 | foreach ($order->getPropertyCollection() as $prop) { 33 | /** 34 | * @var PropertyValue $prop 35 | */ 36 | if ($prop->isUtil()) { 37 | continue; 38 | } 39 | 40 | $arProp['FORM_NAME'] = 'properties[' . $prop->getField('CODE') . ']'; 41 | $arProp['FORM_LABEL'] = 'property_' . $prop->getField('CODE'); 42 | 43 | $arProp['TYPE'] = $prop->getType(); 44 | $arProp['NAME'] = $prop->getName(); 45 | $arProp['VALUE'] = $prop->getValue(); 46 | $arProp['ERRORS'] = $component->errorCollection->getAllErrorsByCode('PROPERTIES[' . $prop->getField('CODE') . ']'); 47 | 48 | switch ($prop->getType()) { 49 | case 'LOCATION': 50 | if (!empty($arProp['VALUE'])) { 51 | $arProp['LOCATION_DATA'] = LocationHelper::getDisplayByCode($arProp['VALUE']); 52 | } 53 | break; 54 | 55 | case 'ENUM': 56 | $arProp['OPTIONS'] = $prop->getPropertyObject() 57 | ->getOptions(); 58 | break; 59 | } 60 | 61 | $arResult['PROPERTIES'][$prop->getField('CODE')] = $arProp; 62 | } 63 | 64 | 65 | /** 66 | * DELIVERY 67 | */ 68 | $arResult['DELIVERY_ERRORS'] = []; 69 | foreach ($component->errorCollection->getAllErrorsByCode('delivery') as $error) { 70 | $arResult['DELIVERY_ERRORS'][] = $error; 71 | } 72 | 73 | $arResult['DELIVERY_LIST'] = []; 74 | $shipment = OrderHelper::getFirstNonSystemShipment($order); 75 | if ($shipment !== null) { 76 | $availableDeliveries = Delivery\Services\Manager::getRestrictedObjectsList($shipment); 77 | $allDeliveryIDs = $order->getDeliveryIdList(); 78 | $checkedDeliveryId = end($allDeliveryIDs); 79 | 80 | foreach (OrderHelper::calcDeliveries($shipment, $availableDeliveries) as $deliveryID => $calculationResult) { 81 | /** 82 | * @var Delivery\Services\Base $obDelivery 83 | */ 84 | $obDelivery = $availableDeliveries[$deliveryID]; 85 | 86 | $arDelivery = []; 87 | $arDelivery['ID'] = $obDelivery->getId(); 88 | $arDelivery['NAME'] = $obDelivery->getName(); 89 | $arDelivery['CHECKED'] = $checkedDeliveryId === $obDelivery->getId(); 90 | $arDelivery['PRICE'] = $calculationResult->getPrice(); 91 | $arDelivery['PRICE_DISPLAY'] = SaleFormatCurrency( 92 | $calculationResult->getDeliveryPrice(), 93 | $order->getCurrency() 94 | ); 95 | 96 | $arResult['DELIVERY_LIST'][$deliveryID] = $arDelivery; 97 | } 98 | } 99 | 100 | 101 | /** 102 | * PAY SYSTEM 103 | */ 104 | $arResult['PAY_SYSTEM_ERRORS'] = []; 105 | foreach ($component->errorCollection->getAllErrorsByCode('payment') as $error) { 106 | $arResult['PAY_SYSTEM_ERRORS'][] = $error; 107 | } 108 | 109 | $arResult['PAY_SYSTEM_LIST'] = []; 110 | $availablePaySystem = OrderHelper::getAvailablePaySystems($order); 111 | $checkedPaySystemId = 0; 112 | if (!$order->getPaymentCollection()->isEmpty()) { 113 | $payment = $order->getPaymentCollection()->current(); 114 | $checkedPaySystemId = $payment->getPaymentSystemId(); 115 | } 116 | foreach ($availablePaySystem as $paySystem) { 117 | $arPaySystem = []; 118 | 119 | $arPaySystem['ID'] = $paySystem->getField('ID'); 120 | $arPaySystem['NAME'] = $paySystem->getField('NAME'); 121 | $arPaySystem['CHECKED'] = $arPaySystem['ID'] === $checkedPaySystemId; 122 | 123 | $arResult['PAY_SYSTEM_LIST'][$arPaySystem['ID']] = $arPaySystem; 124 | } 125 | 126 | /** 127 | * BASKET 128 | */ 129 | $arResult['BASKET'] = []; 130 | foreach ($order->getBasket() as $basketItem) { 131 | /** 132 | * @var BasketItem $basketItem 133 | */ 134 | $arBasketItem = []; 135 | $arBasketItem['ID'] = $basketItem->getId(); 136 | $arBasketItem['NAME'] = $basketItem->getField('NAME'); 137 | $arBasketItem['CURRENCY'] = $basketItem->getCurrency(); 138 | 139 | $arBasketItem['PROPERTIES'] = []; 140 | foreach ($basketItem->getPropertyCollection() as $basketPropertyItem): 141 | /** 142 | * @var BasketPropertyItem $basketPropertyItem 143 | */ 144 | $propCode = $basketPropertyItem->getField('CODE'); 145 | if ($propCode !== 'CATALOG.XML_ID' && $propCode !== 'PRODUCT.XML_ID') { 146 | $arBasketItem['PROPERTIES'][] = [ 147 | 'NAME' => $basketPropertyItem->getField('NAME'), 148 | 'VALUE' => $basketPropertyItem->getField('VALUE'), 149 | ]; 150 | } 151 | endforeach; 152 | 153 | $arBasketItem['QUANTITY'] = $basketItem->getQuantity(); 154 | $arBasketItem['QUANTITY_DISPLAY'] = $basketItem->getQuantity(); 155 | $arBasketItem['QUANTITY_DISPLAY'] .= ' ' . $basketItem->getField('MEASURE_NAME'); 156 | 157 | $arBasketItem['BASE_PRICE'] = $basketItem->getBasePrice(); 158 | $arBasketItem['BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 159 | $arBasketItem['BASE_PRICE'], 160 | $arBasketItem['CURRENCY'] 161 | ); 162 | 163 | $arBasketItem['PRICE'] = $basketItem->getPrice(); 164 | $arBasketItem['PRICE_DISPLAY'] = SaleFormatCurrency( 165 | $arBasketItem['PRICE'], 166 | $arBasketItem['CURRENCY'] 167 | ); 168 | 169 | $arBasketItem['SUM'] = $basketItem->getPrice() * $basketItem->getQuantity(); 170 | $arBasketItem['SUM_DISPLAY'] = SaleFormatCurrency( 171 | $arBasketItem['SUM'], 172 | $arBasketItem['CURRENCY'] 173 | ); 174 | 175 | $arResult['BASKET'][$arBasketItem['ID']] = $arBasketItem; 176 | } 177 | 178 | /** 179 | * ORDER TOTAL BASKET PRICES 180 | */ 181 | //Стоимость товаров без скидок 182 | $arResult['PRODUCTS_BASE_PRICE'] = $order->getBasket()->getBasePrice(); 183 | $arResult['PRODUCTS_BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 184 | $arResult['PRODUCTS_BASE_PRICE'], 185 | $arResult['CURRENCY'] 186 | ); 187 | 188 | //Стоимость товаров со скидами 189 | $arResult['PRODUCTS_PRICE'] = $order->getBasket()->getPrice(); 190 | $arResult['PRODUCTS_PRICE_DISPLAY'] = SaleFormatCurrency( 191 | $arResult['PRODUCTS_PRICE'], 192 | $arResult['CURRENCY'] 193 | ); 194 | 195 | //Скидка на товары 196 | $arResult['PRODUCTS_DISCOUNT'] = $arResult['PRODUCTS_BASE_PRICE'] - $arResult['PRODUCTS_PRICE']; 197 | $arResult['PRODUCTS_DISCOUNT_DISPLAY'] = SaleFormatCurrency( 198 | $arResult['PRODUCTS_DISCOUNT'], 199 | $arResult['CURRENCY'] 200 | ); 201 | 202 | /** 203 | * ORDER TOTAL DELIVERY PRICES 204 | */ 205 | $arShowPrices = $order->getDiscount() 206 | ->getShowPrices(); 207 | 208 | //Стоимость доставки без скидок 209 | $arResult['DELIVERY_BASE_PRICE'] = $arShowPrices['DELIVERY']['BASE_PRICE'] ?? 0; 210 | $arResult['DELIVERY_BASE_PRICE_DISPLAY'] = SaleFormatCurrency( 211 | $arResult['DELIVERY_BASE_PRICE'], 212 | $arResult['CURRENCY'] 213 | ); 214 | 215 | //Стоимость доставки с учетом скидок 216 | $arResult['DELIVERY_PRICE'] = $order->getDeliveryPrice(); 217 | $arResult['DELIVERY_PRICE_DISPLAY'] = SaleFormatCurrency( 218 | $arResult['DELIVERY_PRICE'], 219 | $arResult['CURRENCY'] 220 | ); 221 | 222 | //Скидка на доставку 223 | $arResult['DELIVERY_DISCOUNT'] = $arShowPrices['DELIVERY']['DISCOUNT'] ?? 0; 224 | $arResult['DELIVERY_DISCOUNT_DISPLAY'] = SaleFormatCurrency( 225 | $arResult['DELIVERY_PRICE'], 226 | $arResult['CURRENCY'] 227 | ); 228 | 229 | /** 230 | * ORDER TOTAL PRICES 231 | */ 232 | //Общая цена без скидок 233 | $arResult['SUM_BASE'] = $arResult['PRODUCTS_BASE_PRICE'] + $arResult['DELIVERY_BASE_PRICE']; 234 | $arResult['SUM_BASE_DISPLAY'] = SaleFormatCurrency( 235 | $arResult['SUM_BASE'], 236 | $arResult['CURRENCY'] 237 | ); 238 | 239 | //Общая скидка 240 | $arResult['DISCOUNT_VALUE'] = $arResult['SUM_BASE'] - $order->getPrice(); 241 | $arResult['DISCOUNT_VALUE_DISPLAY'] = SaleFormatCurrency( 242 | $arResult['DISCOUNT_VALUE'], 243 | $arResult['CURRENCY'] 244 | ); 245 | 246 | //К оплате 247 | $arResult['SUM'] = $order->getPrice(); 248 | $arResult['SUM_DISPLAY'] = SaleFormatCurrency( 249 | $arResult['SUM'], 250 | $arResult['CURRENCY'] 251 | ); -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | var $locationSearch = $('.location-search'); 3 | 4 | $locationSearch.selectize({ 5 | valueField: 'code', 6 | labelField: 'label', 7 | searchField: 'label', 8 | create: false, 9 | render: { 10 | option: function (item, escape) { 11 | return '
' + escape(item.label) + '
'; 12 | } 13 | }, 14 | load: function (q, callback) { 15 | if (!q.length) return callback(); 16 | 17 | var query = { 18 | c: 'opensource:order', 19 | action: 'searchLocation', 20 | mode: 'ajax', 21 | q: q 22 | }; 23 | 24 | $.ajax({ 25 | url: '/bitrix/services/main/ajax.php?' + $.param(query, true), 26 | type: 'GET', 27 | error: function () { 28 | callback(); 29 | }, 30 | success: function (res) { 31 | if (res.status === 'success') { 32 | callback(res.data); 33 | } else { 34 | console.log(res.errors); 35 | callback(); 36 | } 37 | } 38 | }); 39 | } 40 | }); 41 | 42 | /** 43 | * Recalculate all deliveries on location prop change 44 | */ 45 | var $deliveryBlock = $('#os-order-delivery-block'); 46 | 47 | function renderDelivery(deliveryData) { 48 | var html = ''; 49 | html += ''; 54 | html += '
'; 55 | 56 | $deliveryBlock.append(html); 57 | } 58 | 59 | $locationSearch.change(function (event) { 60 | var locationCode = $(event.target).val(); 61 | 62 | if (locationCode.length > 0) { 63 | var formData = $('#os-order-form').serialize(); 64 | 65 | var query = { 66 | c: 'opensource:order', 67 | action: 'calculateDeliveries', 68 | mode: 'ajax' 69 | }; 70 | 71 | var request = $.ajax({ 72 | url: '/bitrix/services/main/ajax.php?' + $.param(query, true), 73 | type: 'POST', 74 | data: formData 75 | }); 76 | 77 | request.done(function (result) { 78 | var selectedDelivery = $deliveryBlock.find('input:checked'); 79 | var selectedDeliveryId = 0; 80 | if(selectedDelivery.length > 0) { 81 | selectedDeliveryId = selectedDelivery.val(); 82 | } 83 | 84 | $deliveryBlock.html(''); 85 | $.each(result.data, function (i, deliveryData) { 86 | renderDelivery(deliveryData); 87 | }); 88 | 89 | if(selectedDeliveryId > 0) { 90 | $deliveryBlock.find('label.delivery' + selectedDeliveryId + ' input').prop('checked', true); 91 | } 92 | }); 93 | 94 | request.fail(function () { 95 | console.error('Can not get delivery data'); 96 | }); 97 | } 98 | }); 99 | }); 100 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/selectize/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alorian/bxorder/427a5037dfd956fdabada1bb672c25867dab1abf/install/components/opensource/order/templates/example_refresh_delivery/selectize/images/spinner.gif -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/selectize/selectize.default.css: -------------------------------------------------------------------------------- 1 | /** 2 | * selectize.default.css (v0.12.6) - Default Theme 3 | * Copyright (c) 2013–2015 Brian Reavis & contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 6 | * file except in compliance with the License. You may obtain a copy of the License at: 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under 10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | * ANY KIND, either express or implied. See the License for the specific language 12 | * governing permissions and limitations under the License. 13 | * 14 | * @author Brian Reavis 15 | */ 16 | .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { 17 | visibility: visible !important; 18 | background: #f2f2f2 !important; 19 | background: rgba(0, 0, 0, 0.06) !important; 20 | border: 0 none !important; 21 | -webkit-box-shadow: inset 0 0 12px 4px #fff; 22 | box-shadow: inset 0 0 12px 4px #fff; 23 | } 24 | .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { 25 | content: '!'; 26 | visibility: hidden; 27 | } 28 | .selectize-control.plugin-drag_drop .ui-sortable-helper { 29 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 30 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 31 | } 32 | .selectize-dropdown-header { 33 | position: relative; 34 | padding: 5px 8px; 35 | border-bottom: 1px solid #d0d0d0; 36 | background: #f8f8f8; 37 | -webkit-border-radius: 3px 3px 0 0; 38 | -moz-border-radius: 3px 3px 0 0; 39 | border-radius: 3px 3px 0 0; 40 | } 41 | .selectize-dropdown-header-close { 42 | position: absolute; 43 | right: 8px; 44 | top: 50%; 45 | color: #303030; 46 | opacity: 0.4; 47 | margin-top: -12px; 48 | line-height: 20px; 49 | font-size: 20px !important; 50 | } 51 | .selectize-dropdown-header-close:hover { 52 | color: #000000; 53 | } 54 | .selectize-dropdown.plugin-optgroup_columns .optgroup { 55 | border-right: 1px solid #f2f2f2; 56 | border-top: 0 none; 57 | float: left; 58 | -webkit-box-sizing: border-box; 59 | -moz-box-sizing: border-box; 60 | box-sizing: border-box; 61 | } 62 | .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { 63 | border-right: 0 none; 64 | } 65 | .selectize-dropdown.plugin-optgroup_columns .optgroup:before { 66 | display: none; 67 | } 68 | .selectize-dropdown.plugin-optgroup_columns .optgroup-header { 69 | border-top: 0 none; 70 | } 71 | .selectize-control.plugin-remove_button [data-value] { 72 | position: relative; 73 | padding-right: 24px !important; 74 | } 75 | .selectize-control.plugin-remove_button [data-value] .remove { 76 | z-index: 1; 77 | /* fixes ie bug (see #392) */ 78 | position: absolute; 79 | top: 0; 80 | right: 0; 81 | bottom: 0; 82 | width: 17px; 83 | text-align: center; 84 | font-weight: bold; 85 | font-size: 12px; 86 | color: inherit; 87 | text-decoration: none; 88 | vertical-align: middle; 89 | display: inline-block; 90 | padding: 2px 0 0 0; 91 | border-left: 1px solid #0073bb; 92 | -webkit-border-radius: 0 2px 2px 0; 93 | -moz-border-radius: 0 2px 2px 0; 94 | border-radius: 0 2px 2px 0; 95 | -webkit-box-sizing: border-box; 96 | -moz-box-sizing: border-box; 97 | box-sizing: border-box; 98 | } 99 | .selectize-control.plugin-remove_button [data-value] .remove:hover { 100 | background: rgba(0, 0, 0, 0.05); 101 | } 102 | .selectize-control.plugin-remove_button [data-value].active .remove { 103 | border-left-color: #00578d; 104 | } 105 | .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { 106 | background: none; 107 | } 108 | .selectize-control.plugin-remove_button .disabled [data-value] .remove { 109 | border-left-color: #aaaaaa; 110 | } 111 | .selectize-control.plugin-remove_button .remove-single { 112 | position: absolute; 113 | right: 0; 114 | top: 0; 115 | font-size: 23px; 116 | } 117 | .selectize-control { 118 | position: relative; 119 | } 120 | .selectize-dropdown, 121 | .selectize-input, 122 | .selectize-input input { 123 | color: #303030; 124 | font-family: inherit; 125 | font-size: 13px; 126 | line-height: 18px; 127 | -webkit-font-smoothing: inherit; 128 | } 129 | .selectize-input, 130 | .selectize-control.single .selectize-input.input-active { 131 | background: #fff; 132 | cursor: text; 133 | display: inline-block; 134 | } 135 | .selectize-input { 136 | border: 1px solid #d0d0d0; 137 | padding: 8px 8px; 138 | display: inline-block; 139 | width: 100%; 140 | overflow: hidden; 141 | position: relative; 142 | z-index: 1; 143 | -webkit-box-sizing: border-box; 144 | -moz-box-sizing: border-box; 145 | box-sizing: border-box; 146 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); 147 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); 148 | -webkit-border-radius: 3px; 149 | -moz-border-radius: 3px; 150 | border-radius: 3px; 151 | } 152 | .selectize-control.multi .selectize-input.has-items { 153 | padding: 5px 8px 2px; 154 | } 155 | .selectize-input.full { 156 | background-color: #fff; 157 | } 158 | .selectize-input.disabled, 159 | .selectize-input.disabled * { 160 | cursor: default !important; 161 | } 162 | .selectize-input.focus { 163 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); 164 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); 165 | } 166 | .selectize-input.dropdown-active { 167 | -webkit-border-radius: 3px 3px 0 0; 168 | -moz-border-radius: 3px 3px 0 0; 169 | border-radius: 3px 3px 0 0; 170 | } 171 | .selectize-input > * { 172 | vertical-align: baseline; 173 | display: -moz-inline-stack; 174 | display: inline-block; 175 | zoom: 1; 176 | *display: inline; 177 | } 178 | .selectize-control.multi .selectize-input > div { 179 | cursor: pointer; 180 | margin: 0 3px 3px 0; 181 | padding: 2px 6px; 182 | background: #1da7ee; 183 | color: #fff; 184 | border: 1px solid #0073bb; 185 | } 186 | .selectize-control.multi .selectize-input > div.active { 187 | background: #92c836; 188 | color: #fff; 189 | border: 1px solid #00578d; 190 | } 191 | .selectize-control.multi .selectize-input.disabled > div, 192 | .selectize-control.multi .selectize-input.disabled > div.active { 193 | color: #ffffff; 194 | background: #d2d2d2; 195 | border: 1px solid #aaaaaa; 196 | } 197 | .selectize-input > input { 198 | display: inline-block !important; 199 | padding: 0 !important; 200 | min-height: 0 !important; 201 | max-height: none !important; 202 | max-width: 100% !important; 203 | margin: 0 1px !important; 204 | text-indent: 0 !important; 205 | border: 0 none !important; 206 | background: none !important; 207 | line-height: inherit !important; 208 | -webkit-user-select: auto !important; 209 | -webkit-box-shadow: none !important; 210 | box-shadow: none !important; 211 | } 212 | .selectize-input > input::-ms-clear { 213 | display: none; 214 | } 215 | .selectize-input > input:focus { 216 | outline: none !important; 217 | } 218 | .selectize-input::after { 219 | content: ' '; 220 | display: block; 221 | clear: left; 222 | } 223 | .selectize-input.dropdown-active::before { 224 | content: ' '; 225 | display: block; 226 | position: absolute; 227 | background: #f0f0f0; 228 | height: 1px; 229 | bottom: 0; 230 | left: 0; 231 | right: 0; 232 | } 233 | .selectize-dropdown { 234 | position: absolute; 235 | z-index: 10; 236 | border: 1px solid #d0d0d0; 237 | background: #fff; 238 | margin: -1px 0 0 0; 239 | border-top: 0 none; 240 | -webkit-box-sizing: border-box; 241 | -moz-box-sizing: border-box; 242 | box-sizing: border-box; 243 | -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 244 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 245 | -webkit-border-radius: 0 0 3px 3px; 246 | -moz-border-radius: 0 0 3px 3px; 247 | border-radius: 0 0 3px 3px; 248 | } 249 | .selectize-dropdown [data-selectable] { 250 | cursor: pointer; 251 | overflow: hidden; 252 | } 253 | .selectize-dropdown [data-selectable] .highlight { 254 | background: rgba(125, 168, 208, 0.2); 255 | -webkit-border-radius: 1px; 256 | -moz-border-radius: 1px; 257 | border-radius: 1px; 258 | } 259 | .selectize-dropdown .option, 260 | .selectize-dropdown .optgroup-header { 261 | padding: 5px 8px; 262 | } 263 | .selectize-dropdown .option, 264 | .selectize-dropdown [data-disabled], 265 | .selectize-dropdown [data-disabled] [data-selectable].option { 266 | cursor: inherit; 267 | opacity: 0.5; 268 | } 269 | .selectize-dropdown [data-selectable].option { 270 | opacity: 1; 271 | } 272 | .selectize-dropdown .optgroup:first-child .optgroup-header { 273 | border-top: 0 none; 274 | } 275 | .selectize-dropdown .optgroup-header { 276 | color: #303030; 277 | background: #fff; 278 | cursor: default; 279 | } 280 | .selectize-dropdown .active { 281 | background-color: #f5fafd; 282 | color: #495c68; 283 | } 284 | .selectize-dropdown .active.create { 285 | color: #495c68; 286 | } 287 | .selectize-dropdown .create { 288 | color: rgba(48, 48, 48, 0.5); 289 | } 290 | .selectize-dropdown-content { 291 | overflow-y: auto; 292 | overflow-x: hidden; 293 | max-height: 200px; 294 | -webkit-overflow-scrolling: touch; 295 | } 296 | .selectize-control.single .selectize-input, 297 | .selectize-control.single .selectize-input input { 298 | cursor: pointer; 299 | } 300 | .selectize-control.single .selectize-input.input-active, 301 | .selectize-control.single .selectize-input.input-active input { 302 | cursor: text; 303 | } 304 | .selectize-control.single .selectize-input:after { 305 | content: ' '; 306 | display: block; 307 | position: absolute; 308 | top: 50%; 309 | right: 15px; 310 | margin-top: -3px; 311 | width: 0; 312 | height: 0; 313 | border-style: solid; 314 | border-width: 5px 5px 0 5px; 315 | border-color: #808080 transparent transparent transparent; 316 | } 317 | .selectize-control.single .selectize-input.dropdown-active:after { 318 | margin-top: -4px; 319 | border-width: 0 5px 5px 5px; 320 | border-color: transparent transparent #808080 transparent; 321 | } 322 | .selectize-control.rtl.single .selectize-input:after { 323 | left: 15px; 324 | right: auto; 325 | } 326 | .selectize-control.rtl .selectize-input > input { 327 | margin: 0 4px 0 -2px !important; 328 | } 329 | .selectize-control .selectize-input.disabled { 330 | opacity: 0.5; 331 | background-color: #fafafa; 332 | } 333 | .selectize-control.multi .selectize-input.has-items { 334 | padding-left: 5px; 335 | padding-right: 5px; 336 | } 337 | .selectize-control.multi .selectize-input.disabled [data-value] { 338 | color: #999; 339 | text-shadow: none; 340 | background: none; 341 | -webkit-box-shadow: none; 342 | box-shadow: none; 343 | } 344 | .selectize-control.multi .selectize-input.disabled [data-value], 345 | .selectize-control.multi .selectize-input.disabled [data-value] .remove { 346 | border-color: #e6e6e6; 347 | } 348 | .selectize-control.multi .selectize-input.disabled [data-value] .remove { 349 | background: none; 350 | } 351 | .selectize-control.multi .selectize-input [data-value] { 352 | text-shadow: 0 1px 0 rgba(0, 51, 83, 0.3); 353 | -webkit-border-radius: 3px; 354 | -moz-border-radius: 3px; 355 | border-radius: 3px; 356 | background-color: #1b9dec; 357 | background-image: -moz-linear-gradient(top, #1da7ee, #178ee9); 358 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#1da7ee), to(#178ee9)); 359 | background-image: -webkit-linear-gradient(top, #1da7ee, #178ee9); 360 | background-image: -o-linear-gradient(top, #1da7ee, #178ee9); 361 | background-image: linear-gradient(to bottom, #1da7ee, #178ee9); 362 | background-repeat: repeat-x; 363 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1da7ee', endColorstr='#ff178ee9', GradientType=0); 364 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03); 365 | box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03); 366 | } 367 | .selectize-control.multi .selectize-input [data-value].active { 368 | background-color: #0085d4; 369 | background-image: -moz-linear-gradient(top, #008fd8, #0075cf); 370 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#008fd8), to(#0075cf)); 371 | background-image: -webkit-linear-gradient(top, #008fd8, #0075cf); 372 | background-image: -o-linear-gradient(top, #008fd8, #0075cf); 373 | background-image: linear-gradient(to bottom, #008fd8, #0075cf); 374 | background-repeat: repeat-x; 375 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff008fd8', endColorstr='#ff0075cf', GradientType=0); 376 | } 377 | .selectize-control.single .selectize-input { 378 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8); 379 | box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8); 380 | background-color: #f9f9f9; 381 | background-image: -moz-linear-gradient(top, #fefefe, #f2f2f2); 382 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fefefe), to(#f2f2f2)); 383 | background-image: -webkit-linear-gradient(top, #fefefe, #f2f2f2); 384 | background-image: -o-linear-gradient(top, #fefefe, #f2f2f2); 385 | background-image: linear-gradient(to bottom, #fefefe, #f2f2f2); 386 | background-repeat: repeat-x; 387 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffefefe', endColorstr='#fff2f2f2', GradientType=0); 388 | } 389 | .selectize-control.single .selectize-input, 390 | .selectize-dropdown.single { 391 | border-color: #b8b8b8; 392 | } 393 | .selectize-dropdown .optgroup-header { 394 | padding-top: 7px; 395 | font-weight: bold; 396 | font-size: 0.85em; 397 | } 398 | .selectize-dropdown .optgroup { 399 | border-top: 1px solid #f0f0f0; 400 | } 401 | .selectize-dropdown .optgroup:first-child { 402 | border-top: 0 none; 403 | } 404 | -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/selectize/selectize.dropdown.css: -------------------------------------------------------------------------------- 1 | .selectize-control.location-search .selectize-dropdown > div { 2 | border-bottom: 1px solid rgba(0, 0, 0, 0.05); 3 | } 4 | 5 | .selectize-control.location-search .selectize-dropdown .name { 6 | font-weight: bold; 7 | margin-right: 5px; 8 | } 9 | 10 | .selectize-control.location-search .selectize-dropdown .title { 11 | padding: 10px; 12 | } 13 | 14 | .selectize-control.location-search::before { 15 | -moz-transition: opacity 0.2s; 16 | -webkit-transition: opacity 0.2s; 17 | transition: opacity 0.2s; 18 | content: ' '; 19 | z-index: 2; 20 | position: absolute; 21 | display: block; 22 | top: 12px; 23 | right: 34px; 24 | width: 16px; 25 | height: 16px; 26 | background: url(images/spinner.gif); 27 | background-size: 16px 16px; 28 | opacity: 0; 29 | } 30 | 31 | .selectize-control.location-search.loading::before { 32 | opacity: 0.4; 33 | } -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/style.css: -------------------------------------------------------------------------------- 1 | .os-order { 2 | } 3 | 4 | .os-order .error { 5 | color: #a40000; 6 | } 7 | 8 | .os-order .basket-properties { 9 | color: #919191; 10 | } 11 | 12 | .os-order table { 13 | border-collapse: collapse; 14 | } 15 | 16 | .os-order table th { 17 | background: #DFDFDF; 18 | padding: 5px; 19 | border: 1px solid #c9c9c9; 20 | } 21 | 22 | .os-order table td { 23 | padding: 5px; 24 | border: 1px solid #DFDFDF; 25 | } 26 | 27 | .os-order .location { 28 | min-width: 400px; 29 | } 30 | 31 | .enum-option { 32 | display:block; 33 | } -------------------------------------------------------------------------------- /install/components/opensource/order/templates/example_refresh_delivery/template.php: -------------------------------------------------------------------------------- 1 | addExternalJs($templateFolder . '/selectize/selectize.js'); 22 | $this->addExternalCss($templateFolder . '/selectize/selectize.default.css'); 23 | $this->addExternalCss($templateFolder . '/selectize/selectize.dropdown.css'); 24 | ?> 25 |
26 | errorCollection) > 0): ?> 27 |
28 | errorCollection as $error): 29 | /** 30 | * @var Error $error 31 | */ 32 | ?> 33 |
getMessage() ?>
34 | 35 |
36 | 37 | 38 | 0) { 39 | include 'done.php'; 40 | } elseif ($component->order instanceof Order && count($component->order->getBasket()) > 0) { 41 | include 'form.php'; 42 | } ?> 43 |
44 | 45 | -------------------------------------------------------------------------------- /install/index.php: -------------------------------------------------------------------------------- 1 | MODULE_VERSION = $arModuleVersion['VERSION']; 26 | $this->MODULE_VERSION_DATE = $arModuleVersion['VERSION_DATE']; 27 | $this->MODULE_NAME = Loc::getMessage('opensource_order_MODULE_NAME'); 28 | $this->MODULE_DESCRIPTION = Loc::getMessage('opensource_order_MODULE_DESC'); 29 | 30 | $this->PARTNER_NAME = Loc::getMessage('opensource_order_PARTNER_NAME'); 31 | $this->PARTNER_URI = Loc::getMessage('opensource_order_PARTNER_URI'); 32 | } 33 | 34 | /** 35 | * Get /document/local (when exists) or /document/bitrix. 36 | * @return string 37 | */ 38 | function getRoot() 39 | { 40 | $local = $_SERVER['DOCUMENT_ROOT'] . '/local'; 41 | if(1 === preg_match('#local[\\\/]modules#', __DIR__) && is_dir($local)) { 42 | return $local; 43 | } 44 | 45 | return $_SERVER['DOCUMENT_ROOT'] . BX_ROOT; 46 | } 47 | 48 | function InstallFiles() 49 | { 50 | CopyDirFiles(__DIR__ . '/components', $this->getRoot() . "/components", true, true); 51 | } 52 | 53 | function UnInstallFiles() 54 | { 55 | DeleteDirFilesEx(BX_ROOT . '/components/opensource/order'); 56 | DeleteDirFilesEx('/local/components/opensource/order'); 57 | } 58 | 59 | function DoInstall() 60 | { 61 | RegisterModule(self::MODULE_ID); 62 | $this->InstallFiles(); 63 | } 64 | 65 | function DoUninstall() 66 | { 67 | UnRegisterModule(self::MODULE_ID); 68 | $this->UnInstallFiles(); 69 | } 70 | } -------------------------------------------------------------------------------- /install/version.php: -------------------------------------------------------------------------------- 1 | '1.0.2', 4 | 'VERSION_DATE' => '2019-05-13 11:00:00' 5 | ); -------------------------------------------------------------------------------- /lang/ru/install/index.php: -------------------------------------------------------------------------------- 1 | values as $error) { 21 | /** @var Error $error */ 22 | if ($error->getCode() === $code) { 23 | $errorsList[] = $error; 24 | } 25 | } 26 | 27 | return $errorsList; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /lib/locationhelper.php: -------------------------------------------------------------------------------- 1 | [ 25 | '=CODE' => $locationCode, 26 | '!PARENTS.TYPE.CODE' => $excludeParts, 27 | '=PARENTS.NAME.LANGUAGE_ID' => LANGUAGE_ID, 28 | '=PARENTS.TYPE.NAME.LANGUAGE_ID' => LANGUAGE_ID, 29 | ], 30 | 'select' => [ 31 | 'PARENT_CODE' => 'PARENTS.CODE', 32 | 'NAME_LANG' => 'PARENTS.NAME.NAME', 33 | 'TYPE_CODE' => 'PARENTS.TYPE.CODE', 34 | 'TYPE_NAME_LANG' => 'PARENTS.TYPE.NAME.NAME' 35 | ], 36 | 'order' => [ 37 | 'PARENTS.DEPTH_LEVEL' => $order 38 | ] 39 | ]); 40 | 41 | $label = []; 42 | $partsList = []; 43 | while ($item = $res->fetch()) { 44 | $part = [ 45 | 'name' => $item['NAME_LANG'], 46 | 'code' => $item['PARENT_CODE'], 47 | 'type' => $item['TYPE_CODE'], 48 | 'type_name' => $item['TYPE_NAME_LANG'] 49 | ]; 50 | 51 | $label[] = $part['name']; 52 | $partsList[$part['type']] = $part; 53 | 54 | if($part['code'] === $locationCode) { 55 | $result = $part; 56 | } 57 | } 58 | 59 | $result['label'] = implode(', ', $label); 60 | $result['parts'] = $partsList; 61 | } 62 | 63 | return $result; 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /lib/orderhelper.php: -------------------------------------------------------------------------------- 1 | getShipmentCollection() as $shipment) { 24 | if (!$shipment->isSystem()) { 25 | return $shipment; 26 | } 27 | } 28 | 29 | return null; 30 | } 31 | 32 | /** 33 | * @param Order $order 34 | * @return PaySystem\Service[] 35 | * 36 | * @throws Exception 37 | */ 38 | public static function getAvailablePaySystems(Order $order): array 39 | { 40 | $payment = Payment::create($order->getPaymentCollection()); 41 | $payment->setField('SUM', $order->getPrice()); 42 | $payment->setField('CURRENCY', $order->getCurrency()); 43 | 44 | $paySystemList = PaySystem\Manager::getListWithRestrictions($payment); 45 | foreach ($paySystemList as $key => $paySystem) { 46 | $paySystemList[$key] = new PaySystem\Service($paySystem); 47 | } 48 | 49 | return $paySystemList; 50 | } 51 | 52 | /** 53 | * @param Shipment $shipment 54 | * @param Delivery\Services\Base[] $deliveryObjects 55 | * @return null[]|CalculationResult[] 56 | * 57 | * @throws Exception 58 | */ 59 | public static function calcDeliveries(Shipment $shipment, array $deliveryObjects): array 60 | { 61 | $calculatedDeliveries = []; 62 | 63 | $order = $shipment->getParentOrder(); 64 | 65 | $deliveryId = $shipment->getDeliveryId(); 66 | $deliveryPrice = $shipment->getField('BASE_PRICE_DELIVERY'); 67 | 68 | foreach ($deliveryObjects as $obDelivery) { 69 | $shipment->setField('DELIVERY_ID', $obDelivery->getId()); 70 | $calculationResult = $obDelivery->calculate($shipment); 71 | 72 | if ($calculationResult->isSuccess()) { 73 | $shipment->setBasePriceDelivery($calculationResult->getPrice()); 74 | $arShowPrices = $order->getDiscount() 75 | ->getShowPrices(); 76 | 77 | $data = $calculationResult->getData(); 78 | $data['DISCOUNT_DATA'] = $arShowPrices['DELIVERY']; 79 | $calculationResult->setData($data); 80 | } 81 | 82 | $calculatedDeliveries[$obDelivery->getId()] = $calculationResult; 83 | } 84 | 85 | //restore actual data 86 | $shipment->setField('DELIVERY_ID', $deliveryId); 87 | $shipment->setBasePriceDelivery($deliveryPrice); 88 | 89 | return $calculatedDeliveries; 90 | } 91 | 92 | } --------------------------------------------------------------------------------