├── .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 |
2 | $MESS ['OPEN_SOURCE_ORDER_COMPONENT_NAME'] = 'OpenSource Оформление заказа';
3 | $MESS ['OPEN_SOURCE_ORDER_COMPONENT_DESCRIPTION'] = 'Документация https://github.com/Alorian/bxorder';
--------------------------------------------------------------------------------
/install/components/opensource/order/lang/ru/.parameters.php:
--------------------------------------------------------------------------------
1 |
22 |
23 | = Loc::getMessage('OPEN_SOURCE_ORDER_TEMPLATE_ORDER_CREATED', [
24 | '#ORDER_ID#' => $arResult['ID']
25 | ]) ?>
26 |
--------------------------------------------------------------------------------
/install/components/opensource/order/templates/.default/form.php:
--------------------------------------------------------------------------------
1 |
22 |
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 |
= $error->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 | Заказ №=$arResult['ID']?> успешно создан
23 |
--------------------------------------------------------------------------------
/install/components/opensource/order/templates/example_person_type/form.php:
--------------------------------------------------------------------------------
1 |
21 |
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 |
= $error->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 | = Loc::getMessage('OPEN_SOURCE_ORDER_TEMPLATE_ORDER_CREATED', [
24 | '#ORDER_ID#' => $arResult['ID']
25 | ]) ?>
26 |
--------------------------------------------------------------------------------
/install/components/opensource/order/templates/example_refresh_delivery/form.php:
--------------------------------------------------------------------------------
1 |
21 |
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 |
= $error->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 |
2 |
3 | use Bitrix\Main\Localization\Loc;
4 |
5 | IncludeModuleLangFile(__FILE__);
6 |
7 | if (class_exists('opensource_order')) {
8 | return;
9 | }
10 |
11 | Class opensource_order extends CModule
12 | {
13 | const MODULE_ID = 'opensource.order';
14 | public $MODULE_ID = 'opensource.order';
15 | public $MODULE_VERSION;
16 | public $MODULE_VERSION_DATE;
17 | public $MODULE_NAME;
18 | public $MODULE_DESCRIPTION;
19 | public $MODULE_CSS;
20 |
21 | public function __construct()
22 | {
23 | $arModuleVersion = [];
24 | include __DIR__ . '/version.php';
25 | $this->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 | }
--------------------------------------------------------------------------------